DDI

Menus

This page doesn’t seem to implement working examples

CollapsibleMenu

The CollapsibleMenu component automatically moves menu items into an overflow dropdown when there isn’t enough horizontal space to display them all. Perfect for responsive navigation bars and headers.

Features:

Basic Usage

---
import { CollapsibleMenu } from '@dynamic-type/ddi/server';
---

<CollapsibleMenu
    buttonClass="custom-button-style"
    popoverClass="custom-popover-style"
    menuItemsClass="custom-menu-style"
    collapseAll
>
    <a href="/item-1" class="button tertiary">Item 1</a>
    <a href="/item-2" class="button tertiary">Item 2</a>
    <a href="/item-3" class="button tertiary">Item 3</a>
</CollapsibleMenu>

Attributes

Custom classes - resize to see overflow behavior
<div class="box content x-flow items:center mbe:3xl bg:alt rounded">
    <div class="p bg rounded">Logo</div>
    <div class="x-stack justify:center flex:1 min-width:0">
        <script type="module" src="/_astro/Popover.astro_astro_type_script_index_0_lang.Bn9QbtRK.js"></script><ddi-collapsible-menu popoverClass="drop-shadow" class="bg:rgb(255,255,255) rounded" data-ddi-collapsed="false" data-ddi-collapse-all="false" data-astro-cid-6skp7dxg="true">
            <div class="visible-items " data-astro-cid-6skp7dxg><a href="/item-1" class="button tertiary">
                    <p>Item 1</p>
                </a><a href="/item-2" class="button tertiary">
                    <p>Item 2</p>
                </a><a href="/item-3" class="button tertiary">
                    <p>Item 3</p>
                </a><a href="/item-4" class="button tertiary">
                    <p>Item 4</p>
                </a><a href="/item-5" class="button tertiary">
                    <p>Item 5</p>
                </a><a href="/item-6" class="button tertiary">
                    <p>Item 6</p>
                </a><a href="/item-7" class="button tertiary">
                    <p>Item 7</p>
                </a><a href="/item-8" class="button tertiary">
                    <p>Item 8</p>
                </a></div>
            <div class="overflow-menu" data-astro-cid-6skp7dxg>
                <button class="tertiary text-decoration:none x-flow items:center bg:rgb(255,200,160)" data-astro-cid-6skp7dxg>Meny<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-6skp7dxg>
                        <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-6skp7dxg></path>
                    </svg></button>
                <div class="popover " data-ddi-overflow-items="true" data-astro-cid-6skp7dxg="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
                    <div class="p bg flow rounded drop-shadow" data-astro-cid-6skp7dxg></div>
                </div>
            </div>
        </ddi-collapsible-menu>
        <script type="module" src="/_astro/CollapsibleMenu.astro_astro_type_script_index_0_lang.DFTU6CTU.js"></script>
    </div>
</div>
Set `collapseAll` to put all items in overflow menu if the menu overflows.
<div class="box content x-flow items:center mbe:3xl bg:alt rounded">
    <div class="p bg rounded">Logo</div>
    <div class="x-stack justify:center flex:1 min-width:0"><ddi-collapsible-menu class data-ddi-collapsed="false" data-ddi-collapse-all="true" data-astro-cid-6skp7dxg="true">
            <div class="visible-items " data-astro-cid-6skp7dxg><a href="/item-1" class="button tertiary">
                    <p>Item 1</p>
                </a><a href="/item-2" class="button tertiary">
                    <p>Item 2</p>
                </a><a href="/item-3" class="button tertiary">
                    <p>Item 3</p>
                </a><a href="/item-4" class="button tertiary">
                    <p>Item 4</p>
                </a><a href="/item-5" class="button tertiary">
                    <p>Item 5</p>
                </a><a href="/item-6" class="button tertiary">
                    <p>Item 6</p>
                </a><a href="/item-7" class="button tertiary">
                    <p>Item 7</p>
                </a><a href="/item-8" class="button tertiary">
                    <p>Item 8</p>
                </a></div>
            <div class="overflow-menu" data-astro-cid-6skp7dxg>
                <button class="tertiary text-decoration:none x-flow items:center " data-astro-cid-6skp7dxg>Meny<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-6skp7dxg>
                        <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-6skp7dxg></path>
                    </svg></button>
                <div class="popover " data-ddi-overflow-items="true" data-astro-cid-6skp7dxg="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
                    <div class="p bg flow " data-astro-cid-6skp7dxg></div>
                </div>
            </div>
        </ddi-collapsible-menu></div>
