This commit is contained in:
Lea Verou
2024-12-17 02:03:06 -05:00
8 changed files with 158 additions and 99 deletions

View File

@@ -157,7 +157,7 @@ Use [CSS parts](#css-parts) to customize the way form controls are drawn. This e
text-align: right;
}
.label-on-left::part(form-control-hint) {
.label-on-left::part(hint) {
grid-column-start: 2;
}
</style>

View File

@@ -22,9 +22,9 @@ The styles shown below can be all yours by adding Web Awesome's applied styleshe
<wa-button>WA Button</wa-button>
<label for="input-text">Input (text)</label>
<input type="text" id="input-text"></input>
<input type="text" id="input-text" placeholder="placeholder"></input>
<wa-input label="WA Input (text)" type="text"></wa-input>
<wa-input label="WA Input (text)" type="text" placeholder="placeholder"></wa-input>
<label for="input-number">Input (number)</label>
<input type="number" id="input-number"></input>
@@ -32,9 +32,34 @@ The styles shown below can be all yours by adding Web Awesome's applied styleshe
<wa-input label="WA Input (number)" type="number"></wa-input>
<label for="input-password">Input (password)</label>
<input type="password" id="input-password"></input>
<input type="password" id="input-password" required></input>
<wa-input label="WA Input (password)" type="password"></wa-input>
<wa-input label="WA Input (password)" type="password" required></wa-input>
<label for="input-datetime-local">Input (datetime-local)</label>
<input type="datetime-local" id="input-datetime-local"></input>
<wa-input label="WA Input (datetime-local)" type="datetime-local"></wa-input>
<label for="input-email">Input (email)</label>
<input type="email" id="input-email"></input>
<wa-input label="WA Input (email)" type="email"></wa-input>
<label for="input-search">Input (search)</label>
<input type="search" id="input-search"></input>
<wa-input label="WA Input (search)" type="search"></wa-input>
<label for="input-tel">Input (tel)</label>
<input type="tel" id="input-tel"></input>
<wa-input label="WA Input (tel)" type="tel"></wa-input>
<label for="input-url">Input (url)</label>
<input type="url" id="input-url"></input>
<wa-input label="WA Input (url)" type="url"></wa-input>
<input type="checkbox" id="input-checkbox"></input>
<label for="input-checkbox">Input (checkbox)</label>

View File

@@ -1,63 +1,13 @@
:host {
--background-color: var(--wa-form-control-background-color);
--border-color: var(--wa-form-control-resting-color);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-form-control-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
display: block;
}
:host([filled]) {
--background-color: var(--wa-color-neutral-fill-quiet);
--border-color: var(--background-color);
}
.input {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
flex: 1 1 auto;
display: inline-flex;
display: flex;
align-items: stretch;
justify-content: start;
position: relative;
width: 100%;
font: inherit;
vertical-align: middle;
overflow: hidden;
cursor: text;
transition:
background var(--wa-transition-normal) var(--wa-transition-easing),
border var(--wa-transition-normal) var(--wa-transition-easing),
outline var(--wa-transition-fast) var(--wa-transition-easing);
}
/* Standard inputs */
.input--standard.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
border-color: var(--wa-form-control-activated-color);
}
.input--standard.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* Filled inputs */
.input--filled.input--focused:not(.input--disabled) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
.input--filled.input--disabled {
opacity: 0.5;
cursor: not-allowed;
}
.input__control {
@@ -65,8 +15,6 @@
min-width: 0;
height: 100%;
font: inherit;
line-height: var(--wa-form-control-value-line-height);
color: var(--wa-form-control-value-color);
border: none;
/* prettier-ignore */
background-color: rgb(118 118 118 / 0); /* ensures proper placeholder styles in webkit's date input */
@@ -84,28 +32,6 @@
-webkit-appearance: none;
}
.input__control:-webkit-autofill,
.input__control:-webkit-autofill:hover,
.input__control:-webkit-autofill:focus,
.input__control:-webkit-autofill:active {
box-shadow: none;
-webkit-text-fill-color: var(--wa-color-brand-on-normal);
caret-color: var(--wa-form-control-value-color);
}
.input--filled .input__control:-webkit-autofill,
.input--filled .input__control:-webkit-autofill:hover,
.input--filled .input__control:-webkit-autofill:focus,
.input--filled .input__control:-webkit-autofill:active {
box-shadow: none;
}
.input__control::placeholder {
color: var(--wa-form-control-placeholder-color);
user-select: none;
-webkit-user-select: none;
}
.input__control:focus {
outline: none;
}
@@ -195,14 +121,6 @@
}
}
/*
* Pill modifier
*/
.input--pill {
border-radius: var(--wa-border-radius-pill);
}
/*
* Clearable + Password Toggle
*/

View File

