Copy environment

Newsletter

<form class="newsletter   ">
    <div class="newsletter__textfield-container">

        <div class="textfield textfield--label-hidden textfield--border-hidden newsletter__textfield">
            <div class="textfield__inner">
                <input class="textfield__input" type="text" id="text1" name="textfield" placeholder="Enter your email here">
                <label class="textfield__label text-button " for="text1">
                    newsletter
                </label>
            </div>
        </div>

        <button type="submit" class="button  newsletter__button ">

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

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

        <button type="submit" class="button button--icon newsletter__button newsletter__button--mobile ">
            <span class="button__pseudo-icon">
                <svg class="icon  button__icon">
                    <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#arrow-enter-bold"></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#arrow-enter-bold"></use>
                    </svg>

                </span>
            </span>
        </button>
    </div>
    <span class="newsletter__error-message"></span>
</form>
<form class="newsletter {{ modifier }} {{ class }} {% if data.label %}newsletter--block{% endif %}">
    <div class="newsletter__textfield-container">
        {% if data.label %}
            <div class="newsletter__button-wrapper">
                {% if data.textfield %}
                    {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
                {% endif %}
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
            <div class="newsletter__button-wrapper">
                <div class="newsletter__label text-small">
                    {{ data.label }}
                    <span class="newsletter__error-message"></span>
                </div>
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
        {% else %}
            {% if data.static %}
                <input type="text" name="name" value="" class="newsletter__textfield-static">
            {% endif %}
            {% if data.textfield %}
                {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
            {% endif %}
            {% if data.button %}
                {% include '@button' with {class: 'newsletter__button', type: 'submit', data: data.button} %}
            {% endif %}
            {% if data.buttonMobile %}
                {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', type: 'submit', modifier: 'button--icon', data: data.buttonMobile} %}
            {% endif %}
        {% endif %}
    </div>
    {% if not data.label %}
        <span class="newsletter__error-message"></span>
    {% endif %}
    {% if data.check %}
        <div class="newsletter__check-container">
            {% include '@check' with {class: 'newsletter__check', data: data.check} %}
        </div>
    {% endif %}
    {% if data.thanks %}
        <div class="newsletter__success">
            {% if data.thanks.title %}
                <div class="text-large newsletter__vw-title">
                    {{ data.thanks.title }}
                </div>
            {% endif %}
            {{ data.thanks.message }}
        </div>
    {% endif %}
</form>
{
  "language": "en-US",
  "data": {
    "textfield": {
      "label": "newsletter",
      "id": "text1",
      "name": "textfield",
      "placeholder": "Enter your email here"
    },
    "button": {
      "text": "subscribe"
    },
    "buttonMobile": {
      "icon": "arrow-enter-bold"
    }
  }
}
  • Content:
    .newsletter {
        position: relative;
    }
    
    .newsletter__textfield-container {
        display: flex;
        box-shadow: -1px 1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        .newsletter--block & {
            flex-direction: column-reverse;
            box-shadow: 0 1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: none;
                flex-wrap: nowrap;
            }
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            visibility: hidden;
        }
    }
    
    .newsletter__button-wrapper {
        display: flex;
    
        @include bp(sm-min) {
            width: 100%;
        }
    }
    
    .newsletter__label {
        flex-grow: 1;
        overflow: hidden;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: flex;
        align-items: center;
        opacity: .7;
        text-transform: uppercase;
        padding: 6px 16px 5px;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding: 0 0 0 32px;
            font-size: $font-size-button-lg;
            line-height: $font-line-height-button-lg;
            opacity: 1;
        }
    
        @include bp(md-min) {
            padding-left: 16px;
        }
    
        .newsletter--block & {
            box-shadow: 0 -1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: 0 -1px 0 0 var(--color-brand) inset;
            }
        }
    }
    
    .newsletter__check-container {
        display: flex;
        margin-top: 27px;
    
        @include bp(sm-min) {
            margin-top: 64px;
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            display: none;
        }
    }
    
    .newsletter__textfield {
        flex-grow: 1;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding-left: 17px;
        }
    
        @include bp(md-min) {
            padding-left: 0;
        }
    
        .newsletter--block & {
            box-shadow: none;
        }
    }
    
    .newsletter__textfield-static {
        width: 0;
        height: 0;
        border: 0;
        padding: 0;
        margin: 0;
    }
    
    .newsletter__button {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: none;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            display: block;
        }
    }
    
    .newsletter__button--mobile {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: block;
    
        .newsletter--block & {
            box-shadow: 1px 0 0 0 var(--color-brand) inset;
        }
    
        @include bp(sm-min) {
            display: none;
        }
    }
    
    .newsletter__success {
        position: absolute;
        top: 50%;
        left: 0;
        transform: translateY(-50%);
        padding: 0 58px;
        display: none;
        box-shadow: 0 -1px 0 0 var(--color-brand);
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            box-shadow: none;
        }
    
        @include bp(md-min) {
            font-size: #{'min(1.2vw, #{$font-size-base-lg})'};
            line-height: #{'min(1.6vw, #{$font-line-height-base-lg})'};
        }
    
        .newsletter.is-success & {
            display: block;
        }
    }
    
    .newsletter__vw-title {
        @include bp(md-min) {
            font-size: #{'min(3vw, #{$font-size-large-lg})'};
            line-height: #{'min(3.2vw, #{$font-line-height-large-lg})'};
            font-weight: $font-weight-normal;
        }
    }
    
    .newsletter__error-message {
        color: $color-error;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding-left: 8px;
    }
    
  • URL: /components/raw/newsletter/newsletter.scss
  • Filesystem Path: src/patterns/components/newsletter/newsletter.scss
  • Size: 3.6 KB
  • Content:
    import './newsletter.scss';
    import Component from '@component';
    import SubmitEvent = JQuery.SubmitEvent;
    import Ajax, { IAjaxPostParams } from '@ajax';
    
    interface INewsletterSettings {
        ajaxSuccessClass: string;
        ajaxFailClass: string;
        submitButtonClass: string;
        termsCheckboxClass: string;
        errorSpanClass: string;
        emailTextfieldClass: string;
    }
    
    interface INewsletterResponse {
        success: boolean,
        message: string,
        status: string,
        statusText: string,
    }
    
    export default class Newsletter extends Component {
        static initSelector: string = '.newsletter';
        settings: INewsletterSettings;
        termsCheckbox: JQuery;
        submitButton: JQuery;
        errorMessage: JQuery;
        emailField: JQuery;
    
        constructor(element: HTMLElement) {
            super(element);
    
            this.settings = {
                ajaxFailClass: 'is-fail',
                ajaxSuccessClass: 'is-success',
                emailTextfieldClass: 'newsletter__textfield',
                errorSpanClass: 'newsletter__error-message',
                submitButtonClass: 'newsletter__button',
                termsCheckboxClass: 'newsletter__check',
            };
    
            this.termsCheckbox = this.element.find('.' + this.settings.termsCheckboxClass + ' ' + 'input');
            this.submitButton = this.element.find('.' + this.settings.submitButtonClass);
            this.errorMessage = this.element.find('.' + this.settings.errorSpanClass);
            this.emailField = this.element.find('.' + this.settings.emailTextfieldClass + ' ' + '.textfield__input');
    
            this.init();
        }
    
        init(): void {
            this.element.on('submit', this.submitHandler.bind(this));
            if (this.termsCheckbox.length > 0) {
                this.termsCheckbox.on('change', this.termsHandler.bind(this));
                this.termsHandler();
            }
        }
    
        termsHandler(): void {
            this.submitButton.prop('disabled', !this.termsCheckbox.prop('checked'));
        }
    
        submitHandler(e: SubmitEvent): void {
            e.preventDefault();
            const email: string = typeof this.emailField.val() === 'string' ? this.emailField.val().toString() : '';
            const formData: IAjaxPostParams = {
                action: 'newsletter',
                email,
            };
    
            let agreed: boolean = true;
    
            if (this.termsCheckbox.length > 0) {
                agreed = this.termsCheckbox.prop('checked');
            }
    
            if (agreed) {
                Ajax.post(formData).then((response: INewsletterResponse) => {
                    if (response.success) {
                        this.element.addClass(this.settings.ajaxSuccessClass);
                        this.showError('');
                    } else {
                        this.showError(response.message);
                    }
                }).catch((response: INewsletterResponse): void => {
                    this.showError(response.status + ': ' + response.statusText);
                });
            }
        }
    
        showError(errorMessage: string): void {
            this.errorMessage.text(errorMessage);
        }
    }
    
  • URL: /components/raw/newsletter/newsletter.ts
  • Filesystem Path: src/patterns/components/newsletter/newsletter.ts
  • Size: 3 KB

