Copy environment

Profile

<div class="profile">
    <button class="profile__toggle js-profile-toggle" type="button">
        <span class="profile__toggle-inner">
            <span class="grid grid--no-wrap">
                <span class="grid__col grid__col--max">
                    <span class="profile__role">NOPE kliendihaldur</span>
                    <span class="profile__name text-small">
                        <span class="profile__name-inner">
                            Kaarel Nurmsalu
                        </span>
                    </span>
                </span>
                <span class="grid__col grid__col--min">
                    <svg class="icon  profile__icon" focusable="false">
                        <use href="../../inc/svg/global.4609ec92109fc41e7ad4764ef897ea8e.svg#chevron-bottom"></use>
                    </svg>
                </span>
            </span>
        </span>
    </button>
    <div class="profile__content text-small">
        <div class="profile__content-inner">
            <div class="grid grid--no-wrap grid--equalheight">
                <div class="grid__col grid__col--min">
                    <figure class="image image--full image--round profile__image">

                        <img loading="lazy" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2048%2048%22%3E%3C%2Fsvg%3E" data-srcset="//via.placeholder.com/100x100 100w, //via.placeholder.com/200x200 200w, //via.placeholder.com/300x300 300w, //via.placeholder.com/400x400 400w, //via.placeholder.com/500x500 500w, //via.placeholder.com/600x600 600w, //via.placeholder.com/700x700 700w, //via.placeholder.com/800x800 800w, //via.placeholder.com/48x48 48w, //via.placeholder.com/96x96 96w" data-sizes="auto" alt="" class="image__img lazyload">

                    </figure>
                </div>
                <div class="grid__col grid__col--max">
                    <div class="profile__data">
                        <div class="profile__role">NOPE kliendihaldur</div>
                        <span class="profile__name">Kaarel Nurmsalu</span> <a class="profile__phone" href="tel:+372&nbsp;53&nbsp;453&nbsp;833">+372&nbsp;53&nbsp;453&nbsp;833</a><br> <a class="profile__email" href="mailto:kaarel.nurmsalu@ramirent.ee">kaarel.nurmsalu@ramirent.ee</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{% set BEM -%}
    profile
    {%- if modifier %} {{ modifier }}{% endif %}
    {%- if class %} {{ class }}{% endif %}
{% endset %}

