From bc92981c164700a8d219961bd2d6a546d83b7795 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 28 Aug 2020 17:24:23 -0400 Subject: [PATCH] Fix select validation --- docs/components/form.md | 2 +- src/components/select/select.scss | 5 +++++ src/components/select/select.tsx | 13 +++++++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/components/form.md b/docs/components/form.md index aaab6293..1442e21e 100644 --- a/docs/components/form.md +++ b/docs/components/form.md @@ -86,7 +86,7 @@ To make a field required, use the `required` prop. The form will not be submitte
- + Birds Cats Dogs diff --git a/src/components/select/select.scss b/src/components/select/select.scss index 92af84dc..9c28144f 100644 --- a/src/components/select/select.scss +++ b/src/components/select/select.scss @@ -19,6 +19,11 @@ cursor: pointer; } + // Hide the caret since we use a faux readonly technique to prevent user input + &::part(input) { + caret-color: transparent; + } + span[slot='prefix'] { margin-left: var(--sl-spacing-xx-small); diff --git a/src/components/select/select.tsx b/src/components/select/select.tsx index ea468836..75d0e9b3 100644 --- a/src/components/select/select.tsx +++ b/src/components/select/select.tsx @@ -143,8 +143,7 @@ export class Select { /** Sets a custom validation message. If `message` is not empty, the field will be considered invalid. */ @Method() async setCustomValidity(message: string) { - // this.input.setCustomValidity(message); - // this.invalid = !this.input.checkValidity(); + this.input.setCustomValidity(message); } getItemLabel(item: HTMLSlMenuItemElement) { @@ -186,6 +185,10 @@ export class Select { event.preventDefault(); return; } + + // Make the input "readonly" without using the `readonly` attribute, since that would prevent the browser's + // validation messages from appearing + event.preventDefault(); } handleLabelClick() { @@ -308,7 +311,10 @@ export class Select { ); } - this.displayLabel = ''; + // With `multiple`, the input uses the display label as its value. If no selection is made, we set it to an empty + // string. If items are selected, we use a zero-width space so `required` validation doesn't fail, but nothing is + // drawn in the label either. This is a bit ugly, but it gets the job done. + this.displayLabel = this.value.length === 0 ? '' : '\u200B'; } else { const checkedItem = items.filter(item => item.value === value[0])[0]; this.displayLabel = checkedItem ? this.getItemLabel(checkedItem) : ''; @@ -387,7 +393,6 @@ export class Select { disabled={this.disabled} pill={this.pill} placeholder={this.displayLabel === '' && this.displayTags.length === 0 ? this.placeholder : null} - readonly={true} size={this.size} invalid={this.invalid} clearable={this.clearable}