Terms Checkmark

<form class="newsletter   ">
    <div class="newsletter__textfield-container">

        <div class="textfield textfield--label-hidden textfield--border-hidden newsletter__textfield">
            <div class="textfield__inner">
                <input class="textfield__input" type="text" id="text1" name="textfield" placeholder="Enter your email here">
                <label class="textfield__label text-button " for="text1">
                    newsletter
                </label>
            </div>
        </div>

        <button type="submit" class="button  newsletter__button ">

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

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

        <button type="submit" class="button button--icon newsletter__button newsletter__button--mobile ">
            <span class="button__pseudo-icon">
                <svg class="icon  button__icon">
                    <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#arrow-enter-bold"></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#arrow-enter-bold"></use>
                    </svg>

                </span>
            </span>
        </button>
    </div>
    <span class="newsletter__error-message"></span>
    <div class="newsletter__check-container">

        <div class="check newsletter__check">
            <input type="checkbox" id="check1" name="check" value="" class="check__input">
            <label for="check1" class="check__label">
                <span class="check__indicator">
                    <svg class="icon  check__icon">
                        <use xlink:href="../../inc/svg/global.49d3f64de1a3f5ccf16c763316702027.svg#checkbox-crossed-big"></use>
                    </svg>
                </span>
                <span class="check__text"><span>I agree with <a href="#" class="link">terms and conditions</a></span></span>
            </label>
        </div>
    </div>