</div>

VerticalMenu

The VerticalMenu component creates a dropdown menu triggered by a button. It displays menu items in a vertical popover when activated, perfect for navigation submenus and grouped actions.

Features:

Basic Usage

---
import { VerticalMenu } from "@dynamic-type/ddi/server";
---

<VerticalMenu
    name="Menu Name"
    buttonClass="custom-button-style"
    itemsClass="custom-items-style"
>
    <a href="/item-1" class="button tertiary">Item 1</a>
    <a href="/item-2" class="button tertiary">Item 2</a>
    <a href="/item-3" class="button tertiary">Item 3</a>
</VerticalMenu>

Custom Button

<VerticalMenu name="Custom Menu">
    <button slot="vertical-menu-button" class="custom-trigger-button">
        Custom Trigger
        <svg><!-- custom icon --></svg>
    </button>
    <a href="/item-1">Item 1</a>
    <a href="/item-2">Item 2</a>
</VerticalMenu>

With Unwrap Prefix

<VerticalMenu name="Services" unwrapPrefix={true}>
    <a href="/web-design" class="button tertiary">Web Design</a>
    <a href="/development" class="button tertiary">Development</a>
    <a href="/consulting" class="button tertiary">Consulting</a>
</VerticalMenu>

When this menu is moved to overflow in a CollapsibleMenu, items become “Services – Web Design”, “Services – Development”, etc.

Attributes

Slots

Basic vertical menu
<div class="center"><ddi-vertical-menu data-ddi-name="Menu Items" data-ddi-unwrap-prefix data-ddi-unwrap-in-collapsed="true" class data-astro-cid-wlhgjonm="true">
        <button class="vertical-menu-button button tertiary text-decoration:none x-flow items:center " data-astro-cid-wlhgjonm>Menu Items<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-wlhgjonm>
                <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-wlhgjonm></path>
            </svg></button>
        <div class="popover " data-ddi-vertical-items-popover="true" data-astro-cid-wlhgjonm="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
            <div class="p bg flow " data-astro-cid-wlhgjonm><a href="/item-1" class="button tertiary">
                    <p>Item 1</p>
                </a><a href="/item-2" class="button tertiary">
                    <p>Item 2</p>
                </a><a href="/item-3" class="button tertiary">
                    <p>Item 3</p>
                </a></div>
        </div>
    </ddi-vertical-menu>
    <script type="module">
        var e = 0,
            t = () => e++,
            n = class extends HTMLElement {
                key;
                constructor(e = t()) {
                    super(), this.key = e, this.style.visibility = `unset`;
                    let n = this.menuButton(),
                        r = `vertical-menu-items${this.key}`;
                    n.dataset.ddiPopovertarget = r;
                    let i = this.itemsPopover();
                    i.id = r
                }
                menuButton() {
                    let e = this.querySelector(`.vertical-menu-button`);
                    if (!e) throw Error(`No button in ddi-vertical-menu`);
                    return e
                }
                itemsPopover() {
                    let e = this.querySelector(`.popover`);
                    if (!e) throw Error(`No popover in ddi-vertical-menu`);
                    return e
                }
                unwrap() {
                    let e = this.itemsPopover().firstElementChild?.children;
                    if (!e) throw Error(`Empty vertical menu`);
                    for (let t of e) t.textContent = this.dataset.ddiUnwrapPrefix + t.textContent;
                    this.replaceWith(...e)
                }
            };
        customElements.define(`ddi-vertical-menu`, n);
    </script>
