Copy environment

Header

<header class="header  ">
    <div class="header__inner">
        <div class="header__grid grid grid--no-gutter">
            <div class="header__column grid__col grid__col--md-5">

                <button type="button" class="button button--icon header__burger-button ">
                    <span class="button__pseudo-icon">
                        <svg class="icon  button__icon">
                            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#menu"></use>
                        </svg>

                    </span>

                    <span class="button__inner" data-text="">
                        <span class="button__text">

                            <svg class="icon  button__icon">
                                <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#menu"></use>
                            </svg>

                        </span>
                    </span>
                </button>

                <div class="logo  header__logo">
                    <a href="#" class="logo__content logo__link">
                        <figure class="image  logo__image">
                            <img loading="lazy" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" data-srcset="../../inc/logo/logo.svg" data-sizes="auto" alt="letters-logo" class="image__img lazyload">

                        </figure>

                    </a>
                </div>

                <button type="button" class="button button--icon header__search-button header__search-button--mobile ">
                    <span class="button__pseudo-icon">
                        <svg class="icon  button__icon">
                            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#search"></use>
                        </svg>

                    </span>

                    <span class="button__inner" data-text="">
                        <span class="button__text">

                            <svg class="icon  button__icon">
                                <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#search"></use>
                            </svg>

                        </span>
                    </span>
                </button>
            </div>
            <div class="header__column header__column--desktop grid__col grid__col--md-19">
                <div class="header__theme-wrapper">
                    <div class="theme-switcher  header__theme">
                        <button data-theme="theme-beige" class="theme-switcher__button theme-switcher__button--beige">
                            <span class="theme-switcher__icon-cross"></span>
                        </button>
                        <button data-theme="theme-gray" class="theme-switcher__button theme-switcher__button--gray">
                            <span class="theme-switcher__icon-cross"></span>
                        </button>
                        <button data-theme="theme-yellow" class="theme-switcher__button theme-switcher__button--yellow">
                            <span class="theme-switcher__icon-cross"></span>
                        </button>
                        <button data-theme="theme-green" class="theme-switcher__button theme-switcher__button--green">
                            <span class="theme-switcher__icon-cross"></span>
                        </button>
                        <button data-theme="theme-dark" class="theme-switcher__button theme-switcher__button--dark">
                            <span class="theme-switcher__icon-cross"></span>
                        </button>
                    </div>
                </div>

                <button type="button" class="button button--icon-text header__search-button ">

                    <span class="button__inner" data-text="Search">
                        <span class="button__text">
                            Search
                            <svg class="icon  button__icon">
                                <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#arrow-down-left"></use>
                            </svg>

                        </span>
                    </span>
                </button>

                <nav class="navigation  header__navigation text-button">
                    <ul class="navigation__list">
                        <li class="navigation__item is-current navigation__item--only-mobile " data-text="home">
                            <a href="#" class="navigation__link">
                                <span class="navigation__link-text">
                                    home
                                </span>
                            </a>
                        </li>
                        <li class="navigation__item   " data-text="fonts">
                            <a href="#" class="navigation__link">
                                <span class="navigation__link-text">
                                    fonts
                                </span>
                            </a>
                        </li>
                        <li class="navigation__item   " data-text="about">
                            <a href="#" class="navigation__link">
                                <span class="navigation__link-text">
                                    about
                                </span>
                            </a>
                        </li>
                        <li class="navigation__item  navigation__item--only-mobile " data-text="contact">
                            <a href="#" class="navigation__link">
                                <span class="navigation__link-text">
                                    contact
                                </span>
                            </a>
                        </li>
                    </ul>
                </nav>
            </div>
        </div>
        <div class="header__burger-top">

            <button type="button" class="button button--icon header__burger-button header__burger-button--close ">
                <span class="button__pseudo-icon">
                    <svg class="icon  button__icon">
                        <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#exit"></use>
                    </svg>

                </span>

                <span class="button__inner" data-text="">
                    <span class="button__text">

                        <svg class="icon  button__icon">
                            <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#exit"></use>
                        </svg>

                    </span>
                </span>
            </button>
        </div>
    </div>
    <div class="header_appear-container">
        <div class="header__search">
            <form method="get" action="the.url.com">

                <div class="textfield textfield--label-hidden header__search-field">
                    <div class="textfield__inner">
                        <input class="textfield__input" type="text" id="search" name="textfield" placeholder="Search">
                        <label class="textfield__label text-button " for="search">
                            Textfield label
                        </label>
                    </div>
                </div>
            </form>
        </div>
        <div class="header__burger">

            <nav class="navigation  header__navigation text-button">
                <ul class="navigation__list">
                    <li class="navigation__item is-current navigation__item--only-mobile " data-text="home">
                        <a href="#" class="navigation__link">
                            <span class="navigation__link-text">
                                home
                            </span>
                        </a>
                    </li>
                    <li class="navigation__item   " data-text="fonts">
                        <a href="#" class="navigation__link">
                            <span class="navigation__link-text">
                                fonts
                            </span>
                        </a>
                    </li>
                    <li class="navigation__item   " data-text="about">
                        <a href="#" class="navigation__link">
                            <span class="navigation__link-text">
                                about
                            </span>
                        </a>
                    </li>
                    <li class="navigation__item  navigation__item--only-mobile " data-text="contact">
                        <a href="#" class="navigation__link">
                            <span class="navigation__link-text">
                                contact
                            </span>
                        </a>
                    </li>
                </ul>
            </nav>
            <div class="header__burger-heading text-small">switch themes</div>
            <div class="theme-switcher  header__theme">
                <button data-theme="theme-beige" class="theme-switcher__button theme-switcher__button--beige">
                    <span class="theme-switcher__icon-cross"></span>
                </button>
                <button data-theme="theme-gray" class="theme-switcher__button theme-switcher__button--gray">
                    <span class="theme-switcher__icon-cross"></span>
                </button>
                <button data-theme="theme-yellow" class="theme-switcher__button theme-switcher__button--yellow">
                    <span class="theme-switcher__icon-cross"></span>
                </button>
                <button data-theme="theme-green" class="theme-switcher__button theme-switcher__button--green">
                    <span class="theme-switcher__icon-cross"></span>
                </button>
                <button data-theme="theme-dark" class="theme-switcher__button theme-switcher__button--dark">
                    <span class="theme-switcher__icon-cross"></span>
                </button>
            </div>
            <div class="header__burger-heading text-small">Instagram</div>
            <a href="#" class="header__link h2">@lettersfromtartu</a>
        </div>
    </div>
