Copy environment

Languages

<nav class="languages  ">
    <button type="button" class="languages__trigger" aria-label="Toggle language menu" aria-expanded="false">
        eng
        <svg class="icon  languages__chevron">
            <use xlink:href="../../inc/svg/global.bc9cdd731ad718497c5d8f03d08908d4.svg#chevron-bottom"></use>
        </svg>
    </button>
    <ul class="languages__list">
        <li class="languages__item ">
            <a href="#" class="languages__link" aria-label="Estonian ">est</a>
        </li>
        <li class="languages__item is-current">
            <a href="#" class="languages__link" aria-label="English - current language">eng</a>
        </li>
        <li class="languages__item ">
            <a href="#" class="languages__link" aria-label="Russian ">rus</a>
        </li>
    </ul>
</nav>
<nav class="languages {{ modifier }} {{ class }}">
    {% for item in data.items %}
        {% if item.current %}
            <button type="button" class="languages__trigger" aria-label="{{ data.label }}" aria-expanded="false">
                {{ item.shortName }}
                {% include '@icon' with { name: 'chevron-bottom', class: 'languages__chevron' } %}
            </button>
        {% endif %}
    {% endfor %}
    {% if data.items %}
        <ul class="languages__list">
            {% for item in data.items %}
                <li class="languages__item {% if item.current %}is-current{% endif %}">
                    <a href="{{ item.link }}" class="languages__link" aria-label="{{ item.fullName }} {% if item.current and data.currentLabel %}{{ '- ' ~ data.currentLabel }}{% endif %}">{{ item.shortName }}</a>
                </li>
            {% endfor %}
        </ul>
    {% endif %}
</nav>
{
  "language": "en-US",
  "data": {
    "label": "Toggle language menu",
    "currentLabel": "current language",
    "items": [
      {
        "link": "#",
        "shortName": "est",
        "fullName": "Estonian"
      },
      {
        "link": "#",
        "shortName": "eng",
        "fullName": "English",
        "current": "true"
      },
      {
        "link": "#",
        "shortName": "rus",
        "fullName": "Russian"
      }
    ]
  }
}
  • Content:
    .languages {
        position: relative;
        display: inline-block;
        text-transform: uppercase;
        z-index: map-get($zindex, 'languages');
        overflow: hidden;
    
        &.is-active {
            overflow: visible;
        }
    }
    
    .languages__trigger {
        appearance: none;
        text-align: center;
        background: transparent;
        border: none;
        text-transform: uppercase;
        margin: 0;
        padding: 12px 50px 12px 24px;
        align-items: center;
        cursor: pointer;
        color: $color-text-01;
    }
    
    .languages__link {
        display: block;
        color: $color-text-01;
        text-decoration: none;
        padding: 12px 16px;
    
        &:hover {
            background-color: $color-ui-03;
        }
    }
    
    .languages__chevron {
        position: absolute;
        top: 0;
        bottom: 0;
        right: 24px;
        font-size: 24px;
        margin: auto 0 auto 4px;
        pointer-events: none;
    
        @include bp(md-min) {
            margin: auto 0;
        }
    
        .languages.is-active & {
            transform: rotate(180deg);
        }
    }
    
    .languages__list {
        position: absolute;
        top: 100%;
        right: 0;
        z-index: map-get($zindex, 'default');
        background-color: $color-ui-01;
        border-radius: $border-radius-base;
        box-shadow: $elevation-05;
        padding: 4px 0;
        display: inline-block;
        opacity: 0;
        visibility: hidden;
        transition: visibility $transition-duration $transition-easing, opacity $transition-duration $transition-easing;
    
        .languages.to-top & {
            top: auto;
            bottom: 100%;
        }
    
        .languages.is-active & {
            opacity: 1;
            visibility: visible;
        }
    }
    
  • URL: /components/raw/languages/languages.scss
  • Filesystem Path: src/patterns/components/languages/languages.scss
  • Size: 1.6 KB
  • Content:
    import Component from '../component/component';
    
    import './languages.scss';
    
    interface ILanguageSettings {
        activeClass: string;
        topClass: string;
    }
    
    export default class Languages extends Component {
        static initSelector: string = '.languages';
    
        public trigger: JQuery;
    
        settings: ILanguageSettings;
    
        constructor(target: HTMLElement) {
            super(target);
    
            this.trigger = this.element.find('.languages__trigger');
    
            this.documentClickHandler = this.documentClickHandler.bind(this);
    
            this.settings = {
                activeClass: 'is-active',
                topClass: 'to-top',
            };
    
            this.init();
        }
    
        init(): void {
            this.trigger.on('click', this.toggleHandler.bind(this));
            this.element.on('keyup.languages', this.keyboardHandler.bind(this));
        }
    
        addEventListeners(): void {
            $(document).on('click.languages', this.documentClickHandler);
        }
    
        documentClickHandler(event: JQuery.TriggeredEvent): void {
            if ($(event.target).closest(this.element).length === 0) {
                this.close();
            }
        }
    
        toggleHandler(event: Event): void {
            event.preventDefault();
    
            if (this.element.hasClass(this.settings.activeClass)) {
                this.close();
            } else {
                this.open();
            }
        }
    
        keyboardHandler(event: KeyboardEvent): void {
            if (event.key === 'Escape') {
                this.close();
                this.trigger.focus();
            }
        }
    
        open(): void {
            if (this.getListDirection() === 'top') {
                this.element.addClass(this.settings.topClass);
            } else {
                this.element.removeClass(this.settings.topClass);
            }
    
            this.element.addClass(this.settings.activeClass);
            this.trigger.attr('aria-expanded', 'true');
    
            this.addEventListeners();
        }
    
        close(): void {
            this.element.removeClass(this.settings.activeClass);
            this.trigger.attr('aria-expanded', 'false');
    
            this.destroy();
        }
    
        getListDirection(): 'top' | 'bottom' {
            const elemTop: number = this.element.offset().top;
            const windowTop: number = $(window).scrollTop();
            const windowHeight: number = $(window).height();
            const elemHeight: number = this.element.outerHeight();
            const ddHeight: number = this.element.find('.languages__list').outerHeight();
    
            if ((elemTop - windowTop + elemHeight + ddHeight) > windowHeight) {
                return 'top';
            } else {
                return 'bottom';
            }
        }
    
        destroy(): void {
            $(document).off('click.languages', this.documentClickHandler);
        }
    }
    
  • URL: /components/raw/languages/languages.ts
  • Filesystem Path: src/patterns/components/languages/languages.ts
  • Size: 2.7 KB
  • Handle: @languages--default
  • Filesystem Path: src/patterns/components/languages/languages.twig
  • References (1): @icon