<div class="rtds-dropdown-menu">
    <button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center  hover:rtds-content-primary aria-expanded:rtds-bg-white lg:aria-expanded:rtds-bg-transparent aria-expanded:rtds-content-primary aria-expanded:rtds-relative rtds-p-3 rtds-gap-2 rtds-text-sm lg:rtds-text-base" aria-expanded="false" aria-controls="submenuId01">

        Menu item

        <svg class="rtds-icon rtds-fill-current rtds-w-5 rtds-h-5 rtds-ml-auto rtds-transition-all rtds-dropdown-menu__trigger-icon group-aria-expanded:-rtds-rotate-180" aria-hidden="true" focusable="false" role="img">
            <use href="../../icons.svg#mini--chevron-down" />
        </svg>

    </button>

    <ul class="rtds-dropdown-menu__list rtds-hidden rtds-border rtds-border-t-0 rtds-w-full lg:rtds-border-t lg:rtds-rounded lg:rtds-shadow-md lg:rtds-absolute" id="submenuId01">

        <li class="rtds-dropdown-menu__item rtds-group/menu-item">
            <a class="rtds-dropdown-menu__link rtds-block rtds-transition group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
                <div class="rtds-flex rtds-gap-2 rtds-items-center">

                    <svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
                        <use href="../../icons.svg#solid--cube-transparent" />
                    </svg>

                    <span class="rtds-grow">Item label 1</span>

                </div>

            </a>
        </li>

        <li class="rtds-dropdown-menu__item rtds-group/menu-item">
            <a class="rtds-dropdown-menu__link rtds-block rtds-transition group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
                <div class="rtds-flex rtds-gap-2 rtds-items-center">

                    <span class="rtds-grow">Item label 3</span>

                    <svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-ml-2 rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform group-hover:rtds-translate-x-1" aria-hidden="true" focusable="false" role="img">
                        <use href="../../icons.svg#mini--chevron-right" />
                    </svg>

                </div>
                <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</div>
            </a>
        </li>

        <li class="rtds-dropdown-menu__item rtds-group/menu-item">
            <a class="rtds-dropdown-menu__link rtds-block rtds-transition group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
                <div class="rtds-flex rtds-gap-2 rtds-items-center">

                    <svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-mr-2" aria-hidden="true" focusable="false" role="img">
                        <use href="../../icons.svg#solid--cube-transparent" />
                    </svg>

                    <span class="rtds-grow">Item label 4</span>

                    <svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 rtds-ml-2 rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform group-hover:rtds-translate-x-1" aria-hidden="true" focusable="false" role="img">
                        <use href="../../icons.svg#mini--chevron-right" />
                    </svg>

                </div>

            </a>
        </li>

        <li class="rtds-dropdown-menu__item rtds-group/menu-item">
            <a class="rtds-dropdown-menu__link rtds-block rtds-transition group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b" href="">
                <div class="rtds-flex rtds-gap-2 rtds-items-center">

                    <span class="rtds-grow">Item label 5</span>

                </div>

            </a>
        </li>

    </ul>

</div>
<{% if listItem %}li{% else %}div{% endif %} class="rtds-dropdown-menu{% if listItem %} has-dropdown-menu{% endif %}{% block classes %}{% if classes %} {{ classes }}{% endif %}{% endblock classes %}">
    <button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center {% if hoverStyles %} {{ hoverStyles }}{% endif %}{% if triggerAriaExpandedStyles %} {{ triggerAriaExpandedStyles }}{% endif %}{% if triggerSpacing %} {{ triggerSpacing }}{% endif %}{% if triggerFontSize %} {{ triggerFontSize }}{% endif %}{% if triggerTextColor %} {{ triggerTextColor }}{% endif %}{% if triggerClasses %} {{ triggerClasses }}{% endif %}" aria-expanded="false" aria-controls="{{ id }}">
        {% block triggerContent %}
            {{ label }}
        {% endblock triggerContent %}
        {% block triggerIcon %}
            {%- render '@icon--small', {id: 'mini--chevron-down',size: 'rtds-w-5 rtds-h-5', classes: 'rtds-ml-auto rtds-transition-all rtds-dropdown-menu__trigger-icon group-aria-expanded:-rtds-rotate-180'},true -%}
        {% endblock triggerIcon %}
    </button>
    {% block listStart %}
    <ul class="rtds-dropdown-menu__list rtds-hidden rtds-border rtds-border-t-0{% if listWidth %} {{ listWidth }}{% endif %}{% if listPosition %} {{ listPosition }}{% endif %}{% if listResponsiveStyles %} {{ listResponsiveStyles }}{% endif %}{% if listClasses %} {{ listClasses }}{% endif %}" id="{{ id }}">
    {% endblock listStart %}
        {% for item in items %}
        <li class="rtds-dropdown-menu__item rtds-group/menu-item{% if listItemClasses %} {{ listItemClasses }}{% endif %}">
            <a class="rtds-dropdown-menu__link rtds-block rtds-transition{% if listItemLinkFontSize %} {{ listItemLinkFontSize }}{% endif %}{% if listItemLinkRadius %} {{ listItemLinkRadius }}{% endif %}" href="">
                <div class="rtds-flex rtds-gap-2 rtds-items-center">
                    {% if item.iconLeft %}
                        {% render '@icon--small', { id: item.iconLeft, classes: 'rtds-mr-2', size: 'rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6' }, true %}
                    {% endif %}
                    <span class="rtds-grow">{% if item.label %}{{ item.label }}{% else %} Item {% endif %}</span>
                    {% if item.iconRight %}
                        {% render '@icon--small', { id: item.iconRight, classes: 'rtds-ml-2 rtds-transition-all rtds-duration-200 rtds-ease-out rtds-transform group-hover:rtds-translate-x-1', size: 'rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6' }, true %}
                    {% endif %}
                </div>
                {% if item.description %}<div>{{ item.description }}</div>{% endif %}
            </a>
        </li>
        {% endfor %}
    {% block listEnd %}
    </ul>
    {% endblock listEnd %}