</header>
<header class="header {{ class }} {{ modifier }}">
    <div class="header__inner">
        <div class="header__grid grid grid--no-gutter">
            <div class="header__column grid__col grid__col--md-5">
                {% include '@button' with {class: 'header__burger-button', modifier: "button--icon", data: {icon: "menu"}} %}
                {% if data.logo %}
                    {% include '@logo' with {class: 'header__logo', data: data.logo} %}
                {% endif %}
                {% include '@button' with {class: 'header__search-button header__search-button--mobile', modifier: "button--icon", data: {icon: "search"}} %}
            </div>
            <div class="header__column header__column--desktop grid__col grid__col--md-19">
                {% if data.themeSwitcher %}
                    <div class="header__theme-wrapper">
                        {% include '@theme-switcher' with {class: 'header__theme', data: data.themeSwitcher} %}
                    </div>
                {% endif %}
                {% if data.searchButton %}
                    {% include '@button' with {class: 'header__search-button', modifier: "button--icon-text", data: data.searchButton|merge({icon: "arrow-down-left"})} %}
                {% endif %}
                {% if data.navigation %}
                    {% include '@navigation' with {class: 'header__navigation text-button', data: data.navigation} %}
                {% endif %}
            </div>
        </div>
            <div class="header__burger-top">
                {% include '@button' with {class: 'header__burger-button header__burger-button--close', modifier: "button--icon", data: {icon: "exit"}} %}
            </div>
    </div>
    <div class="header_appear-container">
        {% if data.search %}
            <div class="header__search">
                <form method="get" action="{{data.search.url}}">
                    {% include '@textfield' with {class: 'header__search-field', data: data.search, modifier: 'textfield--label-hidden'}%}
                </form>
            </div>
        {% endif %}
        <div class="header__burger">
            {% if data.navigation %}
                {% include '@navigation' with {class: 'header__navigation text-button', data: data.navigation} %}
            {% endif %}
            {% if data.themeHeading %}
                <div class="header__burger-heading text-small">{{ data.themeHeading }}</div>
            {% endif %}
            {% if data.themeSwitcher %}
                {% include '@theme-switcher' with {class: 'header__theme', data: data.themeSwitcher} %}
            {% endif %}
            {% if data.instagram %}
                <div class="header__burger-heading text-small">{{ data.instagram.heading }}</div>
                <a href="{{ data.instagram.link }}" class="header__link h2">{{ "@" ~ data.instagram.handle }}</a>
            {% endif %}
        </div>
    </div>
