<div class="text-field--light">
<div class="text-field__wrapper">
<input class="text-field__input" id="text" type="text" name="text" />
<label class="text-field__label" for="text">Text</label>
</div>
<div class="text-field__helper">Please note that this form field has a helper text</div>
<!-- NOTE: This div is reserved for field-specific error messages by a backend -->
<div class="text-field__error">Please provide a value for this field</div>
</div>
<div class="text-field--{{splitDashLast _self.name}}">
<div class="text-field__wrapper">
<input class="text-field__input" id="{{id}}" type="{{type}}" name="{{name}}" {{#if value}}value="{{value}}"{{/if}} {{#if disabled}}disabled{{/if}} {{#if required }}required="true"{{/if}} {{#if autocomplete}}autocomplete="{{autocomplete}}"{{/if}}/>
<label class="text-field__label" for="{{id}}">{{label}}</label>
</div>
{{#if helper}}
<div class="text-field__helper">{{helper}}</div>
{{/if}}
<!-- NOTE: This div is reserved for field-specific error messages by a backend -->
{{#if error}}
<div class="text-field__error">{{error}}</div>
{{else}}
<!--<div class="text-field__error">Put in the error message here...</div>-->
{{/if}}
</div>
{
"id": "text",
"name": "text",
"label": "Text",
"required": false,
"value": "",
"disabled": false,
"type": "text",
"autocomplete": "",
"error": "Please provide a value for this field",
"helper": "Please note that this form field has a helper text"
}
import './text-field-material-like.scss';
export * from './text-field-material-like';
import FormComponent from '../../form-component';
export class TextField extends FormComponent {
constructor(context, options) {
super(
context,
context.querySelector('.text-field__input'),
context.querySelector('.text-field__error'),
'Text Field',
options
);
super.init();
this.initEvents();
}
initEvents() {
if (this.field.type === 'date' || this.field.type === 'time') {
this.setIsFilledIn(true);
} else {
this.field.addEventListener('focus', () => this.setIsFilledIn(true));
this.field.addEventListener('blur', () => this.setIsFilledIn());
this.field.addEventListener('input', () => {
// Don't just call setIsFilledIn() for the case where you've removed
// the text field value but are still focusing the text field
this.setIsFilledIn(
this.field.value || this.field === document.activeElement
);
});
}
}
}
export const selector = '[class^="text-field--"]';
@import "~shared/base";
/*******************************************************************************
* Contextual classes:
* - is-disabled: When input is disabled
* - is-filled-in: When value is available or the user clicked into the input
* - is-tabbed: When the input is focused by tabbing (a11y)
* - is-focused: When the input is focused
* - is-initialized: When the JS for the component is initialized
* - has-no-label: If there is no label available
******************************************************************************/
// size settings
$textFieldHeight: 2.375rem; // 38px + 12px == 50px height
$textFieldPaddingX: 0;
// font settings
$textFieldLabelFontSize: 1.125rem;
$textFieldLabelFilledInFontSize: 0.75rem;
$textFieldLabelFontFamily: inherit;
$textFieldFontSize: 1.125rem;
$textFieldFontFamily: inherit;
$textFieldErrorFontSize: 1rem;
$textFieldHelperFontSize: 1rem;
// Don't use the same line height as "height" to avoid a large cursor
// in Safari on macOS. Also multiply the font size with 1.35 and use it
// as line height to avoid text jump in FF when you mark the text
$textFieldLineHeight: $textFieldFontSize * 1.35;
$textFieldPadding: ($textFieldHeight - $textFieldLineHeight) / 2;
// need to use string here due to:
// https://github.com/webpack-contrib/sass-loader/issues/487
$variants: "dark", "light";
@each $color in $variants {
@if $color == "light" {
// color settings
$textFieldBorderColor: $black !global;
$textFieldBorderActiveColor: $black !global;
$textFieldBorderInvalidColor: $red !global;
$textFieldBorderInvalidActiveColor: $red !global;
$textFieldBackgroundColor: transparent !global;
$textFieldBackgroundActiveColor: transparent !global;
$textFieldBackgroundInvalidColor: transparent !global;
$textFieldBackgroundInvalidActiveColor: transparent !global;
$textFieldColor: $black !global;
$textFieldActiveColor: $black !global;
$textFieldInvalidColor: $black !global;
$textFieldInvalidActiveColor: $black !global;
$textFieldLabelColor: $black !global;
$textFieldLabelFilledInColor: $textFieldLabelColor !global;
$textFieldLabelFilledInActiveColor: $textFieldLabelColor !global;
$textFieldLabelInvalidColor: $red !global;
$textFieldLabelInvalidFilledInColor: $textFieldLabelInvalidColor !global;
$textFieldLabelInvalidFilledInActiveColor: $textFieldLabelInvalidColor !global;
$textFieldErrorColor: $red !global;
$textFieldHelperColor: $black !global;
$textFieldHelperInvalidColor: $black !global;
$textFieldBorderTabbedColor: #95a5a6 !global;
} @else {
// color settings
$textFieldBorderColor: $white !global;
$textFieldBorderActiveColor: $white !global;
$textFieldBorderInvalidColor: $red !global;
$textFieldBorderInvalidActiveColor: $red !global;
$textFieldBackgroundColor: transparent !global;
$textFieldBackgroundActiveColor: transparent !global;
$textFieldBackgroundInvalidColor: transparent !global;
$textFieldBackgroundInvalidActiveColor: transparent !global;
$textFieldColor: $white !global;
$textFieldActiveColor: $white !global;
$textFieldInvalidColor: $white !global;
$textFieldInvalidActiveColor: $white !global;
$textFieldLabelColor: $white !global;
$textFieldLabelFilledInColor: $textFieldLabelColor !global;
$textFieldLabelFilledInActiveColor: $textFieldLabelColor !global;
$textFieldLabelInvalidColor: $red !global;
$textFieldLabelInvalidFilledInColor: $textFieldLabelInvalidColor !global;
$textFieldLabelInvalidFilledInActiveColor: $textFieldLabelInvalidColor !global;
$textFieldErrorColor: $red !global;
$textFieldHelperColor: $white !global;
$textFieldHelperInvalidColor: $white !global;
$textFieldBorderTabbedColor: #95a5a6 !global;
}
/*****************************************************************************
* General
****************************************************************************/
.text-field {
$block: &;
height: $textFieldHeight;
&--#{unquote($color)} {
&.is-tabbed {
outline: 1px solid $textFieldBorderTabbedColor;
outline-offset: 3px;
}
#{$block}__wrapper {
position: relative;
padding-top: $textFieldLabelFilledInFontSize;
width: 100%;
}
/*************************************************************************
* Input
************************************************************************/
#{$block}__input {
&,
&:invalid,
&:required {
border-width: 0 0 1px 0;
border-style: solid;
border-color: transparent transparent $textFieldBorderColor transparent;
cursor: text;
display: block;
height: $textFieldHeight;
line-height: $textFieldLineHeight;
// add 1 px additional padding to avoid text jumping when
// border-bottom-width is set to 2px when focused
padding: $textFieldPadding $textFieldPaddingX calc(#{$textFieldPadding} + 1px) $textFieldPaddingX;
background: $textFieldBackgroundColor;
color: $textFieldColor;
box-sizing: border-box;
width: 100%;
font-size: $textFieldFontSize;
font-family: $textFieldFontFamily;
border-radius: 0; // iOS default removal
box-shadow: none; // red border removal in case it's invalid/required
}
// use a "bug" of Chrome to overwrite autofill styling
// https://stackoverflow.com/a/37432260/3894981
// !important is necessary as it won't work otherwise
@-webkit-keyframes autofill {
to {
color: $textFieldColor !important;
background-color: $textFieldBackgroundColor;
}
}
&:-webkit-autofill {
-webkit-animation-name: autofill;
-webkit-animation-fill-mode: both;
}
// Active
&:focus,
&:invalid:focus,
&:required:focus {
border-bottom-width: 2px;
border-color: transparent transparent $textFieldBorderActiveColor transparent;
padding: $textFieldPadding $textFieldPaddingX;
color: $textFieldActiveColor;
background: $textFieldBackgroundActiveColor;
outline: none;
}
}
// Disabled
&.is-disabled #{$block}__input {
cursor: not-allowed;
}
// Invalid
&.is-invalid #{$block}__input {
border-color: transparent transparent $textFieldBorderInvalidColor transparent;
color: $textFieldInvalidColor;
background: $textFieldBackgroundInvalidColor;
// Invalid & Active
&:focus,
&:invalid:focus,
&:required:focus {
border-color: transparent transparent $textFieldBorderInvalidActiveColor transparent;
color: $textFieldInvalidActiveColor;
background: $textFieldBackgroundInvalidActiveColor;
}
}
/*************************************************************************
* Label (will be moved to top when value available)
************************************************************************/
#{$block}__label {
position: absolute;
top: $textFieldLabelFilledInFontSize;
left: 0;
height: $textFieldHeight;
line-height: $textFieldHeight;
width: 100%;
box-sizing: border-box;
cursor: text;
// a border and padding is necessary to have the same line height like
// input
border-bottom: 1px solid transparent;
padding: 0 $textFieldPaddingX 1px $textFieldPaddingX;
font-size: $textFieldLabelFontSize;
font-family: $textFieldLabelFontFamily;
color: $textFieldLabelColor;
user-select: none;
background-color: transparent;
transform: translateY(0);
@include transition("all .275s");
@media screen and (-ms-high-contrast: active) {
border: none;
}
}
// Disabled
&.is-disabled #{$block}__label {
cursor: not-allowed;
user-select: none;
}
// Filled in
// NOTE: We need to use two selectors here, as otherwise it won't work in
// Firefox. Mixins aren't allowed inside @each directives, so we can only
// use redundant code in these two selectors
// NOTE: Also trigger this style when the text field isn't initialized yet
// to avoid label jumping when forms with filled-in values are loaded
// via AJAX
&.is-filled-in #{$block}__label,
&:not(.is-initialized) #{$block}__label {
transform: translateY(-#{$textFieldLabelFilledInFontSize});
height: $textFieldLabelFilledInFontSize;
font-size: $textFieldLabelFilledInFontSize;
color: $textFieldLabelFilledInColor;
line-height: $textFieldLabelFilledInFontSize;
}
#{$block}__input:-webkit-autofill + #{$block}__label {
// webkit autofill is used to remove the delay between Chrome, which
// fills in predefined data, and JS that's being loaded
transform: translateY(-#{$textFieldLabelFilledInFontSize});
height: $textFieldLabelFilledInFontSize;
font-size: $textFieldLabelFilledInFontSize;
color: $textFieldLabelFilledInColor;
line-height: $textFieldLabelFilledInFontSize;
}
// Filled in & Active
&.is-filled-in.is-focused #{$block}__label,
&.is-filled-in.is-focused:not(.is-initialized) #{$block}__label {
color: $textFieldLabelFilledInActiveColor;
}
&.is-filled-in.is-focused #{$block}__input:-webkit-autofill + #{$block}__label {
color: $textFieldLabelFilledInActiveColor;
}
// Invalid
&.is-invalid #{$block}__label,
&.is-invalid:not(.is-initialized) #{$block}__label {
color: $textFieldLabelInvalidColor;
}
&.is-invalid #{$block}__input:-webkit-autofill + #{$block}__label {
color: $textFieldLabelInvalidColor;
}
// Invalid & Filled In
&.is-invalid.is-filled-in #{$block}__label,
&.is-invalid.is-filled-in:not(.is-initialized) #{$block}__label {
color: $textFieldLabelInvalidFilledInColor;
}
&.is-invalid.is-filled-in #{$block}__input:-webkit-autofill + #{$block}__label {
color: $textFieldLabelInvalidFilledInColor;
}
// Invalid & Filled in & Active
&.is-invalid.is-filled-in.is-focused #{$block}__label,
&.is-invalid.is-filled-in.is-focused:not(.is-initialized) #{$block}__label {
color: $textFieldLabelInvalidFilledInActiveColor;
}
&.is-invalid.is-filled-in.is-focused #{$block}__input:-webkit-autofill + #{$block}__label {
color: $textFieldLabelInvalidFilledInActiveColor;
}
/*************************************************************************
* Error
************************************************************************/
#{$block}__error {
font-size: $textFieldErrorFontSize;
color: $textFieldErrorColor;
margin: 5px $textFieldPaddingX;
a {
color: $textFieldErrorColor;
}
}
/*************************************************************************
* Helper
************************************************************************/
#{$block}__helper {
font-size: $textFieldHelperFontSize;
color: $textFieldHelperColor;
margin: 5px $textFieldPaddingX;
}
&.is-invalid #{$block}__helper {
color: $textFieldHelperInvalidColor;
}
}
}
}
No notes defined.