@@ -12,6 +12,7 @@ import { HasSlotController } from '../../internal/slot.js';
import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js';
import nativeStyles from '../../styles/native/input.css';
import formControlStyles from '../../styles/shadow/form-control.css';
import { LocalizeController } from '../../utilities/localize.js';
import type WaButton from '../button/button.js';
@@ -61,7 +62,7 @@ import styles from './input.css';
*/
@customElement('wa-input')
export default class WaInput extends WebAwesomeFormAssociatedElement {
static shadowStyle = [formControlStyles, styles];
static shadowStyle = [formControlStyles, nativeStyles, styles];
static shadowRootOptions = { ...WebAwesomeFormAssociatedElement.shadowRootOptions, delegatesFocus: true };
@@ -206,8 +207,8 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
converter: {
// Allow "true|false" attribute values but keep the property boolean
fromAttribute: value => (!value || value === 'false' ? false : true),
toAttribute: value => (value ? 'true' : 'false'),
},
toAttribute: value => (value ? 'true' : 'false')
}
})
spellcheck = true;
@@ -289,7 +290,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
}
const button = formElements.find(
(el: HTMLButtonElement) => el.type === 'submit' && !el.matches(':disabled'),
(el: HTMLButtonElement) => el.type === 'submit' && !el.matches(':disabled')
) as undefined | HTMLButtonElement | WaButton;
// No button found, don't submit.
@@ -339,7 +340,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
setSelectionRange(
selectionStart: number,
selectionEnd: number,
selectionDirection: 'forward' | 'backward' | 'none' = 'none',
selectionDirection: 'forward' | 'backward' | 'none' = 'none'
) {
this.input.setSelectionRange(selectionStart, selectionEnd, selectionDirection);
}
@@ -349,7 +350,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
replacement: string,
start?: number,
end?: number,
selectMode: 'select' | 'start' | 'end' | 'preserve' = 'preserve',
selectMode: 'select' | 'start' | 'end' | 'preserve' = 'preserve'
) {
const selectionStart = start ?? this.input.selectionStart!;
const selectionEnd = end ?? this.input.selectionEnd!;
@@ -410,7 +411,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
'form-control--small': this.size === 'small',
'form-control--medium': this.size === 'medium',
'form-control--large': this.size === 'large',
'form-control--has-label': hasLabel,
'form-control--has-label': hasLabel
})}
>
<label
@@ -440,7 +441,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
'input--disabled': this.disabled,
'input--focused': this.hasFocus,
'input--empty': !this.value,
'input--no-spin-buttons': this.noSpinButtons,
'input--no-spin-buttons': this.noSpinButtons
})}
>
<span part="prefix" class="input__prefix">
@@ -531,7 +532,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
name="hint"
part="hint"
class=${classMap({
'has-slotted': hasHint,
'has-slotted': hasHint
})}
aria-hidden=${hasHint ? 'false' : 'true'}
>${this.hint}</slot

View File

@@ -1 +1,3 @@
@import url('./native/button.css');
@import url('./native/form-control.css');
@import url('./native/input.css');

View File

@@ -0,0 +1,13 @@
label {
display: inline-block;
color: var(--wa-form-control-label-color);
font-weight: var(--wa-form-control-label-font-weight);
line-height: var(--wa-form-control-label-line-height);
margin-bottom: var(--wa-space-xs);
}
label:has(+ input:required)::after {
content: var(--wa-form-control-required-content);
margin-inline-start: var(--wa-form-control-required-content-offset);
color: var(--wa-form-control-required-content-color);
}

View File

@@ -0,0 +1,98 @@
/* Exclude inputs that don't accept text, referenced in subsequent rules with :where(&) */
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
) {
/* Set custom properties for native and WA inputs */
input:where(:not(:host input)):where(&),
:host(&) {
--background-color: var(--wa-form-control-background-color);
--border-color: var(--wa-form-control-resting-color);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-form-control-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
}
/* Set custom properties for filled input variants via class="wa-filled" or <wa-input filled> */
input:where(:not(:host input)).wa-filled:where(&),
:host(.wa-filled:where(&)),
:host([filled]:where(&)) {
--background-color: var(--wa-color-neutral-fill-quiet);
--border-color: var(--background-color);
}
/* Set custom properties for pill input variants via class="wa-pill" or <wa-input pill> */
input:where(:not(:host input)).wa-pill:where(&),
:host(.wa-pill:where(&)),
:host([pill]:where(&)) {
--border-radius: var(--wa-border-radius-pill);
}
/* Style text controls of inputs, including within <wa-input> */
:is(input):where(&) {
color: var(--wa-form-control-value-color);
font-size: var(--wa-font-size-m);
line-height: var(--wa-form-control-value-line-height);
padding: 0 var(--wa-space-m);
&:-webkit-autofill,
&:-webkit-autofill:hover,
&:-webkit-autofill:focus,
&:-webkit-autofill:active {
box-shadow: none;
caret-color: var(--wa-form-control-value-color);
}
&::placeholder {
color: var(--wa-form-control-placeholder-color);
user-select: none;
-webkit-user-select: none;
}
}
/* Style native inputs and <wa-input>'s visible container */
:is(input:where(:not(:host input)), :host .input):where(&) {
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
cursor: text;
font-family: inherit;
line-height: var(--wa-form-control-value-line-height);
overflow: hidden;
vertical-align: middle;
width: 100%;
transition:
background-color var(--wa-transition-normal),
border var(--wa-transition-normal),
outline var(--wa-transition-fast);
transition-timing-function: var(--wa-transition-easing);
&:not(.input--small, .input--large) {
height: var(--wa-form-control-height-m);
}
}
/* Style focused inputs */
:is(input:where(:not(:host input)):focus, :host .input--focused:not(.input--disabled)):where(&) {
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
/* Style disabled inputs */
:is(input:where(:not(:host input)):disabled, :host .input--disabled):where(&) {
cursor: not-allowed;
opacity: 0.5;
}
}

View File

@@ -8,7 +8,7 @@
color: var(--wa-form-control-label-color);
font-weight: var(--wa-form-control-label-font-weight);
line-height: var(--wa-form-control-label-line-height);
margin-bottom: var(--wa-space-3xs);
margin-block-end: var(--wa-space-xs);
&:is(.form-control--small *) {
font-size: var(--wa-font-size-s);
@@ -32,9 +32,11 @@
/* Help text */
[part~='form-control-hint'],
[part~='hint'] {
display: inline-block;
color: var(--wa-color-text-quiet);
margin-top: var(--wa-space-3xs);
margin-block-start: var(--wa-space-xs);
font-size: var(--size-smaller, 85%);
line-height: var(--wa-form-control-label-line-height);
&:is(.form-control--small *) {
font-size: var(--wa-font-size-xs);