{% macro onsInput(params) %}
    {% from "components/mutually-exclusive/_macro.njk" import onsMutuallyExclusive %}
    {% from "components/char-check-limit/_macro.njk" import onsCharLimit %}
    {% from "components/field/_macro.njk" import onsField %}
    {% from "components/label/_macro.njk" import onsLabel %}
    {% from "components/button/_macro.njk" import onsButton %}

    {% if params.type == "number" %}
        {# Type must be "text" or Firefox and Safari will set a blank value to the server if non numeric characters are entered -
        they don’t block non numeric characters: https://bugzilla.mozilla.org/show_bug.cgi?id=1398528 #}
        {% set type = "text" %}
        {% set pattern = "[0-9]*" %}
        {% set inputmode = "numeric" %}
    {% elif params.type %}
        {% set type = params.type %}
    {% elif params.searchButton %}
        {% set type = "search" %}
    {% else %}
        {% set type = "text" %}
    {% endif %}
    {% set exclusiveClass = " ons-js-exclusive-group-item" if params.mutuallyExclusive %}
    {% set inputPlaceholder = " ons-input--placeholder" if params.accessiblePlaceholder %}

    {% set input %}
        <input
            type="{{ type }}"
            id="{{ params.id }}"
            class="ons-input ons-input--text ons-input-type__input{{ ' ons-input--error' if params.error }}{{ ' ons-search__input' if params.searchButton }}{{ ' ons-input--header-search' if params.searchButton.variant == 'header' }}{{ ' ' + params.classes if params.classes else '' }}{% if params.width %}{{ ' ' }}ons-input{% if params.type == 'number' or params.type == 'tel' %}-number{% endif %}--w-{{ params.width }}{% endif %}{{ exclusiveClass }}{{ inputPlaceholder }}"
            {% if params.prefix and params.prefix.id and not params.prefix.title %}aria-labelledby="{{ params.prefix.id }}"{% elif params.suffix and params.suffix.id and not params.suffix.title %}aria-labelledby="{{ params.suffix.id }}"{% endif %}
            {% if params.prefix and params.prefix.id %}
                aria-labelledby="{{ params.id }} {{ params.prefix.id }}"
            {% elif params.suffix and params.suffix.id %}
                aria-labelledby="{{ params.id }} {{ params.suffix.id }}"
            {% endif %}
            {% if params.name %}name="{{ params.name }}"{% endif %}
            {% if params.value %}value="{{ params.value }}"{% endif %}
            {% if params.accept %}accept="{{ params.accept }}"{% endif %}
            {% if params.min %}min="{{ params.min }}"{% endif %}
            {% if params.max %}max="{{ params.max }}"{% endif %}
            {% if params.minLength %}minlength="{{ params.minLength }}"{% endif %}
            {% if params.maxLength %}maxlength="{{ params.maxLength }}"{% endif %}
            {% if pattern %}pattern="{{ pattern }}"{% endif %}
            {% if inputmode %}inputmode="{{ inputmode }}"{% endif %}
            {% if params.autocomplete %}autocomplete="{{ params.autocomplete }}"{% endif %}
            {% if params.accessiblePlaceholder %}placeholder="{{ params.label.text }}"{% endif %}
            {% if params.charCheckLimit %}
                data-message-check-ref="{{ params.id }}-check" data-message-check-num="{{ params.charCheckLimit.limit }}"
                aria-describedby="{{ params.id }}-check"
            {% endif %}
            {% if params.attributes %}{% for attribute, value in (params.attributes.items() if params.attributes is mapping and params.attributes.items else params.attributes) %}{{ ' ' }}{{ attribute }}{% if value %}="{{ value }}"{% endif %}{% endfor %}{% endif %}
            {% if params.label and params.label.description %}{% if params.label.id %}aria-describedby="{{ params.label.id }}-description-hint"{% else %}aria-describedby="description-hint"{% endif %}{% endif %}
        />
        {% if params.listeners %}
            <!-- prettier-ignore-start -->
            <script {% if csp_nonce %}nonce="{{ csp_nonce() }}"{% endif %}>
                {% for listener, value in (params.listeners.items() if params.listeners is mapping and params.listeners.items else params.listeners) %}
                    document.getElementById("{{ params.id }}").addEventListener('{{ listener }}', function(){ {{ value }} });
                {% endfor %}
            </script>
            <!-- prettier-ignore-end -->
        {% endif %}
        {% if params.postTextboxLinkText %}
            <a class="ons-u-fs-s ons-input__post-link" href="{{ params.postTextboxLinkUrl }}">{{ params.postTextboxLinkText }}</a>
        {% endif %}
    {% endset %}

    {% set field %}
        {% if (not params.accessiblePlaceholder or params.label.description) and (params.label and params.label.text) %}
            {{
                onsLabel({
                    "for": params.id,
                    "id": params.label.id,
                    "text": params.label.text,
                    "classes": params.label.classes,
                    "description": params.label.description,
                    "attributes": params.label.attributes,
                    "accessiblePlaceholder": params.accessiblePlaceholder,
                    "inline": params.label.inline
                })
            }}
        {% endif %}

        {% if params.prefix or params.suffix %}
            {% if (params.prefix and params.prefix.id) or (params.suffix and params.suffix.id) %}
                <span
                    class="ons-input-type{{ ' ons-input-type--prefix' if params.prefix }}{{ ' ons-js-input-container-abbr' if params.prefix or params.suffix }}"
                >
                    <span class="ons-input-type__inner">
                        {{ input | safe }}
                        {% set abbr = params.prefix or params.suffix %}
                        {% if params.prefix.title or params.suffix.title %}
                            {% set tag = '<abbr' %}
                            {% set endTag = '</abbr>' %}
                        {% else %}
                            {% set tag = '<span' %}
                            {% set endTag = '</span>' %}
                        {% endif %}

                        {{ tag | safe }}
                        id="{{ abbr.id }}" class="ons-input-type__type ons-js-input-abbr"
                        {% if params.prefix or params.suffix %}
                            aria-label="{{ abbr.title }}" role="figure"
                        {% endif %}
                        {% if abbr.title %}title="{{ abbr.title }}"{% endif %}
                        >{{- abbr.text -}}
                        {{ endTag | safe }}
                    </span>
                </span>
            {% endif %}
        {% elif params.searchButton %}
            <span
                class="ons-grid-flex ons-grid-flex--vertical-top ons-input_search-button{{ ' ons-input__button--header-search' if params.searchButton.variant == 'header' }}{{ ' ons-input--with-text-description' if params.label.description }}"
            >
                {% if params.accessiblePlaceholder %}
                    {{
                        onsLabel({
                            "for": params.id,
                            "id": params.label.id,
                            "text": params.label.text,
                            "classes": params.label.classes,
                            "attributes": params.label.attributes,
                            "accessiblePlaceholder": params.accessiblePlaceholder,
                            "inline": params.label.inline
                        })
                    }}
                {% endif %}

                {{ input | safe }}

                {%- set buttonLabel -%}
                    {%- if params.searchButton.visuallyHideButtonText == true -%}
                        <span class="ons-u-vh">{{ params.searchButton.text }}</span>
                    {%- else -%}
                        {{ params.searchButton.text }}
                    {%- endif -%}
                {%- endset -%}

                {{
                    onsButton({
                        "type": params.searchButton.type,
                        "html": buttonLabel,
                        "text": params.searchButton.text,
                        "id": params.searchButton.id,
                        "variants": 'header-search' if params.searchButton.variant == 'header' else 'small',
                        "classes": 'ons-search__btn' + (" " + params.searchButton.classes if params.searchButton.classes else ""),
                        "attributes": params.searchButton.attributes,
                        "iconType": params.searchButton.iconType,
                        "iconPosition": 'only' if params.searchButton.visuallyHideButtonText == true else 'before'
                    })
                }}
            </span>
        {% else %}
            {% if params.accessiblePlaceholder %}
                <span class="ons-grid-flex{{ ' ons-input--with-text-description' if params.label.description }}">
                    {{
                        onsLabel({
                            "for": params.id,
                            "id": params.label.id,
                            "text": params.label.text,
                            "classes": params.label.classes,
                            "attributes": params.label.attributes,
                            "accessiblePlaceholder": params.accessiblePlaceholder,
                            "inline": params.label.inline
                        })
                    }}
                    {{ input | safe }}
                </span>
            {% else %}
                {{ input | safe }}
            {% endif %}
        {% endif %}
    {% endset %}

    {% if params.charCheckLimit and params.charCheckLimit.limit %}
        {% set charCheckField %}
            {%
                call onsCharLimit({
                    "id": params.id ~ "-check",
                    "limit": params.charCheckLimit.limit,
                    "variant": "check",
                    "charCountSingular": params.charCheckLimit.charCountSingular,
                    "charCountPlural": params.charCheckLimit.charCountPlural,
                    "charCountOverLimitSingular": params.charCheckLimit.charCountOverLimitSingular,
                    "charCountOverLimitPlural": params.charCheckLimit.charCountOverLimitPlural
                })
            %}
                {{ field | safe }}
            {% endcall %}
        {% endset %}
    {% endif %}

    {% if params.mutuallyExclusive %}
        {%
            call onsMutuallyExclusive({
                "id": params.fieldId,
                "legend": params.legend,
                "legendClasses": params.legendClasses ~ " ons-js-input-legend",
                "description": params.description,
                "dontWrap": params.dontWrap,
                "legendIsQuestionTitle": params.legendIsQuestionTitle,
                "exclusiveOptions": params.mutuallyExclusive.exclusiveOptions,
                "or": params.mutuallyExclusive.or,
                "deselectMessage": params.mutuallyExclusive.deselectMessage,
                "deselectGroupAdjective": params.mutuallyExclusive.deselectGroupAdjective,
                "deselectExclusiveOptionAdjective": params.mutuallyExclusive.deselectExclusiveOptionAdjective,
                "error": params.error,
                "autosuggestResults": params.autosuggestResults
            })
        %}
            {% if charCheckField %}
                {{ charCheckField | safe }}
            {% else %}
                {{ field | safe }}
            {% endif %}
        {% endcall %}
    {% elif type == "hidden" %}
        {{ field | safe }}
    {% else %}
        {%
            call onsField({
                "id": params.fieldId,
                "classes": params.fieldClasses,
                "dontWrap": params.dontWrap,
                "error": params.error,
                "inline": params.label.inline if params.label
            })
        %}
            {% if charCheckField %}
                {{ charCheckField | safe }}
            {% else %}
                {{ field | safe }}
            {% endif %}
        {% endcall %}
    {% endif %}
{% endmacro %}