</div>
Styled vertical menu
<div class="center"><ddi-vertical-menu data-ddi-name="Styled Menu" data-ddi-unwrap-prefix data-ddi-unwrap-in-collapsed="true" class data-astro-cid-wlhgjonm="true">
        <button class="vertical-menu-button button tertiary text-decoration:none x-flow items:center bg:brand color:white" data-astro-cid-wlhgjonm>Styled Menu<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-wlhgjonm>
                <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-wlhgjonm></path>
            </svg></button>
        <div class="popover " data-ddi-vertical-items-popover="true" data-astro-cid-wlhgjonm="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
            <div class="p bg flow bg:alt border border:sink rounded drop-shadow" data-astro-cid-wlhgjonm><a href="/item-1" class="button tertiary">
                    <p>Dashboard</p>
                </a><a href="/item-2" class="button tertiary">
                    <p>Settings</p>
                </a><a href="/item-3" class="button tertiary">
                    <p>Profile</p>
                </a><a href="/item-4" class="button tertiary">
                    <p>Logout</p>
                </a></div>
        </div>
    </ddi-vertical-menu></div>

Combining CollapsibleMenu with VerticalMenu

When you combine these components, VerticalMenu items can be automatically unwrapped and prefixed when the CollapsibleMenu moves them to overflow. This provides better UX by showing users which submenu the items came from.

Put vertical menus in collapsible menu - resize to see unwrapPrefix in action
<div class="box content x-flow items:center mbe:3xl bg:alt rounded">
    <div class="p bg rounded">Logo</div>
    <div class="x-stack justify:center" style="flex: 1; min-width: 0"><ddi-collapsible-menu class data-ddi-collapsed="false" data-ddi-collapse-all="false" data-astro-cid-6skp7dxg="true">
            <div class="visible-items " data-astro-cid-6skp7dxg><a href="/item-1" class="button tertiary">
                    <p>Item 1</p>
                </a><a href="/item-2" class="button tertiary">
                    <p>Item 2</p>
                </a><ddi-vertical-menu data-ddi-name="3–6" data-ddi-unwrap-prefix="3–6 – " data-ddi-unwrap-in-collapsed="true" class data-astro-cid-wlhgjonm="true">
                    <button class="vertical-menu-button button tertiary text-decoration:none x-flow items:center " data-astro-cid-wlhgjonm>3–6<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-wlhgjonm>
                            <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-wlhgjonm></path>
                        </svg></button>
                    <div class="popover " data-ddi-vertical-items-popover="true" data-astro-cid-wlhgjonm="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
                        <div class="p bg flow " data-astro-cid-wlhgjonm><a href="/item-3" class="button tertiary">
                                <p>Item 3</p>
                            </a><a href="/item-4" class="button tertiary">
                                <p>Item 4</p>
                            </a><a href="/item-5" class="button tertiary">
                                <p>Item 5</p>
                            </a><a href="/item-6" class="button tertiary">
                                <p>Item 6</p>
                            </a></div>
                    </div>
                </ddi-vertical-menu><a href="/item-7" class="button tertiary">
                    <p>Item 7</p>
                </a><a href="/item-8" class="button tertiary">
                    <p>Item 8</p>
                </a></div>
            <div class="overflow-menu" data-astro-cid-6skp7dxg>
                <button class="tertiary text-decoration:none x-flow items:center " data-astro-cid-6skp7dxg>Meny<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" data-astro-cid-6skp7dxg>
                        <path d="M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" data-astro-cid-6skp7dxg></path>
                    </svg></button>
                <div class="popover " data-ddi-overflow-items="true" data-astro-cid-6skp7dxg="true" data-ddi-open="false" data-astro-cid-qbypwhzy>
                    <div class="p bg flow " data-astro-cid-6skp7dxg></div>
                </div>
            </div>
        </ddi-collapsible-menu></div>
</div>