Add clearable and required props to select; fixes #182

pull/186/head
Cory LaViska 2020-08-25 16:25:25 -04:00
rodzic e169c937df
commit 7d5aac4bc8
5 zmienionych plików z 100 dodań i 41 usunięć

Wyświetl plik

@ -2,6 +2,9 @@
## 2.0.0-beta.16
- Add `sl-format-bytes` utility component
- Add `clearable` and `required` props to `sl-select`
- Add `slClear` event to `sl-input`
- Fix incorrect `aria-selected` state in `sl-menu-item`
## 2.0.0-beta.15

Wyświetl plik

@ -5,7 +5,7 @@
Selects allow you to choose one or more items from a dropdown menu.
```html preview
<sl-select placeholder="Select one">
<sl-select>
<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>
@ -20,38 +20,60 @@ Selects allow you to choose one or more items from a dropdown menu.
## Examples
### Labels
### Placeholders
Use the `label` attribute to give the select an accessible label.
Use the `placeholder` attribute to add a placeholder.
```html preview
<sl-select label="Select one">
<sl-select placeholder="Select one">
<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>
</sl-select>
```
### Help Text
### Clearable
Add descriptive help text to an input with the `help-text` slot.
Use the `clearable` attribute to make the control clearable.
```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>
<sl-select placeholder="Clearable" clearable>
<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>
</sl-select>
```
<div slot="help-text">Please tell us your skill level.</div>
### Pill
Use the `pill` prop to give selects rounded edges.
```html preview
<sl-select pill multiple>
<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>
</sl-select>
```
### Disabled
Use the `disabled` prop to disable a select.
```html preview
<sl-select placeholder="Disabled" disabled>
<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>
</sl-select>
```
### Multiple
To allow multiple options to be selected, use the `multiple` attribute.
To allow multiple options to be selected, use the `multiple` attribute. It's a good practice to use `clearable` when this option is enabled.
```html preview
<sl-select placeholder="Select a few" multiple>
<sl-select placeholder="Select a few" multiple clearable>
<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>
@ -62,7 +84,25 @@ To allow multiple options to be selected, use the `multiple` attribute.
</sl-select>
```
### Size
### Grouping Options
Options can be grouped visually using menu labels and menu dividers.
```html preview
<sl-select placeholder="Select one">
<sl-menu-label>Group 1</sl-menu-label>
<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>
<sl-menu-divider></sl-menu-divider>
<sl-menu-label>Group 2</sl-menu-label>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
</sl-select>
```
### Sizes
Use the `size` attribute to change a select's size.
@ -90,45 +130,29 @@ Use the `size` attribute to change a select's size.
</sl-select>
```
### Pill
### Labels
Use the `pill` prop to give selects rounded edges.
Use the `label` attribute to give the select an accessible label.
```html preview
<sl-select pill multiple>
<sl-select label="Select one">
<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>
</sl-select>
```
### Groups
### Help Text
Options can be grouped visually using menu labels and menu dividers.
Add descriptive help text to an input with the `help-text` slot.
```html preview
<sl-select placeholder="Select one">
<sl-menu-label>Group 1</sl-menu-label>
<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>
<sl-menu-divider></sl-menu-divider>
<sl-menu-label>Group 2</sl-menu-label>
<sl-menu-item value="option-4">Option 4</sl-menu-item>
<sl-menu-item value="option-5">Option 5</sl-menu-item>
<sl-menu-item value="option-6">Option 6</sl-menu-item>
</sl-select>
```
<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>
### Disabled
Use the `disabled` prop to disable a select.
```html preview
<sl-select placeholder="Disabled" disabled>
<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">Please tell us your skill level.</div>
</sl-select>
```

12
src/components.d.ts vendored
Wyświetl plik

@ -734,6 +734,10 @@ export namespace Components {
"value": number;
}
interface SlSelect {
/**
* Set to true to add a clear button when the select is populated.
*/
"clearable": boolean;
/**
* Set to true to disable the select control.
*/
@ -1868,6 +1872,10 @@ declare namespace LocalJSX {
* Emitted when the control's value changes.
*/
"onSlChange"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the clear button is activated.
*/
"onSlClear"?: (event: CustomEvent<any>) => void;
/**
* Emitted when the control gains focus.
*/
@ -2092,6 +2100,10 @@ declare namespace LocalJSX {
"value"?: number;
}
interface SlSelect {
/**
* Set to true to add a clear button when the select is populated.
*/
"clearable"?: boolean;
/**
* Set to true to disable the select control.
*/

Wyświetl plik

@ -37,3 +37,9 @@
.select--open .select__icon sl-icon {
transform: rotate(-180deg);
}
// Force the input's clear button to show when the select isn't empty. This is important for the `multiple` option, as
// it doesn't use the input's `value` prop to display the selection.
.select:not(.select--empty) .select__input::part(clear-button) {
visibility: visible;
}

Wyświetl plik

@ -77,6 +77,9 @@ export class Select {
/** The select's required attribute. */
@Prop() required: boolean;
/** Set to true to add a clear button when the select is populated. */
@Prop() clearable = false;
/** Set to true to indicate that the user input is valid. */
@Prop() valid = false;
@ -109,6 +112,7 @@ export class Select {
connectedCallback() {
this.handleBlur = this.handleBlur.bind(this);
this.handleFocus = this.handleFocus.bind(this);
this.handleClear = this.handleClear.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.handleLabelClick = this.handleLabelClick.bind(this);
this.handleMenuKeyDown = this.handleMenuKeyDown.bind(this);
@ -156,6 +160,12 @@ export class Select {
this.input.setSelectionRange(0, 0);
}
handleClear() {
this.value = this.multiple ? [] : '';
this.syncItemsFromValue();
this.dropdown.hide();
}
handleKeyDown(event: KeyboardEvent) {
const target = event.target as HTMLElement;
@ -251,7 +261,8 @@ export class Select {
pill={this.pill}
clearable
onClick={event => event.stopPropagation()}
onSlClear={() => {
onSlClear={event => {
event.stopPropagation();
item.checked = false;
this.syncValueFromItems();
}}
@ -327,6 +338,7 @@ export class Select {
class={{
select: true,
'select--open': this.isOpen,
'select--empty': this.value.length === 0,
'select--focused': this.hasFocus,
'select--disabled': this.disabled,
'select--multiple': this.multiple,
@ -353,11 +365,13 @@ export class Select {
size={this.size}
valid={this.valid}
invalid={this.invalid}
clearable={this.clearable}
required={this.required}
aria-labelledby={this.labelId}
aria-describedby={this.helpTextId}
onSlFocus={this.handleFocus}
onSlBlur={this.handleBlur}
onSlClear={this.handleClear}
onKeyDown={this.handleKeyDown}
>
{this.displayTags.length && (