</form>
<form class="newsletter {{ modifier }} {{ class }} {% if data.label %}newsletter--block{% endif %}">
    <div class="newsletter__textfield-container">
        {% if data.label %}
            <div class="newsletter__button-wrapper">
                {% if data.textfield %}
                    {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
                {% endif %}
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
            <div class="newsletter__button-wrapper">
                <div class="newsletter__label text-small">
                    {{ data.label }}
                    <span class="newsletter__error-message"></span>
                </div>
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
        {% else %}
            {% if data.static %}
                <input type="text" name="name" value="" class="newsletter__textfield-static">
            {% endif %}
            {% if data.textfield %}
                {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
            {% endif %}
            {% if data.button %}
                {% include '@button' with {class: 'newsletter__button', type: 'submit', data: data.button} %}
            {% endif %}
            {% if data.buttonMobile %}
                {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', type: 'submit', modifier: 'button--icon', data: data.buttonMobile} %}
            {% endif %}
        {% endif %}
    </div>
    {% if not data.label %}
        <span class="newsletter__error-message"></span>
    {% endif %}
    {% if data.check %}
        <div class="newsletter__check-container">
            {% include '@check' with {class: 'newsletter__check', data: data.check} %}
        </div>
    {% endif %}
    {% if data.thanks %}
        <div class="newsletter__success">
            {% if data.thanks.title %}
                <div class="text-large newsletter__vw-title">
                    {{ data.thanks.title }}
                </div>
            {% endif %}
            {{ data.thanks.message }}
        </div>
    {% endif %}
</form>
{
  "language": "en-US",
  "data": {
    "textfield": {
      "label": "newsletter",
      "id": "text1",
      "name": "textfield",
      "placeholder": "Enter your email here"
    },
    "button": {
      "text": "subscribe"
    },
    "buttonMobile": {
      "icon": "arrow-enter-bold"
    },
    "check": {
      "label": "<span>I agree with <a href=\"#\" class=\"link\">terms and conditions</a></span>",
      "id": "check1",
      "name": "check"
    }
  }
}
  • Content:
    .newsletter {
        position: relative;
    }
    
    .newsletter__textfield-container {
        display: flex;
        box-shadow: -1px 1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        .newsletter--block & {
            flex-direction: column-reverse;
            box-shadow: 0 1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: none;
                flex-wrap: nowrap;
            }
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            visibility: hidden;
        }
    }
    
    .newsletter__button-wrapper {
        display: flex;
    
        @include bp(sm-min) {
            width: 100%;
        }
    }
    
    .newsletter__label {
        flex-grow: 1;
        overflow: hidden;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: flex;
        align-items: center;
        opacity: .7;
        text-transform: uppercase;
        padding: 6px 16px 5px;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding: 0 0 0 32px;
            font-size: $font-size-button-lg;
            line-height: $font-line-height-button-lg;
            opacity: 1;
        }
    
        @include bp(md-min) {
            padding-left: 16px;
        }
    
        .newsletter--block & {
            box-shadow: 0 -1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: 0 -1px 0 0 var(--color-brand) inset;
            }
        }
    }
    
    .newsletter__check-container {
        display: flex;
        margin-top: 27px;
    
        @include bp(sm-min) {
            margin-top: 64px;
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            display: none;
        }
    }
    
    .newsletter__textfield {
        flex-grow: 1;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding-left: 17px;
        }
    
        @include bp(md-min) {
            padding-left: 0;
        }
    
        .newsletter--block & {
            box-shadow: none;
        }
    }
    
    .newsletter__textfield-static {
        width: 0;
        height: 0;
        border: 0;
        padding: 0;
        margin: 0;
    }
    
    .newsletter__button {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: none;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            display: block;
        }
    }
    
    .newsletter__button--mobile {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: block;
    
        .newsletter--block & {
            box-shadow: 1px 0 0 0 var(--color-brand) inset;
        }
    
        @include bp(sm-min) {
            display: none;
        }
    }
    
    .newsletter__success {
        position: absolute;
        top: 50%;
        left: 0;
        transform: translateY(-50%);
        padding: 0 58px;
        display: none;
        box-shadow: 0 -1px 0 0 var(--color-brand);
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            box-shadow: none;
        }
    
        @include bp(md-min) {
            font-size: #{'min(1.2vw, #{$font-size-base-lg})'};
            line-height: #{'min(1.6vw, #{$font-line-height-base-lg})'};
        }
    
        .newsletter.is-success & {
            display: block;
        }
    }
    
    .newsletter__vw-title {
        @include bp(md-min) {
            font-size: #{'min(3vw, #{$font-size-large-lg})'};
            line-height: #{'min(3.2vw, #{$font-line-height-large-lg})'};
            font-weight: $font-weight-normal;
        }
    }
    
    .newsletter__error-message {
        color: $color-error;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding-left: 8px;
    }
    
  • URL: /components/raw/newsletter/newsletter.scss
  • Filesystem Path: src/patterns/components/newsletter/newsletter.scss
  • Size: 3.6 KB
  • Content:
    import './newsletter.scss';
    import Component from '@component';
    import SubmitEvent = JQuery.SubmitEvent;
    import Ajax, { IAjaxPostParams } from '@ajax';
    
    interface INewsletterSettings {
        ajaxSuccessClass: string;
        ajaxFailClass: string;
        submitButtonClass: string;
        termsCheckboxClass: string;
        errorSpanClass: string;
        emailTextfieldClass: string;
    }
    
    interface INewsletterResponse {
        success: boolean,
        message: string,
        status: string,
        statusText: string,
    }
    
    export default class Newsletter extends Component {
        static initSelector: string = '.newsletter';
        settings: INewsletterSettings;
        termsCheckbox: JQuery;
        submitButton: JQuery;
        errorMessage: JQuery;
        emailField: JQuery;
    
        constructor(element: HTMLElement) {
            super(element);
    
            this.settings = {
                ajaxFailClass: 'is-fail',
                ajaxSuccessClass: 'is-success',
                emailTextfieldClass: 'newsletter__textfield',
                errorSpanClass: 'newsletter__error-message',
                submitButtonClass: 'newsletter__button',
                termsCheckboxClass: 'newsletter__check',
            };
    
            this.termsCheckbox = this.element.find('.' + this.settings.termsCheckboxClass + ' ' + 'input');
            this.submitButton = this.element.find('.' + this.settings.submitButtonClass);
            this.errorMessage = this.element.find('.' + this.settings.errorSpanClass);
            this.emailField = this.element.find('.' + this.settings.emailTextfieldClass + ' ' + '.textfield__input');
    
            this.init();
        }
    
        init(): void {
            this.element.on('submit', this.submitHandler.bind(this));
            if (this.termsCheckbox.length > 0) {
                this.termsCheckbox.on('change', this.termsHandler.bind(this));
                this.termsHandler();
            }
        }
    
        termsHandler(): void {
            this.submitButton.prop('disabled', !this.termsCheckbox.prop('checked'));
        }
    
        submitHandler(e: SubmitEvent): void {
            e.preventDefault();
            const email: string = typeof this.emailField.val() === 'string' ? this.emailField.val().toString() : '';
            const formData: IAjaxPostParams = {
                action: 'newsletter',
                email,
            };
    
            let agreed: boolean = true;
    
            if (this.termsCheckbox.length > 0) {
                agreed = this.termsCheckbox.prop('checked');
            }
    
            if (agreed) {
                Ajax.post(formData).then((response: INewsletterResponse) => {
                    if (response.success) {
                        this.element.addClass(this.settings.ajaxSuccessClass);
                        this.showError('');
                    } else {
                        this.showError(response.message);
                    }
                }).catch((response: INewsletterResponse): void => {
                    this.showError(response.status + ': ' + response.statusText);
                });
            }
        }
    
        showError(errorMessage: string): void {
            this.errorMessage.text(errorMessage);
        }
    }
    
  • URL: /components/raw/newsletter/newsletter.ts
  • Filesystem Path: src/patterns/components/newsletter/newsletter.ts
  • Size: 3 KB
  • Handle: @newsletter--terms-checkmark
  • Filesystem Path: src/patterns/components/newsletter/newsletter.twig
  • References (3): @textfield, @button, @check

