Pageworks / papertrain

Papertrain: a Craft CMS 3 framework
http://download.papertrain.io
MIT License
5 stars 2 forks source link

Forms Update #96

Closed codewithkyle closed 5 years ago

codewithkyle commented 5 years ago

The forms SCSS need to be able to easily handle custom colours (non-primary/secondary background colours).

Forms should also do the following:

codewithkyle commented 5 years ago

Updated SCSS for adjustable margins.

/form-styles/_base.scss

.o-input{
    &.has-helper{
        margin-bottom: $unit;
    }
    &.is-invalid{
        margin-bottom: $unit;

        ...snip...
    }
}

_form.scss

.o-input{
    transition: all 150ms $ease;
}
codewithkyle commented 5 years ago

In the _base.scss form style add the following:

.o-input{
    margin-bottom: $unit;

    &.has-helper{
        margin-bottom: $unit*2;
    }

    &.is-invalid{
        margin-bottom: $unit*2;

        input{
            & + label{
                color: $error;
                font-size: 12px;
                bottom: 34px;
            }
        }
    }
}

Updated form macro

{# Basic Form Input #}
{% macro input(label, name, required = true, type = 'text', help, icon, pattern, autocomplete) %}
    <div class="js-input o-input {% if help != '' %}has-helper{% endif %}">
        <input {% if icon %}class="has-icon"{% endif %} type="{{type}}" {% if type == 'email' %}inputmode="email"{% elseif type == 'tel' %}inputmode="tel"{% endif %} {% if pattern != '' %}pattern="{{pattern}}"{% elseif type == 'email' %}pattern=".+@.+\..+"{% endif %} {% if autocomplete %}autocomplete="{{autocomplete}}"{% endif %} name="{{name}}" id="{{name}}" {% if required %}required{% endif %} />
        <label>{{label}}</label>
        {% if icon %}<i class="o-icon {{icon}}"></i>{% endif %}
        <div class="o-error">
            <i class="far fa-exclamation-circle"></i>
            <span class="js-error o-error_message">Something went wrong.</span>
        </div>
        {% if help %}
            <div class="o-help">
                <span class="o-help_message">{{help}}</span>
            </div>
        {% endif %}
    </div>
{% endmacro %}

{# Number Form Input #}
{% macro number(label, name, required = true, help, icon, min = 0, max, step) %}
    <div class="js-input o-input {% if help != '' %}has-helper{% endif %}">
        <input {% if icon %}class="has-icon"{% endif %} type="number" min="{{min}}" inputmode="numeric" {% if max %}max="{{max}}"{% endif %} {% if step %}step="{{step}}"{% endif %} name="{{name}}" id="{{name}}" {% if required %}required{% endif %} />
        <label>{{label}}</label>
        {% if icon %}<i class="o-icon {{icon}}"></i>{% endif %}
        <div class="o-error">
            <i class="far fa-exclamation-circle"></i>
            <span class="js-error o-error_message">Something went wrong.</span>
        </div>
        {% if help %}
            <div class="o-help">
                <span class="o-help_message">{{help}}</span>
            </div>
        {% endif %}
    </div>
{% endmacro %}

{# Password Form Input #}
{% macro password(label, name, width = 'u-1/1', help, required = true, margin = 'u-margin-bottom', pattern) %}
    <div class="o-layout_item {{width}} {{margin}}">
        <div class="js-input o-input has-content-hidden has-helper">
            <input type="password" pattern="{% if not pattern %}^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}${% else %}{{pattern}}{% endif %}" name="{{name}}" id="{{name}}" {% if required %}required{% endif %} />
            <label>{{label}}</label>
            <span class="js-password-toggle -hidden">
                <i class="fas fa-eye"></i>
            </span>
            <span class="js-password-toggle -visible">
                <i class="fas fa-eye-slash"></i>
            </span>
            <div class="o-error">
                <i class="far fa-exclamation-circle"></i>
                <span class="o-error_message">Must be at least 8 characters with a mix of letters and numbers.</span>
            </div>
            <div class="o-help">
                <span class="o-help_message">
                    {% if help == null %}
                        Must be at least 8 characters with a mix of letters and numbers.
                    {% else %}
                        {{help}}
                    {% endif %}
                </span>
            </div>
        </div>
    </div>
{% endmacro %}

{# Pin Form Input #}
{% macro pin(label, name, width = 'u-1/1', required = true, help,  min = 4, max = 8, pattern = '^[0-9]*', margin = 'u-margin-bottom') %}
    <div class="o-layout_item {{width}} {{margin}}">
        <div class="js-input o-input has-content-hidden has-helper">
            <input type="password" inputmode="numeric" minlength="{{min}}" maxlength="{{max}}" pattern="{{pattern}}" name="{{name}}" id="{{name}}" {% if required %}required{% endif %} />
            <label>{{label}}</label>
            <span class="js-password-toggle -hidden">
                <i class="fas fa-eye"></i>
            </span>
            <span class="js-password-toggle -visible">
                <i class="fas fa-eye-slash"></i>
            </span>
            <div class="o-error">
                <i class="far fa-exclamation-circle"></i>
                <span class="o-error_message">Pin must be a minimum of 4 digits.</span>
            </div>
            <div class="o-help">
                <span class="o-help_message">
                    {% if help == null %}
                        Pin must be 4 to 8 digits.
                    {% else %}
                        {{help}}
                    {% endif %}
                </span>
            </div>
        </div>
    </div>
{% endmacro %}

{# Select Form Input #}
{% macro select(label, name, required = false, help, options) %}
    <div class="js-input o-input {% if help != '' %}has-helper{% endif %}">
        <select id="{{name}}" name="{{name}}" >
            {% if not required %}<option value="any">&nbsp;</option>{% endif %}
            {% for option in options %}
                <option value="{{option.value}}">{{option.label}}</option>
            {% endfor %}
        </select>
        <label>{{label}}</label>
        <i class="o-arrow fas fa-sort-down"></i>
        {% if help %}
            <div class="o-help">
                <span class="o-help_message">{{help}}</span>
            </div>
        {% endif %}
    </div>
{% endmacro %}

{# Textarea Input #}
{% macro textarea(label, name, required = true, help) %}
    <div class="js-input o-textarea {% if help != '' %}has-helper{% endif %}">
        <textarea id="{{name}}" name="{{name}}" {% if required %}required{% endif %}></textarea>
        <label>{{label}}</label>
        <div class="o-error">
            <i class="far fa-exclamation-circle"></i>
            <span class="js-error o-error_message">Something went wrong.</span>
        </div>
        {% if help %}
            <div class="o-help">
                <span class="o-help_message">{{help}}</span>
            </div>
        {% endif %}
    </div>
{% endmacro %}

{# Radio Button Form Input #}
{% macro radio(label, name, options) %}
    <fieldset class="js-input o-radio">
        {% for option in options %}
            <div class="o-radio_item">
                <input type="radio" id="{{option.value}}" name="{{name}}" value="{{option.value}}" />
                <label for="{{option.value}}">
                    <div class="o-radio_icon">
                        <div class="o-radio_outter"></div>
                        <div class="o-radio_inner"></div>
                    </div>
                    <span>{{option.title}}</span>
                </label>
            </div>
        {% endfor %}
        <label>{{label}}</label>
    </fieldset>
{% endmacro %}

{# Checkbox Form Input #}
{% macro checkbox(label, name, options) %}
    <fieldset class="js-input o-checkbox">
        {% for option in options %}
            <div class="o-checkbox_item">
                <input type="checkbox" id="{{option.value}}" name="{{name}}" value="{{option.value}}" />
                <label for="{{option.value}}">
                    <div class="o-checkbox_icon">
                        <div class="o-checkbox_box"></div>
                        <svg class="o-checkbox_check" viewbox="0 0 24 24">
                            <path fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59"></path>
                        </svg>
                    </div>
                    <span>{{option.title}}</span>
                </label>
            </div>
        {% endfor %}
        <label>{{label}}</label>
    </fieldset>
{% endmacro %}

{# Date Form Input #}
{% macro date(label, name, required = true, help, startDate, minDate, maxDate, icon = 'far fa-calendar-alt') %}
    <div class="js-input o-input {% if help != '' %}has-helper{% endif %}">
        <input {% if icon %}class="has-icon"{% endif %} type="date" name="{{name}}" id="{{name}}" {% if required %}required{% endif %} value="{% if startDate %}{{startDate}}{% else %}{{now|date('Y-m-d')}}{% endif %}" {% if minDate %}min="{{minDate}}"{% endif %} {% if maxDate %}max="{{maxDate}}"{% endif %} pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" />
        <label>{{label}}</label>
        {% if icon %}<i class="o-icon {{icon}}"></i>{% endif %}
        <div class="o-error">
            <i class="far fa-exclamation-circle"></i>
            <span class="js-error o-error_message">Something went wrong.</span>
        </div>
        {% if help %}
            <div class="o-help">
                <span class="o-help_message">{{help}}</span>
            </div>
        {% endif %}
    </div>
{% endmacro %}

{# Switch Form Input #}
{% macro switch(label, name, checked = true) %}
    <div class="js-input o-switch">
        <div class="o-switch_item">
            <input type="checkbox" id="id-{{name}}" name="{{name}}" value="{{name}}" {% if checked %}checked{% endif %} />
            <label for="id-{{name}}">
                <span>{{label}}</span>
                <div class="o-switch_icon">
                    <div class="o-switch_track"></div>
                    <div class="o-switch_handle">
                        <div class="o-switch_circle"></div>
                    </div>
                </div>
            </label>
        </div>
    </div>
{% endmacro %}
codewithkyle commented 5 years ago

Updated error and helper objects for objects_form.scss

// Text objects
.o-error,
.o-help{
    padding: $unit-small;
    @include position(absolute, 100% null null 0);
    width: 100%;
    color: $helper-dark;
    font-size: 12px;

    section.-dark-background & {
        color: $helper-light;
    }

    svg{
        margin-right: $unit-small;
    }
}

// Error object
.o-error{
    color: $error !important;
    opacity: 0;
    transform: translateY(5px);
    transition: transform 125ms $ease-sharp, opacity 25ms 100ms $ease-out;
}

// Helper object
.o-help{
    opacity: 1;
    transition: opacity 150ms 75ms $ease-sharp;
}
codewithkyle commented 5 years ago

We should look into disabling hidden form inputs so auto-fills won't touch them and so users can't tab to them.

codewithkyle commented 5 years ago

The final thing we should add before this issue can be closed is to add the ability to define custom margin-bottom values instead of always using $unit and $unit*2. This new variable should live in the base forms file