<div class="{{ BEM }}">
    <button class="profile__toggle js-profile-toggle" type="button">
        <span class="profile__toggle-inner">
            <span class="grid grid--no-wrap">
                <span class="grid__col grid__col--max">
                    <span class="profile__role">{{ data.role }}</span>
                    {% if data.name %}
                        <span class="profile__name text-small">
                            <span class="profile__name-inner">
                                {{ data.name }}
                            </span>
                        </span>
                    {% endif %}
                </span>
                <span class="grid__col grid__col--min">
                    {% include '@icon' with { modifier: '', class: 'profile__icon', name: 'chevron-bottom' } %}
                </span>
            </span>
        </span>
    </button>
    <div class="profile__content text-small">
        <div class="profile__content-inner">
            <div class="grid grid--no-wrap grid--equalheight">
                {% if data.image %}
                    <div class="grid__col grid__col--min">
                        {% include '@image' with {
                            data: data.image|srcset('48x48'),
                            class: 'profile__image',
                            modifier: 'image--full image--round',
                        } %}
                    </div>
                {% endif %}
                <div class="grid__col grid__col--max">
                    <div class="profile__data">
                        <div class="profile__role">{{ data.role }}</div>
                        {% if data.name %}<span class="profile__name">{{ data.name }}</span>{% endif %}
                        {% if data.phone %}<a class="profile__phone" href="tel:{{ data.phone }}">{{ data.phone }}</a><br>{% endif %}
                        {% if data.email %}<a class="profile__email" href="mailto:{{ data.email }}">{{ data.email }}</a>{% endif %}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{
  "language": "en-US",
  "data": {
    "role": "NOPE kliendihaldur",
    "name": "Kaarel Nurmsalu",
    "phone": "+372&nbsp;53&nbsp;453&nbsp;833",
    "email": "kaarel.nurmsalu@ramirent.ee",
    "image": true
  }
}
  • Content:
    .profile {
        color: $L-text-inverted;
    }
    
    .profile__toggle {
        display: block;
        width: 100%;
        padding: 0;
        background: transparent;
        border: none;
        color: $L-text-inverted;
        outline: none;
        -webkit-appearance: none;
        text-align: left;
        cursor: pointer;
    
        html[data-whatinput='keyboard'] &:focus {
            outline: 1px solid $L-text-inverted;
            outline-offset: 2px;
        }
    
        @include bp(sm-min) {
            display: none;
        }
    }
    
    .profile__toggle-inner {
        display: block;
    }
    
    .profile__content {
        opacity: 0;
        visibility: hidden;
        max-height: 0;
        overflow: hidden;
        transition: opacity $transition-duration $transition-easing,
            visibility $transition-duration $transition-easing,
            max-height $transition-duration $transition-easing;
    
        @include bp(sm-min) {
            opacity: 1;
            visibility: visible;
            max-height: none;
            overflow: visible;
        }
    
        .profile.is-opening & {
            opacity: 1;
            visibility: visible;
        }
    
        .profile.is-closing & {
            opacity: 0;
            visibility: hidden;
        }
    
        .profile.is-open & {
            opacity: 1;
            visibility: visible;
            max-height: none;
            overflow: visible;
        }
    }
    
    .profile__role {
        display: block;
        font-size: $font-size-small;
        font-weight: $font-weight-bold;
        letter-spacing: $letter-spacing-default;
        line-height: $line-height-small;
    
        .profile__content & {
            display: none;
    
            @include bp(sm-min) {
                display: block;
            }
        }
    }
    
    .profile__icon {
        flex: 0 0 24px;
        font-size: 24px;
        transition: transform $transition-duration-s $transition-easing;
    
        .profile.is-opening &,
        .profile.is-open & {
            transform: rotate(180deg);
        }
    }
    
    .profile__image {
        width: 48px;
        height: 48px;
    
        @include bp(sm-min) {
            align-self: flex-end;
        }
    }
    
    .profile__phone,
    .profile__email {
        color: $L-text-inverted;
        text-decoration: none;
    
        &:hover,
        &:focus,
        &:active {
            color: $L-text-inverted;
        }
    }
    
    .profile__name {
        display: block;
    
        .profile__toggle & {
            overflow: hidden;
            transition: opacity $transition-duration $transition-easing,
                visibility $transition-duration $transition-easing,
                max-height $transition-duration $transition-easing;
    
            .profile.is-open &,
            .profile.profile.is-opening & {
                opacity: 0;
                visibility: hidden;
            }
    
            .profile.is-open & {
                max-height: 0;
            }
        }
    }
    
    .profile__name-inner {
        display: block;
        padding-top: 8px;
    }
    
  • URL: /components/raw/profile/profile.scss
  • Filesystem Path: src/patterns/components/profile/profile.scss
  • Size: 2.6 KB
  • Content:
    import Component from '../component/component';
    
    import './profile.scss';
    
    export interface IProfileSettings {
        animationDuration?: number;
        closingClass?: string;
        contentSelector?: string;
        nameSelector?: string;
        openClass?: string;
        openingClass?: string;
        toggleSelector?: string;
    }
    
    export const profileSettings: IProfileSettings = {
        animationDuration: 300,
        closingClass: 'is-closing',
        contentSelector: '.profile__content',
        nameSelector: '.profile__name',
        openClass: 'is-open',
        openingClass: 'is-opening',
        toggleSelector: '.js-profile-toggle',
    };
    
    export default class Profile extends Component {
        static initSelector: string = '.profile';
    
        content: JQuery<HTMLElement>;
        inner: JQuery<HTMLElement>;
        isOpen: boolean;
        name: JQuery<HTMLElement>;
        timeout: number;
        nameTimeout: number;
        toggleButton: JQuery<HTMLElement>;
        settings: IProfileSettings;
    
        constructor(target: HTMLElement) {
            super(target);
    
            this.settings = profileSettings;
    
            this.content = this.element.find(this.settings.contentSelector);
            this.inner = this.content.children().first();
            this.isOpen = false;
            this.toggleButton = this.element.find(this.settings.toggleSelector);
            this.name = this.toggleButton.find(this.settings.nameSelector);
    
            this.toggleButton.on('click', this.handleClick.bind(this));
        }
    
        handleClick(): void {
            this.toggle();
        }
    
        toggle(): void {
            this.isOpen = !this.isOpen;
    
            if (this.isOpen) {
                this.element.addClass(this.settings.openingClass);
    
                this.open(this.content);
                this.hideName();
            } else {
                this.element.addClass(this.settings.closingClass);
    
                this.close(this.content);
                this.showName();
            }
        }
    
        open(el: JQuery<HTMLElement>): void {
            el.css({
                maxHeight: this.inner.innerHeight(),
            });
    
            clearTimeout(this.timeout);
    
            this.timeout = window.setTimeout(() => {
                el.removeAttr('style');
    
                this.element.removeClass(this.settings.openingClass);
                this.element.addClass(this.settings.openClass);
            }, this.settings.animationDuration);
        }
    
        close(el: JQuery<HTMLElement>): void {
            el.css({
                maxHeight: this.inner.innerHeight(),
            });
    
            this.element.removeClass(this.settings.openClass);
    
            clearTimeout(this.timeout);
    
            this.timeout = window.setTimeout(() => {
                el.css({
                    maxHeight: 0,
                });
    
                clearTimeout(this.timeout);
    
                this.timeout = window.setTimeout(() => {
                    el.removeAttr('style');
    
                    this.element.removeClass(this.settings.closingClass);
                }, this.settings.animationDuration);
            }, 10);
        }
    
        hideName(): void {
            const inner: JQuery<HTMLElement> = this.name.children().first();
    
            this.name.css({
                maxHeight: inner.outerHeight(),
            });
    
            clearTimeout(this.nameTimeout);
    
            this.nameTimeout = window.setTimeout(() => {
                this.name.css({
                    maxHeight: 0,
                });
    
                clearTimeout(this.nameTimeout);
    
                this.nameTimeout = window.setTimeout(() => {
                    this.name.removeAttr('style');
                }, this.settings.animationDuration);
            }, 10);
        }
    
        showName(): void {
            const inner: JQuery<HTMLElement> = this.name.children().first();
    
            this.name.css({
                maxHeight: inner.outerHeight(),
            });
    
            clearTimeout(this.nameTimeout);
    
            this.nameTimeout = window.setTimeout(() => {
                this.name.removeAttr('style');
            }, this.settings.animationDuration);
        }
    }
    
  • URL: /components/raw/profile/profile.ts
  • Filesystem Path: src/patterns/components/profile/profile.ts
  • Size: 3.8 KB
  • Handle: @profile--default
  • Filesystem Path: src/patterns/components/profile/profile.twig
  • References (2): @icon, @image
  • Referenced by (1): @profile-bar