Copy environment

Search

<div class="search">
    <div class="search__inner">
        <div class="search__textfield-wrapper">

            <div class="textfield search__textfield">
                <label class="textfield__label  h-visually-hidden" for="search1">
                    Otsing
                </label>
                <div class="textfield__inner">
                    <input class="textfield__input" type="text" id="search1" name="search" placeholder="Otsi arvete hulgast...">
                </div>
            </div>
            <button class="search__clear js-search-clear" type="button" aria-label="Tühjenda">
                <span class="search__clear-inner">
                    <svg class="icon  search__icon" focusable="false">
                        <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#close"></use>
                    </svg>
                </span>
            </button>
        </div>
        <button class="search__button search__button--toggle js-search-toggle" type="button" aria-label="Otsi">
            <span class="search__button-inner">
                <svg class="icon  search__icon" focusable="false">
                    <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#search"></use>
                </svg>
            </span>
        </button>
        <button class="search__button search__button--submit" type="submit" aria-label="Otsi">
            <span class="search__button-inner">
                <svg class="icon  search__icon" focusable="false">
                    <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#search"></use>
                </svg>
            </span>
        </button>
    </div>
</div>
{% set BEM -%}
    search
    {%- if modifier %} {{ modifier }}{% endif %}
    {%- if class %} {{ class }}{% endif %}
{% endset %}

<div class="{{ BEM }}">
    <div class="search__inner">
        <div class="search__textfield-wrapper">
            {% include '@textfield' with { class: 'search__textfield', modifier: '', data: data.textfield } %}
            <button class="search__clear js-search-clear" type="button" aria-label="{{ data.clearText }}">
                <span class="search__clear-inner">
                    {% include '@icon' with { name: 'close', class: 'search__icon', modifier: '' } %}
                </span>
            </button>
        </div>
        <button class="search__button search__button--toggle js-search-toggle" type="button" aria-label="{{ data.searchText }}">
            <span class="search__button-inner">
                {% include '@icon' with { name: 'search', class: 'search__icon', modifier: '' } %}
            </span>
        </button>
        <button class="search__button search__button--submit" type="submit" aria-label="{{ data.submitText }}">
            <span class="search__button-inner">
                {% include '@icon' with { name: 'search', class: 'search__icon', modifier: '' } %}
            </span>
        </button>
    </div>
