Copy environment

Select

<div class="textfield select ">
    <div class="textfield__inner">
        <select name="select" id="select1" class="textfield__input select__input" data-text="Select label">
            <option value="1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.</option>
            <option value="2" selected>Option 2</option>
            <option value="3">Option 3</option>
        </select>
        <svg class="icon  select__icon">
            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#chevron-bottom"></use>
        </svg>

        <label class="textfield__label text-button select__label" for="select1">
            Select label
        </label>
    </div>
</div>
{% set input %}
    <select
        name="{{ data.name }}"
        id="{{ data.id }}"
        class="textfield__input select__input"
        data-text="{{ data.label }}"
        {% if data.isDisabled %} disabled{% endif %}
        {{ data.attributes }}
    >
        {% for option in data.options %}
            <option
                value="{{ option.value }}"
                {% if option.isSelected %} selected {% endif %}
            >{{ option.name }}</option>
        {% endfor %}
    </select>
    {% include '@icon' with { class: 'select__icon', name: 'chevron-bottom' } %}
{% endset %}

{% include '@textfield' with {
    data: data,
    input: input,
    class: 'select ' ~ class,
    modifier: modifier,
    labelClass: 'select__label'
} %}
{
  "language": "en-US",
  "data": {
    "label": "Select label",
    "id": "select1",
    "name": "select",
    "options": [
      {
        "name": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.",
        "value": "1"
      },
      {
        "name": "Option 2",
        "value": "2",
        "isSelected": true
      },
      {
        "name": "Option 3",
        "value": "3"
      }
    ]
  }
}
  • Content:
    .select {
        position: relative;
        margin: 0;
        cursor: pointer;
        z-index: map-get($zindex, 'default');
    
        &.is-disabled {
            opacity: .3;
            cursor: default;
        }
    }
    
    .select__input {
        display: none;
    }
    
    .select__icon {
        position: absolute;
        font-size: 24px;
        top: 7px;
        right: 15px;
        pointer-events: none;
        transition: $transition-duration $transition-easing;
        transition-property: transform, fill;
        fill: var(--color-text);
    
        .select__container.is-open + & {
            transform: rotate(180deg);
        }
    
        .select__container.is-focused + & {
            outline: none;
            fill: rgba(var(--color-text--rgb), .5);
        }
    
        @include bp(sm-min) {
            right: 7px;
            top: 17px;
        }
    }
    
    .select__inner {
        display: none;
        width: 100%;
    
        &:hover {
            @media (hover: hover) {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
    
            &:disabled {
                @media (hover: hover) {
                    background-color: transparent;
                    border-color: var(--color-brand);
                    color: var(--color-text);
                }
            }
        }
    
        .select__container.is-focused & {
            outline: none;
            background-color: rgba(var(--color-brand--rgb), .02);
            border-color: var(--color-brand);
            color: rgba(var(--color-text--rgb), .5);
    
            &:disabled {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
        }
    
        .select__container & {
            display: block;
        }
    }
    
    .select__dropdown {
        visibility: hidden;
        z-index: 2;
        position: absolute;
        top: 100%;
        width: 100%;
        border: none;
        overflow: hidden;
        word-break: break-all; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        will-change: visibility; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        background-color: var(--color-background);
    
        .select--search & {
            padding-top: 48px;
        }
    
        .select__container.is-flipped & {
            top: auto;
            bottom: 100%;
    
            .select--search & {
                padding-top: 0;
                padding-bottom: 48px;
            }
        }
    
        .select__container.is-open & {
            visibility: visible;
            border-bottom: 1px solid var(--color-brand);
        }
    
        .select__container.is-open.is-flipped & {
            border-bottom: none;
            border-top: 1px solid var(--color-brand);
        }
    }
    
    .select__list {
        .select__dropdown & {
            overflow-y: auto;
            will-change: scroll-position; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        }
    }
    
    .select__list--single {
        display: flex;
        align-items: center;
        flex-direction: row;
        overflow: hidden;
        white-space: nowrap;
        padding: 10px 0;
        width: 100%;
        height: 100%;
    }
    
    .select__item {
        display: flex;
        align-items: center;
        padding: 8px 16px;
        width: 100%;
        flex-shrink: 1;
    
        @include bp(sm-min) {
            padding: 15px 24px;
        }
    
        .select__list--single & {
            display: block;
            padding: 0 40px 0 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            pointer-events: none;
    
            &.select__item-label {
                width: auto;
                flex-shrink: 0;
                white-space: pre;
                padding-right: 0;
            }
        }
    
        &.select__item--choice {
            transition: $transition-duration $transition-easing;
            transition-property: background-color, color;
    
            &.is-selected {
                background-color: rgba(var(--color-brand--rgb), .05);
            }
    
            &.select__item--highlighted {
                background-color: var(--color-brand);
                color: var(--color-text-inverse);
            }
        }
    }
    
    .select__remove {
        display: none;
    }
    
    .select__label {
        display: none;
    }
    
  • URL: /components/raw/select/select.scss
  • Filesystem Path: src/patterns/components/forms/select/select.scss
  • Size: 4 KB
  • Content:
    import Choices, {Choices as ChoicesLib} from 'choices.js';
    
    import Component from '@component';
    
    import '@textfield';
    
    import './select.scss';
    
    export default class Select extends Component {
        static initSelector: string = '.select';
    
        public input: JQuery;
        public choices: Choices;
        public isOpen: boolean;
    
        constructor(target: HTMLElement) {
            super(target);
            this.input = this.element.find('.select__input');
            this.isOpen = false;
    
            this.init();
        }
    
        init(): void {
            this.choices = new Choices(this.input[0] as HTMLInputElement, {
                callbackOnCreateTemplates(template: ChoicesLib.Types.strToEl): Partial<ChoicesLib.Templates> { // eslint-disable-line prefer-arrow/prefer-arrow-functions
                    return {
                        dropdown: (classNames: ChoicesLib.ClassNames): HTMLElement => template(`
                            <div class="${classNames.list} ${classNames.listDropdown}" aria-expanded="false"></div>
                        `) as HTMLElement,
                    };
                },
                classNames: {
                    activeState: 'is-active',
                    button: 'select__remove',
                    containerInner: 'textfield__input select__inner',
                    containerOuter: 'select__container',
                    disabledState: 'is-disabled',
                    flippedState: 'is-flipped',
                    focusState: 'is-focused',
                    group: 'select__group',
                    groupHeading: 'select__group-heading',
                    highlightedState: 'select__item--highlighted',
                    input: 'select__choices-input',
                    inputCloned: 'select__input--cloned',
                    item: 'select__item text-button',
                    itemChoice: 'select__item--choice',
                    itemDisabled: 'select__item--disabled',
                    itemSelectable: 'select__item--selectable',
                    list: 'select__list',
                    listDropdown: 'select__dropdown',
                    listItems: 'select__list--multiple',
                    listSingle: 'select__list--single',
                    loadingState: 'is-loading',
                    noChoices: 'has-no-choices',
                    noResults: 'has-no-results',
                    openState: 'is-open',
                    placeholder: 'select__placeholder',
                    selectedState: 'is-selected',
                },
                itemSelectText: '',
                removeItems: false,
                renderSelectedChoices: 'always',
                searchChoices: false,
                searchEnabled: false,
            });
    
            this.addEventListeners();
    
            requestAnimationFrame(() => this.addLabel());
        }
    
        addEventListeners(): void {
            this.input.get(0).addEventListener('choice', this.updateItem.bind(this));
    
            this.element.find('.select__inner > .select__list').on('click', (): void => {
                if (this.isOpen) {
                    this.choices.hideDropdown();
                }
            });
    
            this.input.get(0).addEventListener('hideDropdown', (): void => {
                this.isOpen = false;
            });
    
            this.input.get(0).addEventListener('showDropdown', (): void => {
                this.element.find('.select__dropdown .choices__item').first().focus();
    
                this.isOpen = true;
            });
        }
    
        addLabel(): void {
            const span: HTMLSpanElement = document.createElement('span');
            const list: HTMLElement = this.element.find('.select__list')[0];
    
            if (list.childElementCount === 1) {
                span.innerHTML = this.input.attr('data-text') + ': ';
                list.children[0].classList.forEach((_class: string) => span.classList.add(_class));
                span.classList.add('select__item-label');
    
                list.insertBefore(span, list.childNodes[0]);
            }
        }
    
        updateItem(): void {
            requestAnimationFrame(() => this.addLabel());
        }
    }
    
  • URL: /components/raw/select/select.ts
  • Filesystem Path: src/patterns/components/forms/select/select.ts
  • Size: 3.9 KB
  • Handle: @select--default
  • Filesystem Path: src/patterns/components/forms/select/select.twig
  • References (2): @icon, @textfield
  • Referenced by (1): @item-filter

Invalid

<div class="textfield select  is-invalid">
    <div class="textfield__inner">
        <select name="select" id="select1" class="textfield__input select__input" data-text="Select label">
            <option value="1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.</option>
            <option value="2" selected>Option 2</option>
            <option value="3">Option 3</option>
        </select>
        <svg class="icon  select__icon">
            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#chevron-bottom"></use>
        </svg>

        <label class="textfield__label text-button select__label" for="select1">
            Select label
        </label>
    </div>
    <div class="textfield__error text-small">
        Please check your input
    </div>
</div>
{% set input %}
    <select
        name="{{ data.name }}"
        id="{{ data.id }}"
        class="textfield__input select__input"
        data-text="{{ data.label }}"
        {% if data.isDisabled %} disabled{% endif %}
        {{ data.attributes }}
    >
        {% for option in data.options %}
            <option
                value="{{ option.value }}"
                {% if option.isSelected %} selected {% endif %}
            >{{ option.name }}</option>
        {% endfor %}
    </select>
    {% include '@icon' with { class: 'select__icon', name: 'chevron-bottom' } %}
{% endset %}

{% include '@textfield' with {
    data: data,
    input: input,
    class: 'select ' ~ class,
    modifier: modifier,
    labelClass: 'select__label'
} %}
{
  "language": "en-US",
  "data": {
    "label": "Select label",
    "id": "select1",
    "name": "select",
    "options": [
      {
        "name": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.",
        "value": "1"
      },
      {
        "name": "Option 2",
        "value": "2",
        "isSelected": true
      },
      {
        "name": "Option 3",
        "value": "3"
      }
    ],
    "isInvalid": true,
    "error": "Please check your input"
  }
}
  • Content:
    .select {
        position: relative;
        margin: 0;
        cursor: pointer;
        z-index: map-get($zindex, 'default');
    
        &.is-disabled {
            opacity: .3;
            cursor: default;
        }
    }
    
    .select__input {
        display: none;
    }
    
    .select__icon {
        position: absolute;
        font-size: 24px;
        top: 7px;
        right: 15px;
        pointer-events: none;
        transition: $transition-duration $transition-easing;
        transition-property: transform, fill;
        fill: var(--color-text);
    
        .select__container.is-open + & {
            transform: rotate(180deg);
        }
    
        .select__container.is-focused + & {
            outline: none;
            fill: rgba(var(--color-text--rgb), .5);
        }
    
        @include bp(sm-min) {
            right: 7px;
            top: 17px;
        }
    }
    
    .select__inner {
        display: none;
        width: 100%;
    
        &:hover {
            @media (hover: hover) {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
    
            &:disabled {
                @media (hover: hover) {
                    background-color: transparent;
                    border-color: var(--color-brand);
                    color: var(--color-text);
                }
            }
        }
    
        .select__container.is-focused & {
            outline: none;
            background-color: rgba(var(--color-brand--rgb), .02);
            border-color: var(--color-brand);
            color: rgba(var(--color-text--rgb), .5);
    
            &:disabled {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
        }
    
        .select__container & {
            display: block;
        }
    }
    
    .select__dropdown {
        visibility: hidden;
        z-index: 2;
        position: absolute;
        top: 100%;
        width: 100%;
        border: none;
        overflow: hidden;
        word-break: break-all; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        will-change: visibility; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        background-color: var(--color-background);
    
        .select--search & {
            padding-top: 48px;
        }
    
        .select__container.is-flipped & {
            top: auto;
            bottom: 100%;
    
            .select--search & {
                padding-top: 0;
                padding-bottom: 48px;
            }
        }
    
        .select__container.is-open & {
            visibility: visible;
            border-bottom: 1px solid var(--color-brand);
        }
    
        .select__container.is-open.is-flipped & {
            border-bottom: none;
            border-top: 1px solid var(--color-brand);
        }
    }
    
    .select__list {
        .select__dropdown & {
            overflow-y: auto;
            will-change: scroll-position; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        }
    }
    
    .select__list--single {
        display: flex;
        align-items: center;
        flex-direction: row;
        overflow: hidden;
        white-space: nowrap;
        padding: 10px 0;
        width: 100%;
        height: 100%;
    }
    
    .select__item {
        display: flex;
        align-items: center;
        padding: 8px 16px;
        width: 100%;
        flex-shrink: 1;
    
        @include bp(sm-min) {
            padding: 15px 24px;
        }
    
        .select__list--single & {
            display: block;
            padding: 0 40px 0 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            pointer-events: none;
    
            &.select__item-label {
                width: auto;
                flex-shrink: 0;
                white-space: pre;
                padding-right: 0;
            }
        }
    
        &.select__item--choice {
            transition: $transition-duration $transition-easing;
            transition-property: background-color, color;
    
            &.is-selected {
                background-color: rgba(var(--color-brand--rgb), .05);
            }
    
            &.select__item--highlighted {
                background-color: var(--color-brand);
                color: var(--color-text-inverse);
            }
        }
    }
    
    .select__remove {
        display: none;
    }
    
    .select__label {
        display: none;
    }
    
  • URL: /components/raw/select/select.scss
  • Filesystem Path: src/patterns/components/forms/select/select.scss
  • Size: 4 KB
  • Content:
    import Choices, {Choices as ChoicesLib} from 'choices.js';
    
    import Component from '@component';
    
    import '@textfield';
    
    import './select.scss';
    
    export default class Select extends Component {
        static initSelector: string = '.select';
    
        public input: JQuery;
        public choices: Choices;
        public isOpen: boolean;
    
        constructor(target: HTMLElement) {
            super(target);
            this.input = this.element.find('.select__input');
            this.isOpen = false;
    
            this.init();
        }
    
        init(): void {
            this.choices = new Choices(this.input[0] as HTMLInputElement, {
                callbackOnCreateTemplates(template: ChoicesLib.Types.strToEl): Partial<ChoicesLib.Templates> { // eslint-disable-line prefer-arrow/prefer-arrow-functions
                    return {
                        dropdown: (classNames: ChoicesLib.ClassNames): HTMLElement => template(`
                            <div class="${classNames.list} ${classNames.listDropdown}" aria-expanded="false"></div>
                        `) as HTMLElement,
                    };
                },
                classNames: {
                    activeState: 'is-active',
                    button: 'select__remove',
                    containerInner: 'textfield__input select__inner',
                    containerOuter: 'select__container',
                    disabledState: 'is-disabled',
                    flippedState: 'is-flipped',
                    focusState: 'is-focused',
                    group: 'select__group',
                    groupHeading: 'select__group-heading',
                    highlightedState: 'select__item--highlighted',
                    input: 'select__choices-input',
                    inputCloned: 'select__input--cloned',
                    item: 'select__item text-button',
                    itemChoice: 'select__item--choice',
                    itemDisabled: 'select__item--disabled',
                    itemSelectable: 'select__item--selectable',
                    list: 'select__list',
                    listDropdown: 'select__dropdown',
                    listItems: 'select__list--multiple',
                    listSingle: 'select__list--single',
                    loadingState: 'is-loading',
                    noChoices: 'has-no-choices',
                    noResults: 'has-no-results',
                    openState: 'is-open',
                    placeholder: 'select__placeholder',
                    selectedState: 'is-selected',
                },
                itemSelectText: '',
                removeItems: false,
                renderSelectedChoices: 'always',
                searchChoices: false,
                searchEnabled: false,
            });
    
            this.addEventListeners();
    
            requestAnimationFrame(() => this.addLabel());
        }
    
        addEventListeners(): void {
            this.input.get(0).addEventListener('choice', this.updateItem.bind(this));
    
            this.element.find('.select__inner > .select__list').on('click', (): void => {
                if (this.isOpen) {
                    this.choices.hideDropdown();
                }
            });
    
            this.input.get(0).addEventListener('hideDropdown', (): void => {
                this.isOpen = false;
            });
    
            this.input.get(0).addEventListener('showDropdown', (): void => {
                this.element.find('.select__dropdown .choices__item').first().focus();
    
                this.isOpen = true;
            });
        }
    
        addLabel(): void {
            const span: HTMLSpanElement = document.createElement('span');
            const list: HTMLElement = this.element.find('.select__list')[0];
    
            if (list.childElementCount === 1) {
                span.innerHTML = this.input.attr('data-text') + ': ';
                list.children[0].classList.forEach((_class: string) => span.classList.add(_class));
                span.classList.add('select__item-label');
    
                list.insertBefore(span, list.childNodes[0]);
            }
        }
    
        updateItem(): void {
            requestAnimationFrame(() => this.addLabel());
        }
    }
    
  • URL: /components/raw/select/select.ts
  • Filesystem Path: src/patterns/components/forms/select/select.ts
  • Size: 3.9 KB
  • Handle: @select--invalid
  • Filesystem Path: src/patterns/components/forms/select/select.twig
  • References (2): @icon, @textfield

Disabled

<div class="textfield select  is-dirty is-disabled">
    <div class="textfield__inner">
        <select name="select" id="select1" class="textfield__input select__input" data-text="Select label" disabled>
            <option value="1">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.</option>
            <option value="2" selected>Option 2</option>
            <option value="3">Option 3</option>
        </select>
        <svg class="icon  select__icon">
            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#chevron-bottom"></use>
        </svg>

        <label class="textfield__label text-button select__label" for="select1">
            Select label
        </label>
    </div>
</div>
{% set input %}
    <select
        name="{{ data.name }}"
        id="{{ data.id }}"
        class="textfield__input select__input"
        data-text="{{ data.label }}"
        {% if data.isDisabled %} disabled{% endif %}
        {{ data.attributes }}
    >
        {% for option in data.options %}
            <option
                value="{{ option.value }}"
                {% if option.isSelected %} selected {% endif %}
            >{{ option.name }}</option>
        {% endfor %}
    </select>
    {% include '@icon' with { class: 'select__icon', name: 'chevron-bottom' } %}
{% endset %}

{% include '@textfield' with {
    data: data,
    input: input,
    class: 'select ' ~ class,
    modifier: modifier,
    labelClass: 'select__label'
} %}
{
  "language": "en-US",
  "data": {
    "label": "Select label",
    "id": "select1",
    "name": "select",
    "options": [
      {
        "name": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veritatis error velit quidem alias nihil mollitia temporibus, maxime dicta repellat. Perspiciatis veniam doloribus, quia corporis commodi sed omnis adipisci facilis nisi.",
        "value": "1"
      },
      {
        "name": "Option 2",
        "value": "2",
        "isSelected": true
      },
      {
        "name": "Option 3",
        "value": "3"
      }
    ],
    "isDisabled": true,
    "value": "Tere"
  }
}
  • Content:
    .select {
        position: relative;
        margin: 0;
        cursor: pointer;
        z-index: map-get($zindex, 'default');
    
        &.is-disabled {
            opacity: .3;
            cursor: default;
        }
    }
    
    .select__input {
        display: none;
    }
    
    .select__icon {
        position: absolute;
        font-size: 24px;
        top: 7px;
        right: 15px;
        pointer-events: none;
        transition: $transition-duration $transition-easing;
        transition-property: transform, fill;
        fill: var(--color-text);
    
        .select__container.is-open + & {
            transform: rotate(180deg);
        }
    
        .select__container.is-focused + & {
            outline: none;
            fill: rgba(var(--color-text--rgb), .5);
        }
    
        @include bp(sm-min) {
            right: 7px;
            top: 17px;
        }
    }
    
    .select__inner {
        display: none;
        width: 100%;
    
        &:hover {
            @media (hover: hover) {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
    
            &:disabled {
                @media (hover: hover) {
                    background-color: transparent;
                    border-color: var(--color-brand);
                    color: var(--color-text);
                }
            }
        }
    
        .select__container.is-focused & {
            outline: none;
            background-color: rgba(var(--color-brand--rgb), .02);
            border-color: var(--color-brand);
            color: rgba(var(--color-text--rgb), .5);
    
            &:disabled {
                background-color: transparent;
                border-color: var(--color-brand);
                color: var(--color-text);
            }
        }
    
        .select__container & {
            display: block;
        }
    }
    
    .select__dropdown {
        visibility: hidden;
        z-index: 2;
        position: absolute;
        top: 100%;
        width: 100%;
        border: none;
        overflow: hidden;
        word-break: break-all; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        will-change: visibility; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        background-color: var(--color-background);
    
        .select--search & {
            padding-top: 48px;
        }
    
        .select__container.is-flipped & {
            top: auto;
            bottom: 100%;
    
            .select--search & {
                padding-top: 0;
                padding-bottom: 48px;
            }
        }
    
        .select__container.is-open & {
            visibility: visible;
            border-bottom: 1px solid var(--color-brand);
        }
    
        .select__container.is-open.is-flipped & {
            border-bottom: none;
            border-top: 1px solid var(--color-brand);
        }
    }
    
    .select__list {
        .select__dropdown & {
            overflow-y: auto;
            will-change: scroll-position; /* stylelint-disable-line plugin/no-unsupported-browser-features */
        }
    }
    
    .select__list--single {
        display: flex;
        align-items: center;
        flex-direction: row;
        overflow: hidden;
        white-space: nowrap;
        padding: 10px 0;
        width: 100%;
        height: 100%;
    }
    
    .select__item {
        display: flex;
        align-items: center;
        padding: 8px 16px;
        width: 100%;
        flex-shrink: 1;
    
        @include bp(sm-min) {
            padding: 15px 24px;
        }
    
        .select__list--single & {
            display: block;
            padding: 0 40px 0 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            pointer-events: none;
    
            &.select__item-label {
                width: auto;
                flex-shrink: 0;
                white-space: pre;
                padding-right: 0;
            }
        }
    
        &.select__item--choice {
            transition: $transition-duration $transition-easing;
            transition-property: background-color, color;
    
            &.is-selected {
                background-color: rgba(var(--color-brand--rgb), .05);
            }
    
            &.select__item--highlighted {
                background-color: var(--color-brand);
                color: var(--color-text-inverse);
            }
        }
    }
    
    .select__remove {
        display: none;
    }
    
    .select__label {
        display: none;
    }
    
  • URL: /components/raw/select/select.scss
  • Filesystem Path: src/patterns/components/forms/select/select.scss
  • Size: 4 KB
  • Content:
    import Choices, {Choices as ChoicesLib} from 'choices.js';
    
    import Component from '@component';
    
    import '@textfield';
    
    import './select.scss';
    
    export default class Select extends Component {
        static initSelector: string = '.select';
    
        public input: JQuery;
        public choices: Choices;
        public isOpen: boolean;
    
        constructor(target: HTMLElement) {
            super(target);
            this.input = this.element.find('.select__input');
            this.isOpen = false;
    
            this.init();
        }
    
        init(): void {
            this.choices = new Choices(this.input[0] as HTMLInputElement, {
                callbackOnCreateTemplates(template: ChoicesLib.Types.strToEl): Partial<ChoicesLib.Templates> { // eslint-disable-line prefer-arrow/prefer-arrow-functions
                    return {
                        dropdown: (classNames: ChoicesLib.ClassNames): HTMLElement => template(`
                            <div class="${classNames.list} ${classNames.listDropdown}" aria-expanded="false"></div>
                        `) as HTMLElement,
                    };
                },
                classNames: {
                    activeState: 'is-active',
                    button: 'select__remove',
                    containerInner: 'textfield__input select__inner',
                    containerOuter: 'select__container',
                    disabledState: 'is-disabled',
                    flippedState: 'is-flipped',
                    focusState: 'is-focused',
                    group: 'select__group',
                    groupHeading: 'select__group-heading',
                    highlightedState: 'select__item--highlighted',
                    input: 'select__choices-input',
                    inputCloned: 'select__input--cloned',
                    item: 'select__item text-button',
                    itemChoice: 'select__item--choice',
                    itemDisabled: 'select__item--disabled',
                    itemSelectable: 'select__item--selectable',
                    list: 'select__list',
                    listDropdown: 'select__dropdown',
                    listItems: 'select__list--multiple',
                    listSingle: 'select__list--single',
                    loadingState: 'is-loading',
                    noChoices: 'has-no-choices',
                    noResults: 'has-no-results',
                    openState: 'is-open',
                    placeholder: 'select__placeholder',
                    selectedState: 'is-selected',
                },
                itemSelectText: '',
                removeItems: false,
                renderSelectedChoices: 'always',
                searchChoices: false,
                searchEnabled: false,
            });
    
            this.addEventListeners();
    
            requestAnimationFrame(() => this.addLabel());
        }
    
        addEventListeners(): void {
            this.input.get(0).addEventListener('choice', this.updateItem.bind(this));
    
            this.element.find('.select__inner > .select__list').on('click', (): void => {
                if (this.isOpen) {
                    this.choices.hideDropdown();
                }
            });
    
            this.input.get(0).addEventListener('hideDropdown', (): void => {
                this.isOpen = false;
            });
    
            this.input.get(0).addEventListener('showDropdown', (): void => {
                this.element.find('.select__dropdown .choices__item').first().focus();
    
                this.isOpen = true;
            });
        }
    
        addLabel(): void {
            const span: HTMLSpanElement = document.createElement('span');
            const list: HTMLElement = this.element.find('.select__list')[0];
    
            if (list.childElementCount === 1) {
                span.innerHTML = this.input.attr('data-text') + ': ';
                list.children[0].classList.forEach((_class: string) => span.classList.add(_class));
                span.classList.add('select__item-label');
    
                list.insertBefore(span, list.childNodes[0]);
            }
        }
    
        updateItem(): void {
            requestAnimationFrame(() => this.addLabel());
        }
    }
    
  • URL: /components/raw/select/select.ts
  • Filesystem Path: src/patterns/components/forms/select/select.ts
  • Size: 3.9 KB
  • Handle: @select--disabled
  • Filesystem Path: src/patterns/components/forms/select/select.twig
  • References (2): @icon, @textfield