</header>
{
  "language": "en-US",
  "data": {
    "themeHeading": "switch themes",
    "instagram": {
      "heading": "Instagram",
      "link": "#",
      "handle": "lettersfromtartu"
    },
    "logo": {
      "image": {
        "alt": "letters-logo",
        "srcset": "../../inc/logo/logo.svg"
      },
      "link": "#"
    },
    "themeSwitcher": {
      "palettes": [
        {
          "class": "beige"
        },
        {
          "class": "gray"
        },
        {
          "class": "yellow"
        },
        {
          "class": "green"
        },
        {
          "class": "dark"
        }
      ]
    },
    "searchButton": {
      "text": "Search"
    },
    "navigation": {
      "items": [
        {
          "link": "#",
          "title": "home",
          "current": "true",
          "is_only_mobile": true
        },
        {
          "link": "#",
          "title": "fonts"
        },
        {
          "link": "#",
          "title": "about"
        },
        {
          "link": "#",
          "title": "contact",
          "is_only_mobile": true
        }
      ]
    },
    "search": {
      "label": "Textfield label",
      "id": "search",
      "name": "textfield",
      "placeholder": "Search",
      "url": "the.url.com"
    }
  }
}
  • Content:
    @keyframes bounceDiagonal {
        0% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: 0;
            left: 0;
        }
    
        50% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: 4px;
            left: 4px;
        }
    
        100% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: 0;
            left: 0;
        }
    }
    
    @keyframes bounceDiagonalUp {
        0% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: -2px;
            left: 0;
        }
    
        50% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: -6px;
            left: 4px;
        }
    
        100% {
            transition-timing-function: $transition-easing;
            position: relative;
            top: -2px;
            left: 0;
        }
    }
    
    .header {
        position: fixed;
        top: 0;
        left: 0;
        display: flex;
        flex-direction: column;
        transition: $transition-duration $transition-easing;
        transition-property: transform;
        transform: translateY(-100%);
        width: 100%;
        z-index: map-get($zindex, header);
    
        .header-is-visible & {
            transform: translateY(0);
        }
    }
    
    .header_appear-container {
        position: relative;
        margin-top: -40px;
        height: 40px;
    
        @include bp(sm-min) {
            margin-top: -60px;
            height: 60px;
        }
    }
    
    .header__grid {
        flex-wrap: nowrap;
        flex: 1 0 auto;
    }
    
    .header__inner {
        background-color: var(--color-background);
        display: flex;
        flex-direction: row;
        position: relative;
        z-index: 2;
        transition: $transition-duration $transition-easing;
        transition-property: background-color;
    }
    
    .header__burger-top {
        position: absolute;
        display: flex;
        justify-content: flex-end;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        box-shadow: 0 -1px 0 0 var(--color-text) inset;
        background-color: var(--color-background);
        transform: translateX(-100%);
        transition: $transition-duration $transition-easing;
        transition-property: transform, background-color, box-shadow;
    
        &.is-visible {
            transform: translateX(0);
        }
    
        @include bp(md-min) {
            display: none;
        }
    }
    
    .header__burger-button {
        box-shadow: 0 -1px 0 0 var(--color-text) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(md-min) {
            display: none;
        }
    }
    
    .header__burger-button--close {
        box-shadow: 1px 0 0 0 var(--color-text) inset;
    }
    
    .header__theme-wrapper {
        flex-grow: 1;
        display: none;
        flex-direction: row;
        align-items: center;
        box-shadow: 1px -1px 0 0 var(--color-text) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        .header__burger & {
            display: flex;
            box-shadow: none;
        }
    
        @include bp(md-min) {
            display: flex;
        }
    }
    
    .header__theme {
        position: absolute;
        margin: 0;
        top: 0;
        left: 0;
        display: none;
        width: 100%;
        height: 100%;
        justify-content: center;
        align-items: center;
        pointer-events: none;
    
        .header__burger & {
            position: relative;
            display: flex;
            box-shadow: none;
            flex-basis: 10%;
            justify-content: flex-start;
            margin-left: 16px;
            margin-top: 24px;
        }
    
        @include bp(md-min) {
            display: flex;
        }
    }
    
    .header__column {
        display: flex;
    }
    
    .header__column--desktop {
        display: none;
    
        @include bp(md-min) {
            display: flex;
        }
    }
    
    .header__logo {
        box-shadow: 1px -1px 0 0 var(--color-text) inset;
        flex-grow: 1;
        height: 100%;
        max-height: 40px;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            max-height: 60px;
        }
    
        @include bp(md-min) {
            box-shadow: 0 -1px 0 0 var(--color-text) inset;
            display: block;
        }
    }
    
    .header__search-button {
        box-shadow: 1px -1px 0 0 var(--color-text) inset;
        padding: 0 24px;
        display: none;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(md-min) {
            display: block;
        }
    }
    
    .header__search-button--mobile {
        box-shadow: 1px -1px 0 0 var(--color-text) inset;
        padding: 0;
        display: block;
    
        @include bp(md-min) {
            display: none;
        }
    }
    
    .header__navigation {
        flex-grow: 1;
        display: none;
    
        .header__burger & {
            display: block;
            margin-bottom: 30px;
        }
    
        @include bp(md-min) {
            flex-grow: 0;
            display: block;
        }
    }
    
    .header__search {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        background-color: var(--color-background);
        transition: $transition-duration $transition-easing;
        transition-property: top, background-color;
    
        .search-is-visible & {
            top: 100%;
        }
    }
    
    .header__search-field {
        width: 100%;
    }
    
    .header__search-field .textfield__input {
        border-top: none;
        width: 100%;
        padding-left: 60px;
    
        @include bp(md-min) {
            padding-left: 90px;
        }
    }
    
    .header__burger-close-button {
        box-shadow: 1px 0 0 0 var(--color-text) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    }
    
    .header__burger {
        position: absolute;
        overflow: hidden;
        overflow-y: auto;
        top: 40px;
        left: 0;
        right: 0;
        transform: translateY(-100%);
        display: flex;
        flex-direction: column;
        background-color: var(--color-background);
        border-bottom: 1px solid var(--color-brand);
        height: calc(100vh - 39px); /* stylelint-disable-line plugin/no-unsupported-browser-features */
        flex-basis: 33%;
        transition: $transition-duration $transition-easing;
        transition-property: transform, background-color, border-bottom;
    
        &.is-visible {
            transform: translateY(0);
        }
    
        @include bp(sm-min) {
            height: calc(100vh - 60px); /* stylelint-disable-line plugin/no-unsupported-browser-features */
            top: 60px;
        }
    
        @include bp(md-min) {
            display: none;
        }
    }
    
    .header__burger-heading {
        padding: 6px 16px;
        margin-top: 30px;
        border-top: 1px solid var(--color-brand);
        border-bottom: 1px solid var(--color-brand);
        transition: $transition-duration $transition-easing;
        transition-property: border-top, border-bottom;
        text-transform: uppercase;
        color: rgba(var(--color-text--rgb), .7);
    }
    
    .header__link {
        margin: 40px 16px;
        cursor: pointer;
        white-space: normal;
        font-size: #{'min(8vw,#{$font-size-h2})'};
        line-height: $font-line-height-h2;
    
        @include bp(sm-min) {
            font-size: $font-size-h2-lg;
            line-height: $font-line-height-h2-lg;
        }
    
        &:after {
            content: none;
        }
    
        &:before {
            content: none;
        }
    }
    
    .button__icon {
        .header & {
            transition: transform $transition-duration $transition-easing;
        }
    
        .search-is-visible .header__search-button & {
            @include bp(md-min) {
                position: relative;
                top: -2px;
                left: 0;
                transform: rotate(-90deg);
            }
        }
    
        .header__search-button:hover & {
            @include bp(md-min) {
                @media (hover: hover) {
                    position: relative;
                    animation: bounceDiagonal 500ms infinite;
                }
            }
        }
    
        .search-is-visible .header__search-button:hover & {
            @include bp(md-min) {
                @media (hover: hover) {
                    animation: bounceDiagonalUp 500ms infinite;
                }
            }
        }
    
        .search-is-visible .header__search-button:active & {
            @include bp(md-min) {
                animation: none;
            }
        }
    
        .header__search-button:active & {
            animation: none;
        }
    }
    
  • URL: /components/raw/header/header.scss
  • Filesystem Path: src/patterns/modules/header/header.scss
  • Size: 7.9 KB
  • Content:
    import './header.scss';
    import Component from '@component';
    import ClickEvent = JQuery.ClickEvent;
    import Helpers from '@helpers';
    
    interface IHeaderSettings {
        searchButtonClass: string;
        burgerButtonClass: string;
        searchClass: string;
        searchIsVisibleClass: string;
        burgerClass: string;
        burgerTopClass: string;
        isVisibleClass: string;
        stickyHeaderSelector: string;
        headerIsVisibleClass: string;
    }
    
    export default class Header extends Component {
        static initSelector: string = '.header';
    
        searchButtons: JQuery;
        burgerButton: JQuery;
        settings: IHeaderSettings;
    
        searchField: JQuery;
        searchInput: JQuery;
        burgerMenu: JQuery;
        stickyHeaders: JQuery;
        previousScrollY: number;
    
        constructor(target: HTMLElement) {
            super(target);
    
            this.settings = {
                burgerButtonClass: 'header__burger-button',
                burgerClass: 'header__burger',
                burgerTopClass: 'header__burger-top',
                headerIsVisibleClass: 'header-is-visible',
                isVisibleClass: 'is-visible',
                searchButtonClass: 'header__search-button',
                searchClass: 'header__search',
                searchIsVisibleClass: 'search-is-visible',
                stickyHeaderSelector: '.content-section--sticky .content-section__title',
            };
    
            this.previousScrollY = window.scrollY;
            $('body').addClass(this.settings.headerIsVisibleClass);
    
            this.searchButtons = this.element.find('.' + this.settings.searchButtonClass);
            this.burgerButton = this.element.find('.' + this.settings.burgerButtonClass);
    
            this.searchField = this.element.find('.' + this.settings.searchClass);
            this.searchInput = this.searchField.find('input');
            this.burgerMenu = this.element.find('.' + this.settings.burgerClass);
    
            this.stickyHeaders = $(document).find(this.settings.stickyHeaderSelector);
    
            this.init();
        }
    
        init(): void {
            this.searchButtons.on('click', this.toggleSearch.bind(this));
            this.burgerButton.on('click', this.toggleBurger.bind(this));
            this.element.on('click', this.stopPropagation.bind(this));
            window.addEventListener('scroll', this.toggleHeader.bind(this));
            window.addEventListener('click', this.closeSearch.bind(this));
            window.addEventListener('resize', this.resizeHandler.bind(this));
    
            requestAnimationFrame(this.stickyHeadingHandler.bind(this));
        }
    
        resizeHandler(): void {
            if (window.matchMedia('only screen and (min-width: 768px)').matches) {
                this.closeBurger();
            }
    
            this.stickyHeadingHandler();
        }
    
        stopPropagation(event: ClickEvent): void {
            event.stopPropagation();
        }
    
        closeSearch(): void {
            this.element.removeClass(this.settings.searchIsVisibleClass);
        }
    
        openSearch(): void {
            this.element.addClass(this.settings.searchIsVisibleClass);
        }
    
        toggleSearch(): void {
            if (this.element.hasClass(this.settings.searchIsVisibleClass)) {
                this.closeSearch();
            } else {
                this.openSearch();
            }
    
            requestAnimationFrame(this.stickyHeadingHandler.bind(this));
        }
    
        closeBurger(): void {
            this.burgerMenu.removeClass(this.settings.isVisibleClass);
            this.element.find('.' + this.settings.burgerTopClass).removeClass(this.settings.isVisibleClass);
            Helpers.enableScroll();
            this.previousScrollY = window.scrollY;
        }
    
        openBurger(): void {
            this.burgerMenu.addClass(this.settings.isVisibleClass);
            this.element.find('.' + this.settings.burgerTopClass).addClass(this.settings.isVisibleClass);
            Helpers.disableScroll();
            this.closeSearch();
        }
    
        toggleBurger(): void {
            if (this.burgerMenu.hasClass(this.settings.isVisibleClass)) {
                this.closeBurger();
            } else {
                this.openBurger();
            }
        }
    
        getMaxTop(): number {
            if (this.element[0] && this.searchField[0]) {
                const headerRect: DOMRect = this.element[0].getBoundingClientRect();
                const headerTop: number = headerRect.y + headerRect.height;
    
                const searchRect: DOMRect = this.searchField[0].getBoundingClientRect();
                const searchTop: number = searchRect.y + searchRect.height;
    
                return Math.max(0, Math.max(headerTop, searchTop) - 2);
            } else {
                return 0;
            }
        }
    
        stickyHeadingHandler(previousTop?: number): void {
            this.setStickyHeadingTop(this.getMaxTop());
    
            requestAnimationFrame(() => {
                this.setStickyHeadingTop(this.getMaxTop());
                if (previousTop === undefined || previousTop !== this.getMaxTop()) {
                    requestAnimationFrame(() => this.stickyHeadingHandler(this.getMaxTop()));
                }
            });
        }
    
        setStickyHeadingTop(top: number): void {
            this.stickyHeaders.css('top', top - 2);
        }
    
        toggleHeader(): void {
            this.stickyHeadingHandler();
        }
    }
    
  • URL: /components/raw/header/header.ts
  • Filesystem Path: src/patterns/modules/header/header.ts
  • Size: 5 KB