Label

<form class="newsletter   newsletter--block">
    <div class="newsletter__textfield-container">
        <div class="newsletter__button-wrapper">

            <div class="textfield textfield--label-hidden textfield--border-hidden newsletter__textfield">
                <div class="textfield__inner">
                    <input class="textfield__input" type="text" id="text1" name="textfield" placeholder="Enter your email here">
                    <label class="textfield__label text-button " for="text1">
                        newsletter
                    </label>
                </div>
            </div>

            <button type="submit" class="button  newsletter__button newsletter__button--mobile ">

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

                    </span>
                </span>
            </button>
        </div>
        <div class="newsletter__button-wrapper">
            <div class="newsletter__label text-small">
                newsletter
                <span class="newsletter__error-message"></span>
            </div>

            <button type="submit" class="button  newsletter__button ">

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

                    </span>
                </span>
            </button>
        </div>
    </div>
    <div class="newsletter__success">
        <div class="text-large newsletter__vw-title">
            Thank you for signing up!
        </div>
        Your subscription has been confirmed. You've been added to our list and will hear back from us soon.
    </div>
</form>
<form class="newsletter {{ modifier }} {{ class }} {% if data.label %}newsletter--block{% endif %}">
    <div class="newsletter__textfield-container">
        {% if data.label %}
            <div class="newsletter__button-wrapper">
                {% if data.textfield %}
                    {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
                {% endif %}
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
            <div class="newsletter__button-wrapper">
                <div class="newsletter__label text-small">
                    {{ data.label }}
                    <span class="newsletter__error-message"></span>
                </div>
                {% if data.button %}
                    {% include '@button' with {class: 'newsletter__button', data: data.button, type: 'submit'} %}
                {% endif %}
            </div>
        {% else %}
            {% if data.static %}
                <input type="text" name="name" value="" class="newsletter__textfield-static">
            {% endif %}
            {% if data.textfield %}
                {% include '@textfield' with {class: 'newsletter__textfield', modifier: 'textfield--label-hidden textfield--border-hidden', data: data.textfield} %}
            {% endif %}
            {% if data.button %}
                {% include '@button' with {class: 'newsletter__button', type: 'submit', data: data.button} %}
            {% endif %}
            {% if data.buttonMobile %}
                {% include '@button' with {class: 'newsletter__button newsletter__button--mobile', type: 'submit', modifier: 'button--icon', data: data.buttonMobile} %}
            {% endif %}
        {% endif %}
    </div>
    {% if not data.label %}
        <span class="newsletter__error-message"></span>
    {% endif %}
    {% if data.check %}
        <div class="newsletter__check-container">
            {% include '@check' with {class: 'newsletter__check', data: data.check} %}
        </div>
    {% endif %}
    {% if data.thanks %}
        <div class="newsletter__success">
            {% if data.thanks.title %}
                <div class="text-large newsletter__vw-title">
                    {{ data.thanks.title }}
                </div>
            {% endif %}
            {{ data.thanks.message }}
        </div>
    {% endif %}
</form>
{
  "language": "en-US",
  "data": {
    "textfield": {
      "label": "newsletter",
      "id": "text1",
      "name": "textfield",
      "placeholder": "Enter your email here"
    },
    "button": {
      "text": "subscribe"
    },
    "buttonMobile": {
      "icon": "arrow-enter-bold"
    },
    "label": "newsletter",
    "thanks": {
      "title": "Thank you for signing up!",
      "message": "Your subscription has been confirmed. You've been added to our list and will hear back from us soon."
    }
  }
}
  • Content:
    .newsletter {
        position: relative;
    }
    
    .newsletter__textfield-container {
        display: flex;
        box-shadow: -1px 1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        .newsletter--block & {
            flex-direction: column-reverse;
            box-shadow: 0 1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: none;
                flex-wrap: nowrap;
            }
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            visibility: hidden;
        }
    }
    
    .newsletter__button-wrapper {
        display: flex;
    
        @include bp(sm-min) {
            width: 100%;
        }
    }
    
    .newsletter__label {
        flex-grow: 1;
        overflow: hidden;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: flex;
        align-items: center;
        opacity: .7;
        text-transform: uppercase;
        padding: 6px 16px 5px;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding: 0 0 0 32px;
            font-size: $font-size-button-lg;
            line-height: $font-line-height-button-lg;
            opacity: 1;
        }
    
        @include bp(md-min) {
            padding-left: 16px;
        }
    
        .newsletter--block & {
            box-shadow: 0 -1px 0 0 var(--color-brand) inset;
    
            @include bp(sm-min) {
                box-shadow: 0 -1px 0 0 var(--color-brand) inset;
            }
        }
    }
    
    .newsletter__check-container {
        display: flex;
        margin-top: 27px;
    
        @include bp(sm-min) {
            margin-top: 64px;
        }
    
        .newsletter.is-fail &,
        .newsletter.is-success & {
            display: none;
        }
    }
    
    .newsletter__textfield {
        flex-grow: 1;
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            padding-left: 17px;
        }
    
        @include bp(md-min) {
            padding-left: 0;
        }
    
        .newsletter--block & {
            box-shadow: none;
        }
    }
    
    .newsletter__textfield-static {
        width: 0;
        height: 0;
        border: 0;
        padding: 0;
        margin: 0;
    }
    
    .newsletter__button {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: none;
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            display: block;
        }
    }
    
    .newsletter__button--mobile {
        box-shadow: 1px -1px 0 0 var(--color-brand) inset;
        display: block;
    
        .newsletter--block & {
            box-shadow: 1px 0 0 0 var(--color-brand) inset;
        }
    
        @include bp(sm-min) {
            display: none;
        }
    }
    
    .newsletter__success {
        position: absolute;
        top: 50%;
        left: 0;
        transform: translateY(-50%);
        padding: 0 58px;
        display: none;
        box-shadow: 0 -1px 0 0 var(--color-brand);
        transition: $transition-duration $transition-easing;
        transition-property: box-shadow;
    
        @include bp(sm-min) {
            box-shadow: none;
        }
    
        @include bp(md-min) {
            font-size: #{'min(1.2vw, #{$font-size-base-lg})'};
            line-height: #{'min(1.6vw, #{$font-line-height-base-lg})'};
        }
    
        .newsletter.is-success & {
            display: block;
        }
    }
    
    .newsletter__vw-title {
        @include bp(md-min) {
            font-size: #{'min(3vw, #{$font-size-large-lg})'};
            line-height: #{'min(3.2vw, #{$font-line-height-large-lg})'};
            font-weight: $font-weight-normal;
        }
    }
    
    .newsletter__error-message {
        color: $color-error;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        padding-left: 8px;
    }
    
  • URL: /components/raw/newsletter/newsletter.scss
  • Filesystem Path: src/patterns/components/newsletter/newsletter.scss
  • Size: 3.6 KB
  • Content:
    import './newsletter.scss';
    import Component from '@component';
    import SubmitEvent = JQuery.SubmitEvent;
    import Ajax, { IAjaxPostParams } from '@ajax';
    
    interface INewsletterSettings {
        ajaxSuccessClass: string;
        ajaxFailClass: string;
        submitButtonClass: string;
        termsCheckboxClass: string;
        errorSpanClass: string;
        emailTextfieldClass: string;
    }
    
    interface INewsletterResponse {
        success: boolean,
        message: string,
        status: string,
        statusText: string,
    }
    
    export default class Newsletter extends Component {
        static initSelector: string = '.newsletter';
        settings: INewsletterSettings;
        termsCheckbox: JQuery;
        submitButton: JQuery;
        errorMessage: JQuery;
        emailField: JQuery;
    
        constructor(element: HTMLElement) {
            super(element);
    
            this.settings = {
                ajaxFailClass: 'is-fail',
                ajaxSuccessClass: 'is-success',
                emailTextfieldClass: 'newsletter__textfield',
                errorSpanClass: 'newsletter__error-message',
                submitButtonClass: 'newsletter__button',
                termsCheckboxClass: 'newsletter__check',
            };
    
            this.termsCheckbox = this.element.find('.' + this.settings.termsCheckboxClass + ' ' + 'input');
            this.submitButton = this.element.find('.' + this.settings.submitButtonClass);
            this.errorMessage = this.element.find('.' + this.settings.errorSpanClass);
            this.emailField = this.element.find('.' + this.settings.emailTextfieldClass + ' ' + '.textfield__input');
    
            this.init();
        }
    
        init(): void {
            this.element.on('submit', this.submitHandler.bind(this));
            if (this.termsCheckbox.length > 0) {
                this.termsCheckbox.on('change', this.termsHandler.bind(this));
                this.termsHandler();
            }
        }
    
        termsHandler(): void {
            this.submitButton.prop('disabled', !this.termsCheckbox.prop('checked'));
        }
    
        submitHandler(e: SubmitEvent): void {
            e.preventDefault();
            const email: string = typeof this.emailField.val() === 'string' ? this.emailField.val().toString() : '';
            const formData: IAjaxPostParams = {
                action: 'newsletter',
                email,
            };
    
            let agreed: boolean = true;
    
            if (this.termsCheckbox.length > 0) {
                agreed = this.termsCheckbox.prop('checked');
            }
    
            if (agreed) {
                Ajax.post(formData).then((response: INewsletterResponse) => {
                    if (response.success) {
                        this.element.addClass(this.settings.ajaxSuccessClass);
                        this.showError('');
                    } else {
                        this.showError(response.message);
                    }
                }).catch((response: INewsletterResponse): void => {
                    this.showError(response.status + ': ' + response.statusText);
                });
            }
        }
    
        showError(errorMessage: string): void {
            this.errorMessage.text(errorMessage);
        }
    }
    
  • URL: /components/raw/newsletter/newsletter.ts
  • Filesystem Path: src/patterns/components/newsletter/newsletter.ts
  • Size: 3 KB
  • Handle: @newsletter--label
  • Filesystem Path: src/patterns/components/newsletter/newsletter.twig
  • References (3): @textfield, @button, @check