</div>
{
  "language": "en-US",
  "data": {
    "textfield": {
      "label": "Otsing",
      "id": "search1",
      "name": "search",
      "placeholder": "Otsi arvete hulgast...",
      "isLabelHidden": true
    },
    "clearText": "Tühjenda",
    "searchText": "Otsi",
    "submitText": "Otsi"
  }
}
  • Content:
    .search {
        display: none;
    
        @include bp(lg-min) {
            display: block;
        }
    
        &.is-open {
            display: block;
        }
    }
    
    .search__inner {
        display: flex;
        align-items: center;
    
        @include bp(lg-min) {
            gap: 2px;
        }
    }
    
    .search__button {
        display: inline-block;
        padding: 0;
        background: transparent;
        border: none;
        border-radius: $border-radius-base;
        color: $brand-primary;
        outline: none;
        text-align: center;
        cursor: pointer;
        -webkit-appearance: none;
        transition: background $transition-duration-s $transition-easing,
            border-radius $transition-duration-s $transition-easing,
            color $transition-duration-s $transition-easing;
    
        &:hover {
            background: $L-background-none-hover;
        }
    
        html[data-whatinput='keyboard'] &:focus {
            background: $L-background-none-hover;
            outline: 2px solid $L-filter-focus;
            outline-offset: 2px;
        }
    
        .search.is-open & {
            background: $brand-primary;
            color: $L-text-inverted;
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
        }
    }
    
    .search__button--toggle {
        display: none;
    
        @include bp(lg-min) {
            display: inline-block;
        }
    }
    
    .search__button--submit {
        @include bp(lg-min) {
            display: none;
        }
    }
    
    .search__button-inner {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 6px;
    
        .search__button--submit & {
            padding: 8px;
        }
    }
    
    .search__clear {
        opacity: 0;
        visibility: hidden;
        display: inline-block;
        position: absolute;
        top: 50%;
        right: 0;
        padding: 0;
        background: transparent;
        border: none;
        color: $L-border-medium;
        outline: none;
        text-align: center;
        cursor: pointer;
        -webkit-appearance: none;
        transform: translateY(-50%);
        transition: opacity $transition-duration-s $transition-easing,
            visibility $transition-duration-s $transition-easing;
    
        &:hover {
            color: $brand-primary;
        }
    
        .search.is-dirty & {
            opacity: 1;
            visibility: visible;
        }
    }
    
    .search__clear-inner {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 6px;
    }
    
    .search__icon {
        flex: 0 0 24px;
        font-size: 24px;
    }
    
    .search__textfield-wrapper {
        display: block;
        position: relative;
        flex: 1 1 100%;
        opacity: 0;
        visibility: hidden;
        transition: opacity $transition-duration-s $transition-easing,
            visibility $transition-duration-s $transition-easing;
    
        .search.is-open & {
            opacity: 1;
            visibility: visible;
        }
    }
    
    .textfield__input {
        .search__textfield & {
            border: 1px solid $L-border-medium;
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
            min-height: 40px;
        }
    }
    
  • URL: /components/raw/search/search.scss
  • Filesystem Path: src/patterns/components/search/search/search.scss
  • Size: 2.8 KB
  • Content:
    import Component from '../../component/component';
    
    import './search.scss';
    
    export interface ISearchSettings {
        buttonSelector?: string;
        clearSelector?: string;
        dirtyClass?: string;
        inputSelector?: string;
        openClass?: string;
    }
    
    export const searchSettings: ISearchSettings = {
        buttonSelector: '.js-search-toggle',
        clearSelector: '.js-search-clear',
        dirtyClass: 'is-dirty',
        inputSelector: '.textfield__input',
        openClass: 'is-open',
    };
    
    export default class Search extends Component {
        static initSelector: string = '.search';
    
        clear: JQuery<HTMLElement>;
        input: JQuery<HTMLElement>;
        settings: ISearchSettings;
        toggle: JQuery<HTMLElement>;
    
        constructor(target: HTMLElement) {
            super(target);
    
            this.settings = searchSettings;
    
            this.clear = this.element.find(this.settings.clearSelector);
            this.input = $('body').find(this.settings.inputSelector);
            this.toggle = this.element.find(this.settings.buttonSelector);
    
            this.toggle.on('click', this.onClick.bind(this));
            this.input.on('keyup change', this.handleInputChange.bind(this));
            this.clear.on('click', this.handleClear.bind(this));
        }
    
        onClick(): void {
            if (this.element.hasClass(this.settings.openClass)) {
                this.element.removeClass(this.settings.openClass);
            } else {
                this.element.addClass(this.settings.openClass);
    
                window.setTimeout(() => {
                    this.input.trigger('focus');
                }, 150);
            }
        }
    
        handleInputChange(): void {
            if (this.input.val() !== '') {
                this.element.addClass(this.settings.dirtyClass);
            } else {
                this.element.removeClass(this.settings.dirtyClass);
            }
        }
    
        handleClear(): void {
            this.input.val('');
            this.element.removeClass(this.settings.dirtyClass);
        }
    }
    
    $(() => {
        $(document).on('click', (event: Event) => {
            const isDirty: boolean = $('.search').hasClass(searchSettings.dirtyClass);
    
            if ($(event.target).closest('.search').length === 0 && $(event.target).closest('.search-toggle').length === 0 && !isDirty) {
                $('.search').removeClass(searchSettings.openClass);
                $('.search-toggle').removeClass(searchSettings.openClass);
            }
        });
    });
    
  • URL: /components/raw/search/search.ts
  • Filesystem Path: src/patterns/components/search/search/search.ts
  • Size: 2.3 KB
  • Handle: @search--default
  • Filesystem Path: src/patterns/components/search/search/search.twig
  • References (2): @textfield, @icon
  • Referenced by (1): @table-filter