diff --git a/field/internal/field.ts b/field/internal/field.ts index efc8bdc6b2..1ef45b695a 100644 --- a/field/internal/field.ts +++ b/field/internal/field.ts @@ -120,6 +120,8 @@ export class Field extends LitElement implements SurfacePositionTarget {
${this.renderBackground?.()} + ${this.renderIndicator?.()} + ${outline}
@@ -137,8 +139,6 @@ export class Field extends LitElement implements SurfacePositionTarget {
- ${outline} - ${this.renderIndicator?.()}
${this.renderSupportingText()}
diff --git a/textfield/demo/demo.ts b/textfield/demo/demo.ts index 818bb6ed69..0ee83bf5fe 100644 --- a/textfield/demo/demo.ts +++ b/textfield/demo/demo.ts @@ -8,28 +8,19 @@ import './index.js'; import './material-collection.js'; import {KnobTypesToKnobs, MaterialCollection, materialInitsToStoryInits, setUpDemo} from './material-collection.js'; -import {boolInput, Knob, numberInput, textInput} from './index.js'; +import {boolInput, Knob, textInput} from './index.js'; import {stories, StoryKnobs} from './stories.js'; const collection = new MaterialCollection>('Textfield', [ new Knob('label', {ui: textInput(), defaultValue: 'Label'}), - new Knob('textarea', {ui: boolInput(), defaultValue: false}), + new Knob('placeholder', {ui: textInput(), defaultValue: ''}), new Knob('disabled', {ui: boolInput(), defaultValue: false}), - new Knob('required', {ui: boolInput(), defaultValue: false}), new Knob('prefixText', {ui: textInput(), defaultValue: ''}), new Knob('suffixText', {ui: textInput(), defaultValue: ''}), new Knob( 'supportingText', {ui: textInput(), defaultValue: 'Supporting text'}), - new Knob('minLength', {ui: numberInput(), defaultValue: -1}), - new Knob('maxLength', {ui: numberInput(), defaultValue: -1}), - new Knob('min', {ui: textInput(), defaultValue: ''}), - new Knob('max', {ui: textInput(), defaultValue: ''}), - new Knob('step', {ui: textInput(), defaultValue: ''}), - new Knob('pattern', {ui: textInput(), defaultValue: ''}), - new Knob('leading icon', {ui: boolInput(), defaultValue: false}), - new Knob('trailing icon', {ui: boolInput(), defaultValue: false}), ]); collection.addStories(...materialInitsToStoryInits(stories)); diff --git a/textfield/demo/stories.ts b/textfield/demo/stories.ts index 6b4a18d78e..5414bbe3e7 100644 --- a/textfield/demo/stories.ts +++ b/textfield/demo/stories.ts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import '@material/web/button/outlined-button.js'; +import '@material/web/button/text-button.js'; import '@material/web/icon/icon.js'; import '@material/web/iconbutton/icon-button.js'; import '@material/web/textfield/filled-text-field.js'; @@ -16,24 +18,27 @@ import {css, html, nothing} from 'lit'; /** Knob types for Textfield stories. */ export interface StoryKnobs { label: string; - textarea: boolean; + placeholder: string; disabled: boolean; - required: boolean; prefixText: string; suffixText: string; supportingText: string; - minLength: number; - maxLength: number; - min: string; - max: string; - step: string; - pattern: string; - 'leading icon': boolean; - 'trailing icon': boolean; } // Set min-height for resizable textareas const styles = css` + .row { + align-items: flex-start; + display: flex; + flex-wrap: wrap; + gap: 16px; + } + + md-filled-text-field, + md-outlined-text-field { + width: 200px; + } + [type=textarea] { min-height: 56px; } @@ -43,68 +48,207 @@ const styles = css` } `; -const filled: MaterialStoryInit = { - name: '', +const textfields: MaterialStoryInit = { + name: 'Text fields', + styles, + render(knobs) { + return html` +
+ + + +
+ `; + } +}; + +const textareas: MaterialStoryInit = { + name: 'Text areas', + styles, + render(knobs) { + return html` +
+ + + +
+ `; + } +}; + +const icons: MaterialStoryInit = { + name: 'Icons', styles, render(knobs) { return html` - - ${knobs['leading icon'] ? LEADING_ICON : nothing} - ${knobs['trailing icon'] ? TRAILING_ICON : nothing} - +
+ + search + + clear + + + + + search + + clear + + +
`; } }; -const outlined: MaterialStoryInit = { - name: '', +const validation: MaterialStoryInit = { + name: 'Validation', styles, render(knobs) { return html` - - ${knobs['leading icon'] ? LEADING_ICON : nothing} - ${knobs['trailing icon'] ? TRAILING_ICON : nothing} - +
+ + + + + + + +
+ `; + } +}; + +const forms: MaterialStoryInit = { + name: 'Forms', + styles: [ + styles, + css` + .buttons { + justify-content: flex-end; + padding: 16px; + } + `, + ], + render(knobs) { + return html` +
+
+ + +
+
+ Reset + Submit +
+
`; } }; -const LEADING_ICON = html`search`; -const TRAILING_ICON = - html`event`; function reportValidity(event: Event) { (event.target as MdFilledTextField).reportValidity(); } +function clearInput(event: Event) { + const iconButton = event.target as HTMLElement; + const textField = iconButton.parentElement as MdFilledTextField; + iconButton.blur(); + textField.value = ''; + textField.focus(); +} + +function alertValues(event: SubmitEvent) { + event.preventDefault(); + const data = new FormData(event.target as HTMLFormElement); + const first = data.get('first-name') || ''; + const last = data.get('last-name') || ''; + alert(`First name: ${first}, Last name: ${last}`); +} + /** Textfield stories. */ -export const stories = [filled, outlined]; +export const stories = [textfields, textareas, icons, validation, forms]; diff --git a/textfield/internal/_input.scss b/textfield/internal/_input.scss index 4caf48eb18..cd638b6cef 100644 --- a/textfield/internal/_input.scss +++ b/textfield/internal/_input.scss @@ -65,6 +65,7 @@ .prefix, .suffix { + text-wrap: nowrap; width: min-content; }