mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
Updates
This commit is contained in:
@@ -137,9 +137,4 @@ Show a valid or invalid state by setting the `valid` and `invalid` attributes, r
|
||||
</sl-input>
|
||||
```
|
||||
|
||||
The easiest way to handle validation in Shoelace is with the `valid` and `invalid` props shown above. This is designed to work well with client-side and server-side validation.
|
||||
|
||||
[HTML form validation](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#Using_built-in_form_validation) is also possible with limitations. For example, providing validation styles to all the component's internals (e.g. prefix, suffix, labels, and help text) is not a trivial task with this approach. If you only care about styling the underlying _native input_, you can target the component's `input` part with the `:valid` and `:invalid` selector.
|
||||
|
||||
|
||||
[component-metadata:sl-input]
|
||||
|
||||
@@ -32,6 +32,20 @@ Use the `label` attribute to give the select an accessible label.
|
||||
</sl-select>
|
||||
```
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to an input with the `help-text` slot.
|
||||
|
||||
```html preview
|
||||
<sl-select label="Experience">
|
||||
<sl-menu-item value="option-1">Novice</sl-menu-item>
|
||||
<sl-menu-item value="option-2">Intermediate</sl-menu-item>
|
||||
<sl-menu-item value="option-3">Advanced</sl-menu-item>
|
||||
|
||||
<div slot="help-text">Please tell us your skill level.</div>
|
||||
</sl-select>
|
||||
```
|
||||
|
||||
### Multiple
|
||||
|
||||
To allow multiple options to be selected, use the `multiple` attribute.
|
||||
@@ -118,4 +132,28 @@ Use the `disabled` prop to disable a select.
|
||||
</sl-select>
|
||||
```
|
||||
|
||||
### Validation
|
||||
|
||||
Show a valid or invalid state by setting the `valid` and `invalid` attributes, respectively. Help text can be used to provide feedback for validation and will be styled accordingly.
|
||||
|
||||
```html preview
|
||||
<sl-select placeholder="Valid" valid>
|
||||
<sl-menu-item value="option-1">Option 1</sl-menu-item>
|
||||
<sl-menu-item value="option-2">Option 2</sl-menu-item>
|
||||
<sl-menu-item value="option-3">Option 3</sl-menu-item>
|
||||
|
||||
<div slot="help-text">This is a valid selection!</div>
|
||||
</sl-select>
|
||||
|
||||
<br>
|
||||
|
||||
<sl-select placeholder="Invalid" invalid>
|
||||
<sl-menu-item value="option-1">Option 1</sl-menu-item>
|
||||
<sl-menu-item value="option-2">Option 2</sl-menu-item>
|
||||
<sl-menu-item value="option-3">Option 3</sl-menu-item>
|
||||
|
||||
<div slot="help-text">This is not a valid selection!</div>
|
||||
</sl-select>
|
||||
```
|
||||
|
||||
[component-metadata:sl-select]
|
||||
|
||||
16
src/components.d.ts
vendored
16
src/components.d.ts
vendored
@@ -568,6 +568,10 @@ export namespace Components {
|
||||
* Set to true to disable the select control.
|
||||
*/
|
||||
"disabled": boolean;
|
||||
/**
|
||||
* Set to true to indicate that the user input is invalid.
|
||||
*/
|
||||
"invalid": boolean;
|
||||
/**
|
||||
* The select's label.
|
||||
*/
|
||||
@@ -596,6 +600,10 @@ export namespace Components {
|
||||
* The select's size.
|
||||
*/
|
||||
"size": 'small' | 'medium' | 'large';
|
||||
/**
|
||||
* Set to true to indicate that the user input is valid.
|
||||
*/
|
||||
"valid": boolean;
|
||||
/**
|
||||
* The value of the control. This will be a string or an array depending on `multiple`.
|
||||
*/
|
||||
@@ -1682,6 +1690,10 @@ declare namespace LocalJSX {
|
||||
* Set to true to disable the select control.
|
||||
*/
|
||||
"disabled"?: boolean;
|
||||
/**
|
||||
* Set to true to indicate that the user input is invalid.
|
||||
*/
|
||||
"invalid"?: boolean;
|
||||
/**
|
||||
* The select's label.
|
||||
*/
|
||||
@@ -1722,6 +1734,10 @@ declare namespace LocalJSX {
|
||||
* The select's size.
|
||||
*/
|
||||
"size"?: 'small' | 'medium' | 'large';
|
||||
/**
|
||||
* Set to true to indicate that the user input is valid.
|
||||
*/
|
||||
"valid"?: boolean;
|
||||
/**
|
||||
* The value of the control. This will be a string or an array depending on `multiple`.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ let id = 0;
|
||||
* @since 1.0
|
||||
* @status stable
|
||||
*
|
||||
* @slot label - The input's label. Alternatively, you can use the label prop.
|
||||
* @slot prefix - Used to prepend an icon or similar element to the input.
|
||||
* @slot suffix - Used to append an icon or similar element to the input.
|
||||
* @slot clear-icon - An icon to use in lieu of the default clear icon.
|
||||
@@ -242,7 +241,7 @@ export class Input {
|
||||
}}
|
||||
htmlFor={this.inputId}
|
||||
>
|
||||
<slot name="label">{this.label}</slot>
|
||||
{this.label}
|
||||
</label>
|
||||
|
||||
<div
|
||||
|
||||
@@ -57,3 +57,35 @@
|
||||
.select--open .select__icon sl-icon {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Help text
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
.help-text {
|
||||
color: var(--sl-input-help-text-color);
|
||||
|
||||
&.help-text--small {
|
||||
font-size: var(--sl-input-help-text-font-size-small);
|
||||
}
|
||||
|
||||
&.help-text--medium {
|
||||
font-size: var(--sl-input-help-text-font-size-medium);
|
||||
}
|
||||
|
||||
&.help-text--large {
|
||||
font-size: var(--sl-input-help-text-font-size-large);
|
||||
}
|
||||
|
||||
&.help-text--valid {
|
||||
color: var(--sl-input-help-text-color-valid);
|
||||
}
|
||||
|
||||
&.help-text--invalid {
|
||||
color: var(--sl-input-help-text-color-invalid);
|
||||
}
|
||||
|
||||
::slotted(*) {
|
||||
margin-top: var(--sl-spacing-xxx-small);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,13 @@ let id = 0;
|
||||
* @status stable
|
||||
*
|
||||
* @slot - The select's options in the form of menu items.
|
||||
* @slot label - The select's label. Alternatively, you can use the label prop.
|
||||
* @slot help-text - Help text that describes how to use the select.
|
||||
*
|
||||
* @part base - The component's base wrapper.
|
||||
* @part form-control - The form control that wraps the label and the select.
|
||||
* @part label - The select label.
|
||||
* @part input - The select input.
|
||||
* @part tags - The container in which multiselect options are rendered.
|
||||
* @part icon - The select icon.
|
||||
* @part help-text - The select help text.
|
||||
*/
|
||||
|
||||
@Component({
|
||||
@@ -39,8 +38,9 @@ export class Select {
|
||||
|
||||
dropdown: HTMLSlDropdownElement;
|
||||
input: HTMLSlInputElement;
|
||||
inputId = `input-${++id}`;
|
||||
labelId = `input-label-${id}`;
|
||||
inputId = `select-${++id}`;
|
||||
labelId = `select-label-${id}`;
|
||||
helpTextId = `select-help-text-${id}`;
|
||||
menu: HTMLSlMenuElement;
|
||||
resizeObserver: any;
|
||||
|
||||
@@ -82,6 +82,12 @@ export class Select {
|
||||
/** The select's label. */
|
||||
@Prop() label = '';
|
||||
|
||||
/** Set to true to indicate that the user input is valid. */
|
||||
@Prop() valid = false;
|
||||
|
||||
/** Set to true to indicate that the user input is invalid. */
|
||||
@Prop() invalid = false;
|
||||
|
||||
@Watch('multiple')
|
||||
handleMultipleChange() {
|
||||
// Cast to array | string based on `this.multiple`
|
||||
@@ -282,22 +288,11 @@ export class Select {
|
||||
part="form-control"
|
||||
class={{
|
||||
'form-control': true,
|
||||
'form-control--has-label': this.label.length > 0
|
||||
'form-control--has-label': this.label.length > 0,
|
||||
'form-control--valid': this.valid,
|
||||
'form-control--invalid': this.invalid
|
||||
}}
|
||||
>
|
||||
<label
|
||||
part="label"
|
||||
class={{
|
||||
label: true,
|
||||
'label--small': this.size === 'small',
|
||||
'label--medium': this.size === 'medium',
|
||||
'label--large': this.size === 'large'
|
||||
}}
|
||||
htmlFor={this.inputId}
|
||||
onClick={this.handleLabelClick}
|
||||
>
|
||||
<slot name="label">{this.label}</slot>
|
||||
</label>
|
||||
<sl-dropdown
|
||||
part="base"
|
||||
ref={el => (this.dropdown = el)}
|
||||
@@ -327,9 +322,12 @@ export class Select {
|
||||
value={this.displayLabel}
|
||||
disabled={this.disabled}
|
||||
pill={this.pill}
|
||||
label={this.label}
|
||||
placeholder={this.displayLabel === '' && this.displayTags.length === 0 ? this.placeholder : null}
|
||||
readonly={true}
|
||||
size={this.size}
|
||||
valid={this.valid}
|
||||
invalid={this.invalid}
|
||||
aria-labelledby={this.labelId}
|
||||
onSlFocus={this.handleFocus}
|
||||
onSlBlur={this.handleBlur}
|
||||
@@ -355,6 +353,21 @@ export class Select {
|
||||
<slot />
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
|
||||
<div
|
||||
part="help-text"
|
||||
id={this.helpTextId}
|
||||
class={{
|
||||
'help-text': true,
|
||||
'help-text--small': this.size === 'small',
|
||||
'help-text--medium': this.size === 'medium',
|
||||
'help-text--large': this.size === 'large',
|
||||
'help-text--valid': this.valid,
|
||||
'help-text--invalid': this.invalid
|
||||
}}
|
||||
>
|
||||
<slot name="help-text" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ let id = 0;
|
||||
* @since 1.0
|
||||
* @status stable
|
||||
*
|
||||
* @slot label - The textarea's label. Alternatively, you can use the label prop.
|
||||
*
|
||||
* @part base - The component's base wrapper.
|
||||
* @part form-control - The form control that wraps the textarea and label.
|
||||
* @part label - The textarea label.
|
||||
@@ -197,7 +195,7 @@ export class Textarea {
|
||||
}}
|
||||
htmlFor={this.textareaId}
|
||||
>
|
||||
<slot name="label">{this.label}</slot>
|
||||
{this.label}
|
||||
</label>
|
||||
<div
|
||||
part="base"
|
||||
|
||||
Reference in New Issue
Block a user