From e026f33bc08c90fa7200f91f8902c5af24b5c718 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Thu, 2 Jul 2020 07:51:54 -0400 Subject: [PATCH] Add labels to textarea and input --- docs/components/input.md | 8 ++ docs/components/textarea.md | 6 + src/components.d.ts | 20 +++- src/components/input/input.scss | 31 ++++- src/components/input/input.tsx | 156 +++++++++++++++----------- src/components/textarea/textarea.scss | 30 ++++- src/components/textarea/textarea.tsx | 98 ++++++++++------ src/styles/shoelace.scss | 1 + 8 files changed, 245 insertions(+), 105 deletions(-) diff --git a/docs/components/input.md b/docs/components/input.md index 79447a887..e780e4f8e 100644 --- a/docs/components/input.md +++ b/docs/components/input.md @@ -14,6 +14,14 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i ## Examples +### Labels + +```html preview + +
+ +``` + ### Size ```html preview diff --git a/docs/components/textarea.md b/docs/components/textarea.md index 14b413ca4..cd7d8052a 100644 --- a/docs/components/textarea.md +++ b/docs/components/textarea.md @@ -14,6 +14,12 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i ## Examples +### Labels + +```html preview + +``` + ### No Resize ```html preview diff --git a/src/components.d.ts b/src/components.d.ts index f121e6db3..9cfe04241 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -184,7 +184,7 @@ export namespace Components { */ "show": () => Promise; /** - * The plain-text summary to show in the details header. To show an HTML summary, use the `summary` slot. + * The summary to show in the details header. */ "summary": string; } @@ -358,6 +358,10 @@ export namespace Components { * The input's inputmode attribute. */ "inputmode": 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'; + /** + * The input's label. + */ + "label": string; /** * The input's max attribute. */ @@ -706,6 +710,10 @@ export namespace Components { * The textarea's inputmode attribute. */ "inputmode": 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'; + /** + * The textarea's label. + */ + "label": string; /** * The textarea's maxlength attribute. */ @@ -1246,7 +1254,7 @@ declare namespace LocalJSX { */ "open"?: boolean; /** - * The plain-text summary to show in the details header. To show an HTML summary, use the `summary` slot. + * The summary to show in the details header. */ "summary"?: string; } @@ -1444,6 +1452,10 @@ declare namespace LocalJSX { * The input's inputmode attribute. */ "inputmode"?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'; + /** + * The input's label. + */ + "label"?: string; /** * The input's max attribute. */ @@ -1816,6 +1828,10 @@ declare namespace LocalJSX { * The textarea's inputmode attribute. */ "inputmode"?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url'; + /** + * The textarea's label. + */ + "label"?: string; /** * The textarea's maxlength attribute. */ diff --git a/src/components/input/input.scss b/src/components/input/input.scss index 4feb8c112..60c61db77 100644 --- a/src/components/input/input.scss +++ b/src/components/input/input.scss @@ -5,6 +5,34 @@ cursor: text; } +.form-control { + display: flex; + flex-direction: column; + + .label { + display: none; + } +} + +.form-control--has-label { + .label { + display: inline-block; + margin-bottom: var(--sl-spacing-xx-small); + + &.label--small { + font-size: var(--sl-input-font-size-small); + } + + &.label--medium { + font-size: var(--sl-input-font-size-medium); + } + + &.label--large { + font-size: var(--sl-input-font-size-large); + } + } +} + .input { flex: 1 1 auto; display: inline-flex; @@ -14,8 +42,7 @@ width: 100%; font-family: var(--sl-input-font-family); font-weight: var(--sl-input-font-weight); - line-height: var(--sl-line-height-normal); - letter-spacing: var(--sl-letter-spacing-normal); + letter-spacing: var(--sl-input-letter-spacing); background-color: var(--sl-input-background-color); border: solid var(--sl-input-border-width) var(--sl-input-border-color); vertical-align: middle; diff --git a/src/components/input/input.tsx b/src/components/input/input.tsx index 8d6af4cba..8964adf5a 100644 --- a/src/components/input/input.tsx +++ b/src/components/input/input.tsx @@ -1,5 +1,7 @@ import { Component, Element, Event, EventEmitter, Method, Prop, State, h } from '@stencil/core'; +let id = 0; + /** * @since 1.0 * @status stable @@ -27,6 +29,8 @@ export class Input { this.handlePasswordToggle = this.handlePasswordToggle.bind(this); } + inputId = `input-${++id}`; + labelId = `input-label-${id}`; input: HTMLInputElement; @Element() host: HTMLSlInputElement; @@ -46,6 +50,9 @@ export class Input { /** The input's value attribute. */ @Prop({ mutable: true }) value: string = ''; + /** The input's label. */ + @Prop() label = ''; + /** The input's placeholder text. */ @Prop() placeholder: string; @@ -194,77 +201,98 @@ export class Input { return (
0 }} - onMouseDown={this.handleMouseDown} > - - - + - (this.input = el)} - class="input__control" - type={this.type === 'password' && this.isPasswordVisible ? 'text' : this.type} - name={this.name} - placeholder={this.placeholder} - disabled={this.disabled} - readonly={this.readonly} - minLength={this.minlength} - maxLength={this.maxlength} - min={this.min} - max={this.max} - step={this.step} - value={this.value} - autoCapitalize={this.autocapitalize} - autoComplete={this.autocomplete} - autoCorrect={this.autocorrect} - autoFocus={this.autofocus} - pattern={this.pattern} - required={this.required} - inputMode={this.inputmode} - onChange={this.handleChange} - onInput={this.handleInput} - onFocus={this.handleFocus} - onBlur={this.handleBlur} - /> +
- - - - - )} + // Sizes + 'input--small': this.size === 'small', + 'input--medium': this.size === 'medium', + 'input--large': this.size === 'large', - {this.togglePassword && ( - - )} + + )} - - - + {this.togglePassword && ( + + )} + + + + +
); } diff --git a/src/components/textarea/textarea.scss b/src/components/textarea/textarea.scss index 3d09353d7..ae2afa85b 100644 --- a/src/components/textarea/textarea.scss +++ b/src/components/textarea/textarea.scss @@ -5,6 +5,34 @@ cursor: text; } +.form-control { + display: flex; + flex-direction: column; + + .label { + display: none; + } +} + +.form-control--has-label { + .label { + display: inline-block; + margin-bottom: var(--sl-spacing-xx-small); + + &.label--small { + font-size: var(--sl-input-font-size-small); + } + + &.label--medium { + font-size: var(--sl-input-font-size-medium); + } + + &.label--large { + font-size: var(--sl-input-font-size-large); + } + } +} + .textarea { display: flex; align-items: center; @@ -13,7 +41,7 @@ font-family: var(--sl-input-font-family); font-weight: var(--sl-input-font-weight); line-height: var(--sl-line-height-normal); - letter-spacing: var(--sl-letter-spacing-normal); + letter-spacing: var(--sl-input-letter-spacing); background-color: var(--sl-input-background-color); border: solid var(--sl-input-border-width) var(--sl-input-border-color); vertical-align: middle; diff --git a/src/components/textarea/textarea.tsx b/src/components/textarea/textarea.tsx index d174a714c..8dc765b0c 100644 --- a/src/components/textarea/textarea.tsx +++ b/src/components/textarea/textarea.tsx @@ -1,6 +1,8 @@ import { Component, Event, EventEmitter, Method, Prop, State, Watch, h } from '@stencil/core'; import ResizeObserver from 'resize-observer-polyfill'; +let id = 0; + /** * @since 1.0 * @status stable @@ -19,6 +21,8 @@ export class Textarea { this.handleFocus = this.handleFocus.bind(this); } + textareaId = `input-${++id}`; + labelId = `input-label-${id}`; resizeObserver: any; textarea: HTMLTextAreaElement; @@ -33,6 +37,9 @@ export class Textarea { /** The textarea's value attribute. */ @Prop({ mutable: true }) value = ''; + /** The textarea's label. */ + @Prop() label = ''; + /** The textarea's placeholder text. */ @Prop() placeholder: string; @@ -168,44 +175,63 @@ export class Textarea { return (
0 }} > -