</{% if listItem %}li{% else %}div{% endif %}>
{
  "label": "Menu item",
  "id": "submenuId01",
  "triggerSpacing": "rtds-p-3 rtds-gap-2",
  "triggerFontSize": "rtds-text-sm lg:rtds-text-base",
  "triggerAriaExpandedStyles": "aria-expanded:rtds-bg-white lg:aria-expanded:rtds-bg-transparent aria-expanded:rtds-content-primary aria-expanded:rtds-relative",
  "items": [
    {
      "label": "Item label 1",
      "iconLeft": "solid--cube-transparent"
    },
    {
      "label": "Item label 3",
      "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
      "iconRight": "mini--chevron-right"
    },
    {
      "label": "Item label 4",
      "iconLeft": "solid--cube-transparent",
      "iconRight": "mini--chevron-right"
    },
    {
      "label": "Item label 5"
    }
  ],
  "listWidth": "rtds-w-full",
  "listResponsiveStyles": "lg:rtds-border-t lg:rtds-rounded lg:rtds-shadow-md lg:rtds-absolute",
  "listItemLinkRadius": "group-first/menu-item:rtds-rounded-t group-last/menu-item:rtds-rounded-b",
  "hoverStyles": "hover:rtds-content-primary"
}
  • Content:
    /**
     * DROPDOWN MENU
     *
    */
    /* DROPDOWN MENU STYLES */
    .rtds-dropdown-menu__list[style*="block"] {
        z-index: 10;
    }
    .rtds-dropdown-menu__list,
        .rtds-dropdown-menu__item {
            border-color: var(--color-border-gray-01);
        }
    @media (min-width: 1024px) {
        .rtds-dropdown-menu__list:where(.is-open) {
            top: 100%;
        }
    }
    .rtds-dropdown-menu__item {
        border-bottom-width: 1px;
    }
    .rtds-dropdown-menu__item:last-of-type {
        border-bottom-width: 0px;
    }
    .rtds-dropdown-menu__link {
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
        padding: var(--spacing-3);
    }
    .rtds-dropdown-menu__link:hover {
        text-decoration-line: underline;
            background-color: var(--color-background-02);
    }
    .rtds-dropdown-menu__link:focus {
            background-color: var(--color-background-02);
        }
    /* DROPDOWN TRIGGER */
    .rtds-dropdown-menu__trigger[aria-expanded="true"]::after {
        position: absolute;
        left: var(--spacing-0);
        bottom: var(--spacing-0);
        display: block;
        height: 1px;
        width: 100%;
        border-top-width: 2px;
        border-color: currentColor;
        content: var(--tw-content);
        background-color: transparent;
    }
    /* ACTIONS VARIANT STYLES */
    .is-dropdown-menu--actions {
        position: relative;
        justify-content: flex-end;
        display: flex;
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger {
            background-color: var(--color-button-inverted);
            border-color: var(--color-button-inverted);
            color: var(--color-button-inverted-text);
        }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger:hover {
            background-color: var(--color-button-inverted-hover);
            border-color: var(--color-button-inverted-hover);
            color: var(--color-button-inverted-text-hover);
        }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger:focus {
            background-color: var(--color-button-inverted-focus);
            border-color: var(--color-button-inverted-focus);
            color: var(--color-button-inverted-text-focus);
        }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger:active {
            background-color: var(--color-button-inverted-active);
            border-color: var(--color-button-inverted-active);
            color: var(--color-button-inverted-text-active);
        }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger {
        height: var(--spacing-10);
        width: var(--spacing-10);
        border-radius: 9999px;
            color: var(--color-content-01);
            border-color: var(--color-border-gray-04);
        transition-property: all;
        transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
        transition-duration: 150ms;
        border-width: 1px;
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__trigger[aria-expanded="true"] {
            color: var(--color-content-inverse);
            background-color: var(--color-background-08);
        }
    .is-dropdown-menu--actions .rtds-dropdown-menu__list {
        position: absolute;
        right: var(--spacing-0);
        top: var(--spacing-10);
        z-index: 10;
        width: 25ch;
        border-radius: 0.25rem;
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
        --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
        --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
        box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
            border-color: var(--color-border-gray-01);
        border-width: 1px;
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__item {
        border-style: none;
        display: flex;
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link {
        gap: var(--spacing-0-5);
        font-size: var(--fontsize-text-sm);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon),.is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-square) {
        width: var(--spacing-6);
        height: var(--spacing-6);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-right),.is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-left) {
        gap: var(--spacing-1-5);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-right) {
        padding-right: var(--spacing-3);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-left) {
        padding-left: var(--spacing-3);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon),.is-dropdown-menu--actions .rtds-dropdown-menu__link:where(.rtds-btn--icon-square) {
        padding-left: var(--spacing-0);
        padding-right: var(--spacing-0);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link {
        width: 100%;
        justify-content: flex-start;
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
        padding: var(--spacing-3);
        font-size: var(--fontsize-text-sm);
        font-weight: 500;
        transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
        transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
        transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
        transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
        transition-duration: 150ms;
            color: var(--color-content-primary-dark);
        display: flex;
        align-items: center;
        gap: var(--spacing-2);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:hover {
        text-decoration-line: underline;
            background-color: var(--color-background-02);
    }
    .is-dropdown-menu--actions .rtds-dropdown-menu__link:focus {
            background-color: var(--color-background-02);
        }
    /* MEGAMENU STYLES */
    @media (min-width: 1024px) {
    
        .rtds-dropdown-menu__megamenu.is-open {
            background-color: var(--color-background-02);
        }
    }
    .has-megamenu .rtds-dropdown-menu__item {
        border-style: dashed;
            border-color: var(--color-border-gray-03);
        font-weight: 700;
    }
    .has-megamenu .rtds-dropdown-menu__item:last-of-type {
        border-bottom-width: 1px;
    }
    .has-megamenu .rtds-dropdown-menu__list {
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
    }
    @media (min-width: 1024px) {
        .has-megamenu .rtds-dropdown-menu__list {
            display: grid;
            grid-template-columns: repeat(3, minmax(0, 1fr));
            -moz-column-gap: var(--spacing-8);
                 column-gap: var(--spacing-8);
            background-color: transparent;
            padding: var(--spacing-4);
        }
    }
    @media (min-width: 1280px) {
        .has-megamenu .rtds-dropdown-menu__list {
            grid-template-columns: repeat(4, minmax(0, 1fr));
            -moz-column-gap: var(--spacing-10);
                 column-gap: var(--spacing-10);
        }
    }
    .has-megamenu .rtds-dropdown-menu__link {
        padding: var(--spacing-4);
        font-size: var(--fontsize-text-base);
            color: var(--color-content-02);
    }
    @media (min-width: 1024px) {
        .has-megamenu .rtds-dropdown-menu__link {
            background-color: transparent;
        }
    }
    @media (min-width: 1280px) {
        .has-megamenu .rtds-dropdown-menu__link {
            font-size: var(--fontsize-text-lg);
        }
    }
    body.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop,
        :root.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop {
        position: fixed;
        right: var(--spacing-0);
        bottom: var(--spacing-0);
        left: var(--spacing-0);
        z-index: 10;
    }
    @media (min-width: 1024px) {
        body.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop,
        :root.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop {
            display: none;
        }
    }
    body.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop,
        :root.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop {
        position: fixed;
        right: var(--spacing-0);
        bottom: var(--spacing-0);
        left: var(--spacing-0);
        z-index: 10;
    }
    @media (min-width: 1024px) {
        body.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop,
        :root.rtds-dropdown-menu__megamenu.is-hidden .rtds-primary-navigation__backdrop {
            display: none;
        }
    }
    .rtds-dropdown-menu__megamenu.is-hidden {
        visibility: hidden;
        position: absolute;
        overflow: hidden;
    }
    @media (min-width: 1024px) {
        .rtds-dropdown-menu__megamenu.is-hidden {
            position: static;
            display: none;
        }
    }
    /* MEGAMENU MOBILE */
    .rtds-dropdown-menu.has-megamenu {
        z-index: 20;
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
    }
    @media (min-width: 1024px) {
        .rtds-dropdown-menu.has-megamenu {
            position: static;
            top: auto;
            left: auto;
            right: auto;
            bottom: auto;
            z-index: auto;
        }
    }
    .rtds-dropdown-menu.has-megamenu.has-dropdown-open {
        position: absolute;
        top: var(--spacing-0);
        left: var(--spacing-0);
        right: var(--spacing-0);
        bottom: var(--spacing-0);
        z-index: 30;
    }
    @media (min-width: 1024px) {
        .rtds-dropdown-menu.has-megamenu.has-dropdown-open {
            position: static;
            top: auto;
            left: auto;
            right: auto;
            bottom: auto;
        }
    }
    .rtds-dropdown-menu__megamenu .rtds-dropdown-menu__list {
        visibility: hidden;
        position: relative;
        left: 100%;
        right: var(--spacing-0);
        height: var(--spacing-0);
        width: var(--spacing-0);
        --tw-translate-x: 100%;
        transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
        opacity: 0;
        transition-property: all;
        transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
        transition-duration: 150ms;
    }
    @media (min-width: 1024px) {
        .rtds-dropdown-menu__megamenu .rtds-dropdown-menu__list {
            left: auto;
            right: auto;
            height: auto;
            width: 100%;
            --tw-translate-x: var(--spacing-0);
            transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
        }
    }
    .rtds-dropdown-menu__megamenu.is-open .rtds-dropdown-menu__list {
        visibility: visible;
        left: var(--spacing-0);
        width: 100%;
        --tw-translate-x: var(--spacing-0);
        transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
        opacity: 1;
    }
    /* MANAGING NAV PANEL DROPDOWN OPEN */
    :where(.rtds-primary-navigation.has-megamenu) .has-inner-dropdown-open {
        position: absolute;
        top: var(--spacing-0);
        left: var(--spacing-0);
        right: var(--spacing-0);
        bottom: var(--spacing-0);
        z-index: 30;
        --tw-bg-opacity: 1;
        background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
    }
    @media (min-width: 1280px) {
        :where(.rtds-primary-navigation.has-megamenu) .has-inner-dropdown-open {
            position: static;
            top: auto;
            left: auto;
            right: auto;
            bottom: auto;
            z-index: auto;
            background-color: transparent;
        }
    }
    
  • URL: /components/raw/dropdown-menu/dropdown-menu.built.css
  • Filesystem Path: components/03-molecules/dropdown-menu/dropdown-menu.built.css
  • Size: 11.5 KB
  • Content:
    /**
     * DROPDOWN MENU
     *
    */
    @layer components {
        /* DROPDOWN MENU STYLES */
        .rtds-dropdown-menu__list[style*="block"] {
            @apply rtds-z-10;
        }
    
        .rtds-dropdown-menu__list,
        .rtds-dropdown-menu__item {
            @apply rtds-border-gray-01;
        }
    
        .rtds-dropdown-menu__list:where(.is-open) {
            @apply lg:rtds-top-full;
        }
    
        .rtds-dropdown-menu__item {
            @apply rtds-border-b last-of-type:rtds-border-b-0;
        }
    
        .rtds-dropdown-menu__link {
            @apply rtds-p-3 rtds-bg-white hover:rtds-underline hover:rtds-background-02 focus:rtds-background-02;
        }
    
        /* DROPDOWN TRIGGER */
        .rtds-dropdown-menu__trigger[aria-expanded="true"] {
            @apply after:rtds-absolute after:rtds-block after:rtds-bg-transparent after:rtds-border-t-2 after:rtds-border-current after:rtds-h-[1px] after:rtds-w-full after:rtds-left-0 after:rtds-bottom-0;
        }
    
        /* ACTIONS VARIANT STYLES */
        .is-dropdown-menu--actions {
            @apply rtds-flex rtds-justify-end rtds-relative;
        }
    
        .is-dropdown-menu--actions .rtds-dropdown-menu__trigger {
            @apply rtds-rounded-full rtds-border rtds-border-gray-04 rtds-w-10 rtds-h-10 rtds-content-01 rtds-btn--inverted rtds-transition-all;
        }
    
        .is-dropdown-menu--actions .rtds-dropdown-menu__trigger[aria-expanded="true"] {
            @apply rtds-background-08 rtds-content-inverse;
        }
    
        .is-dropdown-menu--actions .rtds-dropdown-menu__list {
            @apply rtds-w-[25ch] rtds-absolute rtds-right-0 rtds-top-10 rtds-bg-white rtds-shadow-lg rtds-z-10 rtds-rounded rtds-border rtds-border-gray-01;
        }
    
        .is-dropdown-menu--actions .rtds-dropdown-menu__item {
            @apply rtds-flex rtds-border-none;
        }
    
        .is-dropdown-menu--actions .rtds-dropdown-menu__link {
            @apply rtds-flex rtds-justify-start rtds-gap-2 rtds-items-center rtds-p-3 rtds-btn--s rtds-w-full rtds-transition rtds-bg-white rtds-font-medium rtds-text-sm rtds-content-primary-dark hover:rtds-underline hover:rtds-background-02 focus:rtds-background-02;
        }
    
        /* MEGAMENU STYLES */
        .rtds-dropdown-menu__megamenu.is-open {
            @apply lg:rtds-background-02;
        }
    
        .has-megamenu .rtds-dropdown-menu__item {
            @apply rtds-border-dashed rtds-border-gray-03 last-of-type:rtds-border-b rtds-font-bold;
        }
    
        .has-megamenu .rtds-dropdown-menu__list {
            @apply rtds-bg-white lg:rtds-bg-transparent lg:rtds-grid lg:rtds-gap-x-8 xl:rtds-gap-x-10 lg:rtds-grid-cols-3 xl:rtds-grid-cols-4 lg:rtds-p-4;
        }
    
        .has-megamenu .rtds-dropdown-menu__link {
            @apply rtds-p-4 lg:rtds-bg-transparent rtds-content-02 rtds-text-base xl:rtds-text-lg;
        }
    
        .rtds-dropdown-menu__megamenu.is-hidden {
            @apply rtds-invisible rtds-absolute lg:rtds-hidden lg:rtds-static rtds-overflow-hidden;
        }
    
        /* MEGAMENU MOBILE */
        .rtds-dropdown-menu.has-megamenu {
            @apply rtds-z-20 rtds-bg-white lg:rtds-static lg:rtds-z-auto lg:rtds-top-auto lg:rtds-left-auto lg:rtds-right-auto lg:rtds-bottom-auto;
        }
    
        .rtds-dropdown-menu.has-megamenu.has-dropdown-open {
            @apply rtds-top-0 rtds-left-0 rtds-right-0 rtds-bottom-0 rtds-absolute rtds-z-30 lg:rtds-static lg:rtds-top-auto lg:rtds-left-auto lg:rtds-right-auto lg:rtds-bottom-auto;
        }
    
        .rtds-dropdown-menu__megamenu .rtds-dropdown-menu__list {
            @apply rtds-invisible rtds-transition-all rtds-opacity-0 rtds-translate-x-full lg:rtds-translate-x-0 rtds-relative rtds-left-full rtds-right-0 rtds-w-0 rtds-h-0 lg:rtds-h-auto lg:rtds-w-full lg:rtds-left-auto lg:rtds-right-auto;
        }
    
        .rtds-dropdown-menu__megamenu.is-open .rtds-dropdown-menu__list {
            @apply rtds-visible rtds-opacity-100 rtds-translate-x-0 rtds-left-0 rtds-w-full;
        }
        
        /* MANAGING NAV PANEL DROPDOWN OPEN */
        :where(.rtds-primary-navigation.has-megamenu) .has-inner-dropdown-open {
            @apply rtds-absolute rtds-top-0 rtds-left-0 rtds-right-0 rtds-bottom-0 rtds-z-30 rtds-bg-white xl:rtds-bg-transparent xl:rtds-z-auto xl:rtds-top-auto xl:rtds-left-auto xl:rtds-right-auto xl:rtds-bottom-auto xl:rtds-static;
        }
    }
  • URL: /components/raw/dropdown-menu/dropdown-menu.css
  • Filesystem Path: components/03-molecules/dropdown-menu/dropdown-menu.css
  • Size: 4.1 KB
  • Content:
    /*
     *   This content is licensed according to the W3C Software License at
     *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
     *
     *   Supplemental JS for the disclosure menu keyboard behavior
     */
    
    'use strict';
    
    // Helper function to find the closest ancestor with a specific tag name
    function findAncestor(element, tagName) {
      while (element) {
        if (element.tagName.toLowerCase() === tagName) {
          return element;
        }
        element = element.parentElement;
      }
      return null;
    }
    
    class DisclosureNav {
      constructor(domNode) {
        this.rootNode = domNode;
        this.controlledNodes = [];
        this.openIndex = null;
        this.useArrowKeys = true;
        this.topLevelNodes = [
          ...this.rootNode.querySelectorAll(
            '.main-link, .rtds-dropdown-trigger'
          ),
        ];
    
        this.topLevelNodes.forEach((node) => {
          if (
            node.tagName.toLowerCase() === 'button' &&
            node.hasAttribute('aria-controls')
          ) {
            // Supporta sia <ul> che <div>
            const menu = node.parentNode.querySelector('ul, div');
    
            if (menu) {
              this.controlledNodes.push(menu);
    
              node.setAttribute('aria-expanded', 'false');
              this.toggleMenu(menu, false);
    
              menu.addEventListener('keydown', this.onMenuKeyDown.bind(this));
              node.addEventListener('click', this.onButtonClick.bind(this));
              node.addEventListener('keydown', this.onButtonKeyDown.bind(this));
            }
          } else {
            this.controlledNodes.push(null);
            node.addEventListener('keydown', this.onLinkKeyDown.bind(this));
          }
        });
    
        // Aggiungiamo un event listener per il click globale
        document.addEventListener('click', this.onDocumentClick.bind(this));
        // Manteniamo anche l'evento focusout per la navigazione da tastiera
        this.rootNode.addEventListener('focusout', this.onBlur.bind(this));
      }
    
      controlFocusByKey(keyboardEvent, nodeList, currentIndex) {
        switch (keyboardEvent.key) {
          case 'ArrowUp':
          case 'ArrowLeft':
            keyboardEvent.preventDefault();
            if (currentIndex > -1) {
              var prevIndex = Math.max(0, currentIndex - 1);
              nodeList[prevIndex].focus();
            }
            break;
          case 'ArrowDown':
          case 'ArrowRight':
            keyboardEvent.preventDefault();
            if (currentIndex > -1) {
              var nextIndex = Math.min(nodeList.length - 1, currentIndex + 1);
              nodeList[nextIndex].focus();
            }
            break;
          case 'Home':
            keyboardEvent.preventDefault();
            nodeList[0].focus();
            break;
          case 'End':
            keyboardEvent.preventDefault();
            nodeList[nodeList.length - 1].focus();
            break;
        }
      }
    
      close() {
        this.toggleExpand(this.openIndex, false);
      }
    
      onBlur(event) {
        // Verifichiamo se il nuovo elemento focusato è all'interno del menu
        const menuContainsFocus = this.rootNode.contains(event.relatedTarget);
        
        // Se il focus è uscito dal menu e non è stato spostato su un altro elemento del menu
        if (!menuContainsFocus && this.openIndex !== null) {
          // Aggiungiamo un piccolo delay per permettere al focus di stabilizzarsi
          setTimeout(() => {
            if (!this.rootNode.contains(document.activeElement)) {
              this.toggleExpand(this.openIndex, false);
            }
          }, 0);
        }
      }
    
      onButtonClick(event) {
        var target = event.target;
    
        if (target.tagName.toLowerCase() !== 'button') {
          var buttonAncestor = findAncestor(target, 'button');
    
          if (buttonAncestor) {
            buttonAncestor.click();
            return;
          }
        }
    
        var button = event.target;
        var buttonIndex = this.topLevelNodes.indexOf(button);
        var buttonExpanded = button.getAttribute('aria-expanded') === 'true';
        this.toggleExpand(buttonIndex, !buttonExpanded);
      }
    
      onButtonKeyDown(event) {
        var targetButtonIndex = this.topLevelNodes.indexOf(document.activeElement);
    
        if (event.key === 'Escape') {
          this.toggleExpand(this.openIndex, false);
        } else if (
          this.useArrowKeys &&
          this.openIndex === targetButtonIndex &&
          event.key === 'ArrowDown'
        ) {
          event.preventDefault();
          this.controlledNodes[this.openIndex].querySelector('a').focus();
        } else if (this.useArrowKeys) {
          this.controlFocusByKey(event, this.topLevelNodes, targetButtonIndex);
        }
      }
    
      onLinkKeyDown(event) {
        var targetLinkIndex = this.topLevelNodes.indexOf(document.activeElement);
    
        if (this.useArrowKeys) {
          this.controlFocusByKey(event, this.topLevelNodes, targetLinkIndex);
        }
      }
    
      onMenuKeyDown(event) {
        if (this.openIndex === null) {
          return;
        }
    
        var menuLinks = Array.prototype.slice.call(
          this.controlledNodes[this.openIndex].querySelectorAll('a')
        );
        var currentIndex = menuLinks.indexOf(document.activeElement);
    
        if (event.key === 'Escape') {
          this.topLevelNodes[this.openIndex].focus();
          this.toggleExpand(this.openIndex, false);
        } else if (this.useArrowKeys) {
          this.controlFocusByKey(event, menuLinks, currentIndex);
        }
      }
    
      toggleExpand(index, expanded) {
        if (this.openIndex !== index) {
          this.toggleExpand(this.openIndex, false);
        }
    
        if (this.topLevelNodes[index]) {
          this.openIndex = expanded ? index : null;
          this.topLevelNodes[index].setAttribute('aria-expanded', expanded);
          this.toggleMenu(this.controlledNodes[index], expanded);
        }
      }
    
      toggleMenu(domNode, show) {
        if (domNode) {
          // Trova l'elemento padre con la classe has-dropdown-menu
          const parentMenu = domNode.closest('.has-dropdown-menu');
          // Trova il modulo di navigazione principale
          const navModule = domNode.closest('.rtds-primary-navigation__module');
          
          // Verifica se è un mega menu
          const isMegaMenu = parentMenu && parentMenu.classList.contains('has-megamenu');
    
          // Gestione delle classi per mostrare/nascondere il menu
          if (show) {
            // Rimuove la classe appropriata in base al tipo di menu
            domNode.classList.remove(isMegaMenu ? 'is-hidden' : 'rtds-hidden');
            domNode.classList.add('is-open');
            if (parentMenu) {
              parentMenu.classList.add('has-dropdown-open');
            }
            if (navModule) {
              navModule.classList.add('has-inner-dropdown-open');
            }
          } else {
            domNode.classList.remove('is-open');
            // Aggiunge la classe appropriata in base al tipo di menu
            domNode.classList.add(isMegaMenu ? 'is-hidden' : 'rtds-hidden');
            if (parentMenu) {
              parentMenu.classList.remove('has-dropdown-open');
            }
            if (navModule) {
              navModule.classList.remove('has-inner-dropdown-open');
            }
          }
    
          const rect = domNode.getBoundingClientRect();
    
          const isOverflowingRight = rect.right > window.innerWidth;
          const isOverflowingLeft = rect.left < 0;
    
          domNode.classList.toggle('rtds-right-0', isOverflowingRight);
          domNode.classList.toggle('rtds-left-0', isOverflowingLeft);
        }
      }
    
      updateKeyControls(useArrowKeys) {
        this.useArrowKeys = useArrowKeys;
      }
    
      // Aggiungiamo un nuovo metodo per gestire i click globali
      onDocumentClick(event) {
        // Se il click è all'interno del menu, non facciamo nulla
        if (this.rootNode.contains(event.target)) {
          return;
        }
        
        // Se c'è un menu aperto, lo chiudiamo
        if (this.openIndex !== null) {
          this.toggleExpand(this.openIndex, false);
        }
      }
    }
    
    /* Inizializza i Disclosure Menus */
    
    window.addEventListener(
      'load',
      function () {
        // Seleziona sia gli elementi con la classe .has-dropdown-menu che i div con la classe .dropdown
        var menus = document.querySelectorAll('.has-dropdown-menu, div.rtds-dropdown-menu');
        var disclosureMenus = [];
    
        for (var i = 0; i < menus.length; i++) {
          disclosureMenus[i] = new DisclosureNav(menus[i]);
        }
      },
      false
    );
  • URL: /components/raw/dropdown-menu/dropdown-menu.js
  • Filesystem Path: components/03-molecules/dropdown-menu/dropdown-menu.js
  • Size: 7.9 KB

Dropdown Menu

Il componente Dropdown Menu fornisce un menu a discesa accessibile e interattivo, con supporto per navigazione da tastiera e screen reader. Supporta diverse varianti, inclusa una versione megamenu per contenuti più complessi e una variante actions per menu di azioni.


Comportamento

Il componente può essere renderizzato come:

  • <div> — wrapper di default per dropdown indipendente
  • <li> — quando listItem: true nel contesto Fractal/Nunjucks; da inserire all’interno di una <ul> di navigazione

Apertura/chiusura al click sul trigger; chiusura automatica quando il focus si sposta fuori dal menu; transizioni fluide; gestione intelligente del posizionamento per evitare overflow.


Varianti

Varianti di Stile

  • default: Menu a discesa standard, larghezza completa, stili responsive con bordo e ombra su desktop
  • list-item: Versione compatibile con liste, larghezza fissa su desktop (52), stili responsive con bordo e ombra
  • megamenu: Menu a discesa a larghezza piena, layout a container su desktop, icone diverse per mobile e desktop
  • actions: Menu di azioni compatto con icona ellipsis verticale, posizionamento a destra con larghezza fissa (25ch), ideale per menu contestuali in card e tabelle

Parametri di configurazione

Contesto di sviluppo Fractal/Nunjucks — Questa sezione riguarda esclusivamente i parametri del context .config.yml usati durante lo sviluppo nella libreria. Non descrive attributi HTML o proprietà da usare nei temi, CMS o ambienti di implementazione: per quello, fare riferimento alla sezione Esempi di utilizzo.

Parametri Base

  • id (stringa, obbligatorio): ID univoco per il dropdown (necessario per l’accessibilità)
  • label (stringa, obbligatorio): Testo del pulsante trigger
  • items (array, obbligatorio): Lista degli elementi del menu
    • label (stringa, obbligatorio): Testo dell’elemento
    • description (stringa, opzionale): Descrizione opzionale dell’elemento
    • iconLeft (stringa, opzionale): ID dell’icona da mostrare a sinistra
    • iconRight (stringa, opzionale): ID dell’icona da mostrare a destra
  • listItem (booleano, opzionale): Se true, il componente viene renderizzato come <li> invece di <div>
  • classes (stringa, opzionale): Classi CSS aggiuntive per personalizzare l’aspetto
  • hasMegamenu (booleano, opzionale): Se true, il dropdown ha un megamenu
  • context (stringa, opzionale): Contesto accessibile per il trigger nella variante actions (es. nome della persona nella card)

Parametri di Stile

  • triggerSpacing (stringa, opzionale): Spaziatura del pulsante trigger
  • triggerFontSize (stringa, opzionale): Dimensione del font del pulsante trigger
  • triggerTextColor (stringa, opzionale): Colore del testo del trigger
  • triggerAriaExpandedStyles (stringa, opzionale): Stili applicati quando il menu è espanso
  • listWidth (stringa, opzionale): Larghezza del menu a discesa
  • listResponsiveStyles (stringa, opzionale): Stili responsive per il menu
  • listItemLinkRadius (stringa, opzionale): Bordi arrotondati per gli elementi del menu
  • listItemLinkFontSize (stringa, opzionale): Dimensione del font per i link degli elementi
  • listPosition (stringa, opzionale): Posizione del menu a discesa (gestisce il posizionamento a sinistra/destra)
  • hoverStyles (stringa, opzionale): Stili per l’hover sugli elementi

Accessibilità

WCAG 2.1

Livello AA — criteri pertinenti:

  • 1.3.1 Informazioni e correlazioni — la struttura è comunicata tramite <button> trigger e <ul> per la lista degli elementi
  • 2.1.1 Tastiera — il menu è completamente navigabile da tastiera tramite frecce direzionali e tasti standard
  • 4.1.2 Nome, ruolo, valore — aria-expanded riflette lo stato aperto/chiuso; aria-controls collega il trigger alla lista

Struttura e semantica

  • <div> — wrapper di default; usare per dropdown indipendenti
  • <li> — usare quando il dropdown è elemento di una lista di navigazione; con classe has-dropdown-menu, da inserire all’interno di una <ul>
  • <button> (trigger) — ruolo implicito button; attivabile con Enter e Space; controlla apertura/chiusura tramite aria-expanded e aria-controls
  • <ul> + <li> + <a> (lista) — struttura semantica di navigazione; ogni elemento è un link nativo

Attributi ARIA

Attributo Valori Condizione
aria-expanded "true" / "false" sempre presente sul <button> trigger
aria-controls ID della lista sempre presente sul <button> trigger
Tasto Azione
Tab / Shift+Tab Navigazione standard tra elementi focusabili
Enter / Space Apre o chiude il menu sul trigger
Arrow Down / Arrow Up Navigazione tra gli elementi del menu aperto
Arrow Left / Arrow Right Navigazione tra i trigger del menu (quando usato in barra di navigazione)
Home / End Sposta il focus al primo / ultimo elemento del menu
Escape Chiude il menu e riporta il focus al trigger

Gestione del focus

  • Focus iniziale: al click sul trigger, il focus rimane sul trigger; gli elementi del menu diventano raggiungibili con le frecce o Tab
  • Focus trap: non presente
  • Focus restoration: alla chiusura del menu (Escape o click esterno), il focus torna al trigger
  • Focus visibile: lo stile :focus-visible è sempre visibile e non viene rimosso via CSS

Screen reader

  • Il trigger ha aria-expanded — lo screen reader annuncia il nome del menu e lo stato aperto/chiuso
  • Nella variante actions, un <span class="rtds-sr-only"> nel trigger aggiunge il contesto necessario (es. “Opzioni [nome persona]”) — lo screen reader lo legge come parte del nome del pulsante, disambiguando trigger identici in liste di card

Stili CSS

Classi Base

  • .rtds-dropdown-menu: Classe base del componente

Classi Elementi (BEM)

  • .rtds-dropdown-menu__trigger: Pulsante trigger
  • .rtds-dropdown-menu__list: Lista degli elementi del menu
  • .rtds-dropdown-menu__item: Elemento del menu
  • .rtds-dropdown-menu__link: Link dell’elemento
  • .rtds-dropdown-menu__megamenu: Contenitore per la variante megamenu

Classi di Stato

  • .has-dropdown-menu: Classe per elementi che contengono un dropdown
  • .has-dropdown-open: Classe per elementi con dropdown aperto
  • .is-open: Classe per menu aperti
  • .is-hidden: Classe per menu nascosti (megamenu)
  • .is-dropdown-menu--actions: Classe specifica per la variante actions

Esempi di utilizzo

<!-- Dropdown standard -->
<div class="rtds-dropdown-menu">
  <button class="rtds-dropdown-menu__trigger rtds-dropdown-trigger rtds-group rtds-w-full rtds-flex rtds-items-center"
          aria-expanded="false" aria-controls="submenuId01">
    Menu item
    <svg class="rtds-ml-auto rtds-transition-all rtds-dropdown-menu__trigger-icon group-aria-expanded:-rtds-rotate-180">...</svg>
  </button>
  <ul class="rtds-dropdown-menu__list rtds-hidden rtds-border rtds-border-t-0" id="submenuId01">
    <li class="rtds-dropdown-menu__item rtds-group/menu-item">
      <a class="rtds-dropdown-menu__link rtds-block rtds-transition" href="">
        <div class="rtds-flex rtds-gap-2 rtds-items-center">
          <span class="rtds-grow">Item label</span>
        </div>
      </a>
    </li>
  </ul>
</div>

Note

  • In preview, lo stile del componente potrebbe apparire incompleto poiché dipende dal contesto del menu/liste in cui viene utilizzato
  • Il componente include la classe DisclosureNav per gestire il comportamento del menu da tastiera
  • Richiede il file JavaScript del componente caricato in pagina per il funzionamento completo