@solid-design-system/components 1.36.0 → 1.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/es/checkbox-group.js +1 -1
- package/dist/components/es/checkbox.js +1 -1
- package/dist/components/es/form.js +1 -1
- package/dist/components/es/input.js +1 -1
- package/dist/components/es/option.js +1 -1
- package/dist/components/es/radio-group.js +1 -1
- package/dist/components/es/radio.js +1 -1
- package/dist/components/es/select.js +2 -2
- package/dist/components/es/solid-element.js +1 -1
- package/dist/components/es/switch.js +1 -1
- package/dist/components/es/teaser.js +1 -1
- package/dist/components/es/textarea.js +1 -1
- package/dist/components/umd/solid-components.js +18 -18
- package/dist/custom-elements.json +1 -1
- package/dist/package/components/checkbox/checkbox.d.ts +2 -0
- package/dist/package/components/checkbox/checkbox.js +23 -6
- package/dist/package/components/checkbox-group/checkbox-group.js +1 -1
- package/dist/package/components/input/input.d.ts +3 -0
- package/dist/package/components/input/input.js +20 -19
- package/dist/package/components/option/option.js +0 -2
- package/dist/package/components/radio/radio.js +3 -3
- package/dist/package/components/radio-group/radio-group.d.ts +4 -3
- package/dist/package/components/radio-group/radio-group.js +25 -27
- package/dist/package/components/select/select.d.ts +3 -3
- package/dist/package/components/select/select.js +18 -23
- package/dist/package/components/switch/switch.d.ts +2 -0
- package/dist/package/components/switch/switch.js +15 -7
- package/dist/package/components/teaser/teaser.js +5 -1
- package/dist/package/components/textarea/textarea.d.ts +3 -0
- package/dist/package/components/textarea/textarea.js +30 -24
- package/dist/package/internal/form.d.ts +3 -1
- package/dist/package/internal/form.js +38 -10
- package/dist/package/internal/solid-element.d.ts +2 -0
- package/dist/package/styles/tailwind.css.js +1 -1
- package/dist/versioned-components/es/accordion-group.js +1 -1
- package/dist/versioned-components/es/accordion.js +1 -1
- package/dist/versioned-components/es/badge.js +1 -1
- package/dist/versioned-components/es/brandshape.js +1 -1
- package/dist/versioned-components/es/button.js +1 -1
- package/dist/versioned-components/es/carousel-item.js +1 -1
- package/dist/versioned-components/es/carousel.js +3 -3
- package/dist/versioned-components/es/checkbox-group.js +1 -1
- package/dist/versioned-components/es/checkbox.js +1 -1
- package/dist/versioned-components/es/divider.js +1 -1
- package/dist/versioned-components/es/drawer.js +1 -1
- package/dist/versioned-components/es/dropdown.js +1 -1
- package/dist/versioned-components/es/form.js +1 -1
- package/dist/versioned-components/es/header.js +1 -1
- package/dist/versioned-components/es/icon.js +1 -1
- package/dist/versioned-components/es/include.js +1 -1
- package/dist/versioned-components/es/input.js +1 -1
- package/dist/versioned-components/es/link.js +1 -1
- package/dist/versioned-components/es/navigation-item.js +1 -1
- package/dist/versioned-components/es/notification.js +1 -1
- package/dist/versioned-components/es/option.js +1 -1
- package/dist/versioned-components/es/popup.js +1 -1
- package/dist/versioned-components/es/radio-button.js +1 -1
- package/dist/versioned-components/es/radio-group.js +1 -1
- package/dist/versioned-components/es/radio.js +1 -1
- package/dist/versioned-components/es/select.js +2 -2
- package/dist/versioned-components/es/solid-element.js +1 -1
- package/dist/versioned-components/es/spinner.js +1 -1
- package/dist/versioned-components/es/switch.js +1 -1
- package/dist/versioned-components/es/tag.js +1 -1
- package/dist/versioned-components/es/teaser.js +1 -1
- package/dist/versioned-components/es/textarea.js +1 -1
- package/dist/versioned-components/es/tooltip.js +2 -2
- package/dist/versioned-components/es/video.js +1 -1
- package/dist/versioned-package/_components/button-group/button-group.d.ts +1 -1
- package/dist/versioned-package/_components/button-group/button-group.js +11 -11
- package/dist/versioned-package/components/accordion/accordion.d.ts +1 -1
- package/dist/versioned-package/components/accordion/accordion.js +2 -2
- package/dist/versioned-package/components/accordion-group/accordion-group.d.ts +1 -1
- package/dist/versioned-package/components/accordion-group/accordion-group.js +3 -3
- package/dist/versioned-package/components/badge/badge.d.ts +1 -1
- package/dist/versioned-package/components/badge/badge.js +1 -1
- package/dist/versioned-package/components/brandshape/brandshape.d.ts +1 -1
- package/dist/versioned-package/components/brandshape/brandshape.js +1 -1
- package/dist/versioned-package/components/button/button.d.ts +1 -1
- package/dist/versioned-package/components/button/button.js +4 -4
- package/dist/versioned-package/components/carousel/carousel.d.ts +1 -1
- package/dist/versioned-package/components/carousel/carousel.js +6 -6
- package/dist/versioned-package/components/carousel-item/carousel-item.d.ts +1 -1
- package/dist/versioned-package/components/carousel-item/carousel-item.js +1 -1
- package/dist/versioned-package/components/checkbox/checkbox.d.ts +3 -1
- package/dist/versioned-package/components/checkbox/checkbox.js +27 -10
- package/dist/versioned-package/components/checkbox-group/checkbox-group.d.ts +1 -1
- package/dist/versioned-package/components/checkbox-group/checkbox-group.js +6 -6
- package/dist/versioned-package/components/divider/divider.d.ts +1 -1
- package/dist/versioned-package/components/divider/divider.js +2 -2
- package/dist/versioned-package/components/drawer/drawer.d.ts +1 -1
- package/dist/versioned-package/components/drawer/drawer.js +2 -2
- package/dist/versioned-package/components/dropdown/dropdown.d.ts +1 -1
- package/dist/versioned-package/components/dropdown/dropdown.js +8 -8
- package/dist/versioned-package/components/header/header.d.ts +1 -1
- package/dist/versioned-package/components/header/header.js +4 -4
- package/dist/versioned-package/components/icon/icon.d.ts +1 -1
- package/dist/versioned-package/components/icon/icon.js +1 -1
- package/dist/versioned-package/components/include/include.d.ts +1 -1
- package/dist/versioned-package/components/include/include.js +1 -1
- package/dist/versioned-package/components/input/input.d.ts +4 -1
- package/dist/versioned-package/components/input/input.js +23 -22
- package/dist/versioned-package/components/link/link.d.ts +1 -1
- package/dist/versioned-package/components/link/link.js +2 -2
- package/dist/versioned-package/components/navigation-item/navigation-item.d.ts +1 -1
- package/dist/versioned-package/components/navigation-item/navigation-item.js +3 -3
- package/dist/versioned-package/components/notification/notification.d.ts +1 -1
- package/dist/versioned-package/components/notification/notification.js +5 -5
- package/dist/versioned-package/components/option/option.d.ts +1 -1
- package/dist/versioned-package/components/option/option.js +2 -4
- package/dist/versioned-package/components/popup/popup.d.ts +1 -1
- package/dist/versioned-package/components/popup/popup.js +1 -1
- package/dist/versioned-package/components/radio/radio.d.ts +1 -1
- package/dist/versioned-package/components/radio/radio.js +5 -5
- package/dist/versioned-package/components/radio-button/radio-button.d.ts +1 -1
- package/dist/versioned-package/components/radio-button/radio-button.js +2 -2
- package/dist/versioned-package/components/radio-group/radio-group.d.ts +6 -5
- package/dist/versioned-package/components/radio-group/radio-group.js +38 -40
- package/dist/versioned-package/components/select/select.d.ts +7 -7
- package/dist/versioned-package/components/select/select.js +44 -49
- package/dist/versioned-package/components/spinner/spinner.d.ts +1 -1
- package/dist/versioned-package/components/spinner/spinner.js +1 -1
- package/dist/versioned-package/components/switch/switch.d.ts +3 -1
- package/dist/versioned-package/components/switch/switch.js +17 -9
- package/dist/versioned-package/components/tag/tag.d.ts +1 -1
- package/dist/versioned-package/components/tag/tag.js +2 -2
- package/dist/versioned-package/components/teaser/teaser.js +6 -2
- package/dist/versioned-package/components/textarea/textarea.d.ts +4 -1
- package/dist/versioned-package/components/textarea/textarea.js +32 -26
- package/dist/versioned-package/components/tooltip/tooltip.d.ts +1 -1
- package/dist/versioned-package/components/tooltip/tooltip.js +5 -5
- package/dist/versioned-package/components/video/video.d.ts +1 -1
- package/dist/versioned-package/components/video/video.js +2 -2
- package/dist/versioned-package/internal/form.d.ts +3 -1
- package/dist/versioned-package/internal/form.js +40 -12
- package/dist/versioned-package/internal/solid-element.d.ts +2 -0
- package/dist/versioned-package/styles/tailwind.css.js +1 -1
- package/dist/versioned-styles/solid-styles.css +1 -1
- package/dist/vscode.html-custom-data.json +44 -34
- package/dist/web-types.json +78 -18
- package/package.json +1 -1
- package/dist/components/es/form-control.styles.js +0 -1
- package/dist/package/styles/form-control.styles.d.ts +0 -2
- package/dist/package/styles/form-control.styles.js +0 -5
- package/dist/versioned-components/es/form-control.styles.js +0 -1
- package/dist/versioned-package/styles/form-control.styles.d.ts +0 -2
- package/dist/versioned-package/styles/form-control.styles.js +0 -5
|
@@ -4,6 +4,7 @@ import type { SolidFormControl } from '../../internal/solid-element';
|
|
|
4
4
|
export default class SdCheckbox extends SolidElement implements SolidFormControl {
|
|
5
5
|
private readonly formControlController;
|
|
6
6
|
input: HTMLInputElement;
|
|
7
|
+
invalidMessage: HTMLDivElement;
|
|
7
8
|
title: string;
|
|
8
9
|
name: string;
|
|
9
10
|
value: string;
|
|
@@ -14,6 +15,7 @@ export default class SdCheckbox extends SolidElement implements SolidFormControl
|
|
|
14
15
|
defaultChecked: boolean;
|
|
15
16
|
form: string;
|
|
16
17
|
required: boolean;
|
|
18
|
+
showInvalidStyle: boolean;
|
|
17
19
|
get validity(): ValidityState;
|
|
18
20
|
firstUpdated(): void;
|
|
19
21
|
private handleClick;
|
|
@@ -5,7 +5,7 @@ import { defaultValue } from "../../internal/default-value.js";
|
|
|
5
5
|
import { FormControlController } from "../../internal/form.js";
|
|
6
6
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
7
7
|
import { live } from "lit/directives/live.js";
|
|
8
|
-
import { query, property } from "lit/decorators.js";
|
|
8
|
+
import { query, property, state } from "lit/decorators.js";
|
|
9
9
|
import { watch } from "../../internal/watch.js";
|
|
10
10
|
import cx from "classix";
|
|
11
11
|
import SolidElement from "../../internal/solid-element.js";
|
|
@@ -37,6 +37,7 @@ let SdCheckbox = class extends SolidElement {
|
|
|
37
37
|
this.defaultChecked = false;
|
|
38
38
|
this.form = "";
|
|
39
39
|
this.required = false;
|
|
40
|
+
this.showInvalidStyle = false;
|
|
40
41
|
}
|
|
41
42
|
/** Gets the validity state object */
|
|
42
43
|
get validity() {
|
|
@@ -59,6 +60,7 @@ let SdCheckbox = class extends SolidElement {
|
|
|
59
60
|
handleInvalid(event) {
|
|
60
61
|
this.formControlController.setValidity(false);
|
|
61
62
|
this.formControlController.emitInvalidEvent(event);
|
|
63
|
+
this.invalidMessage.textContent = event.target.validationMessage;
|
|
62
64
|
}
|
|
63
65
|
handleFocus() {
|
|
64
66
|
this.emit("sd-focus");
|
|
@@ -105,6 +107,7 @@ let SdCheckbox = class extends SolidElement {
|
|
|
105
107
|
this.formControlController.updateValidity();
|
|
106
108
|
}
|
|
107
109
|
render() {
|
|
110
|
+
const checkboxState = this.disabled && this.indeterminate ? "disabledIndeterminate" : this.disabled && this.checked ? "disabledChecked" : this.disabled ? "disabled" : this.showInvalidStyle && this.indeterminate ? "invalidIndeterminate" : this.showInvalidStyle ? "invalid" : this.checked || this.indeterminate ? "filled" : "default";
|
|
108
111
|
return html`<label part="base" class="${cx(
|
|
109
112
|
"sd-checkbox group flex items-start text-base leading-normal text-black cursor-pointer",
|
|
110
113
|
this.disabled && "hover:cursor-not-allowed",
|
|
@@ -121,20 +124,31 @@ let SdCheckbox = class extends SolidElement {
|
|
|
121
124
|
sm: "mt-[2px]",
|
|
122
125
|
lg: "mt-[3px]"
|
|
123
126
|
}[this.size],
|
|
124
|
-
|
|
127
|
+
{
|
|
128
|
+
disabledIndeterminate: "border-neutral-500 bg-neutral-500",
|
|
129
|
+
disabledChecked: "border-neutral-500 bg-neutral-500",
|
|
130
|
+
disabled: "border-neutral-500",
|
|
131
|
+
invalidIndeterminate: "border-error bg-error group-hover:bg-error-400",
|
|
132
|
+
invalid: "border-error group-hover:bg-neutral-200",
|
|
133
|
+
filled: "border-accent hover:border-accent-550 group-hover:border-accent-550 bg-accent group-hover:bg-accent-550",
|
|
134
|
+
default: "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200 bg-white"
|
|
135
|
+
}[checkboxState]
|
|
125
136
|
)}">${this.checked ? html`<sd-icon part="checked-icon" class="text-white w-3 h-3" library="system" name="status-hook"></sd-icon>` : ""} ${!this.checked && this.indeterminate ? html`<sd-icon part="indeterminate-icon" class="text-white w-3 h-3" library="system" name="status-minus"></sd-icon>` : ""} </span><span part="label" id="label" class="${cx(
|
|
126
|
-
"select-none inline-block ml-2
|
|
127
|
-
this.disabled
|
|
128
|
-
)}"><slot></slot></span></label
|
|
137
|
+
"select-none inline-block ml-2",
|
|
138
|
+
this.disabled ? "text-neutral-500" : this.showInvalidStyle ? "text-error" : "text-black"
|
|
139
|
+
)}"><slot></slot></span></label> ${this.formControlController.renderInvalidMessage()}`;
|
|
129
140
|
}
|
|
130
141
|
};
|
|
131
142
|
SdCheckbox.styles = [
|
|
132
143
|
SolidElement.styles,
|
|
133
|
-
css`:host{display:block}:host(:focus-visible){outline-width:0}:host([required]) #label::after{content:' *'}
|
|
144
|
+
css`:host{display:block}:host(:focus-visible){outline-width:0}:host([required]) #label::after{content:' *'}`
|
|
134
145
|
];
|
|
135
146
|
__decorateClass([
|
|
136
147
|
query('input[type="checkbox"]')
|
|
137
148
|
], SdCheckbox.prototype, "input", 2);
|
|
149
|
+
__decorateClass([
|
|
150
|
+
query("#invalid-message")
|
|
151
|
+
], SdCheckbox.prototype, "invalidMessage", 2);
|
|
138
152
|
__decorateClass([
|
|
139
153
|
property()
|
|
140
154
|
], SdCheckbox.prototype, "title", 2);
|
|
@@ -165,6 +179,9 @@ __decorateClass([
|
|
|
165
179
|
__decorateClass([
|
|
166
180
|
property({ type: Boolean, reflect: true })
|
|
167
181
|
], SdCheckbox.prototype, "required", 2);
|
|
182
|
+
__decorateClass([
|
|
183
|
+
state()
|
|
184
|
+
], SdCheckbox.prototype, "showInvalidStyle", 2);
|
|
168
185
|
__decorateClass([
|
|
169
186
|
watch("disabled", { waitUntilFirstUpdate: true })
|
|
170
187
|
], SdCheckbox.prototype, "handleDisabledChange", 1);
|
|
@@ -66,7 +66,7 @@ let SdCheckboxGroup = class extends SolidElement {
|
|
|
66
66
|
sm: "text-sm",
|
|
67
67
|
lg: "text-base"
|
|
68
68
|
}[this.size]
|
|
69
|
-
)}" role="group" aria-labelledby="label"><label part="form-control-label" id="label" class="${cx("mb-2 p-0 font-bold leading-normal text-black", hasLabel ? "flex" : "hidden")}" aria-hidden="${
|
|
69
|
+
)}" role="group" aria-labelledby="label"><label part="form-control-label" id="label" class="${cx("mb-2 p-0 font-bold leading-normal text-black", hasLabel ? "flex" : "hidden")}" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
|
|
70
70
|
{
|
|
71
71
|
vertical: "flex flex-col",
|
|
72
72
|
horizontal: "flex flex-row"
|
|
@@ -7,7 +7,10 @@ export default class SdInput extends SolidElement implements SolidFormControl {
|
|
|
7
7
|
private readonly hasSlotController;
|
|
8
8
|
private readonly localize;
|
|
9
9
|
input: HTMLInputElement;
|
|
10
|
+
invalidMessage: HTMLDivElement;
|
|
10
11
|
private hasFocus;
|
|
12
|
+
showValidStyle: boolean;
|
|
13
|
+
showInvalidStyle: boolean;
|
|
11
14
|
type: 'date' | 'datetime-local' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'time' | 'url';
|
|
12
15
|
size: 'lg' | 'md' | 'sm';
|
|
13
16
|
inputmode: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
|
|
@@ -12,7 +12,6 @@ import { query, state, property } from "lit/decorators.js";
|
|
|
12
12
|
import { watch } from "../../internal/watch.js";
|
|
13
13
|
import componentStyles from "../../styles/component.styles.js";
|
|
14
14
|
import cx from "classix";
|
|
15
|
-
import formControlStyles from "../../styles/form-control.styles.js";
|
|
16
15
|
import SolidElement from "../../internal/solid-element.js";
|
|
17
16
|
var __defProp = Object.defineProperty;
|
|
18
17
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -42,6 +41,8 @@ let SdInput = class extends SolidElement {
|
|
|
42
41
|
);
|
|
43
42
|
this.localize = new LocalizeController(this);
|
|
44
43
|
this.hasFocus = false;
|
|
44
|
+
this.showValidStyle = false;
|
|
45
|
+
this.showInvalidStyle = false;
|
|
45
46
|
this.type = "text";
|
|
46
47
|
this.size = "lg";
|
|
47
48
|
this.value = "";
|
|
@@ -115,8 +116,10 @@ let SdInput = class extends SolidElement {
|
|
|
115
116
|
this.formControlController.updateValidity();
|
|
116
117
|
this.emit("sd-input");
|
|
117
118
|
}
|
|
118
|
-
handleInvalid() {
|
|
119
|
+
handleInvalid(event) {
|
|
119
120
|
this.formControlController.setValidity(false);
|
|
121
|
+
this.formControlController.emitInvalidEvent(event);
|
|
122
|
+
this.invalidMessage.textContent = event.target.validationMessage;
|
|
120
123
|
}
|
|
121
124
|
handleKeyDown(event) {
|
|
122
125
|
const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
|
@@ -210,10 +213,7 @@ let SdInput = class extends SolidElement {
|
|
|
210
213
|
const hasLabel = this.label ? true : !!slots["label"];
|
|
211
214
|
const hasHelpText = this.helpText ? true : !!slots["helpText"];
|
|
212
215
|
const hasClearIcon = this.clearable && !this.readonly && (typeof this.value === "number" || this.value.length > 0);
|
|
213
|
-
const
|
|
214
|
-
const isInvalid = hasValidationAttr && !this.checkValidity();
|
|
215
|
-
const isValid = hasValidationAttr && this.checkValidity();
|
|
216
|
-
const inputState = this.disabled ? "disabled" : this.readonly ? "readonly" : this.hasFocus && isInvalid ? "activeInvalid" : this.hasFocus && isValid ? "activeValid" : this.hasFocus ? "active" : isInvalid ? "invalid" : isValid ? "valid" : "default";
|
|
216
|
+
const inputState = this.disabled ? "disabled" : this.readonly ? "readonly" : this.hasFocus && this.showInvalidStyle ? "activeInvalid" : this.hasFocus && this.showValidStyle ? "activeValid" : this.hasFocus ? "active" : this.showInvalidStyle ? "invalid" : this.showValidStyle ? "valid" : "default";
|
|
217
217
|
const textSize = this.size === "sm" ? "text-sm" : "text-base";
|
|
218
218
|
const textColor = {
|
|
219
219
|
disabled: "text-neutral-500",
|
|
@@ -242,40 +242,41 @@ let SdInput = class extends SolidElement {
|
|
|
242
242
|
md: "text-lg",
|
|
243
243
|
lg: "text-xl"
|
|
244
244
|
}[this.size];
|
|
245
|
-
return html`<div part="form-control" class="${cx(
|
|
246
|
-
"
|
|
247
|
-
borderColor
|
|
248
|
-
)}"></div><div part="base" class="${cx(
|
|
249
|
-
"px-4 flex flex-row items-center rounded-default transition-all",
|
|
245
|
+
return html`<div part="form-control" class="${cx(this.disabled && "pointer-events-none")}"><label part="form-control-label" id="label" class="${cx("mb-2", hasLabel ? "inline-block" : "hidden", textSize)}" for="input" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="relative w-full"><div part="border" class="${cx("absolute w-full h-full pointer-events-none border rounded-default", borderColor)}"></div><div part="base" class="${cx(
|
|
246
|
+
"px-4 flex flex-row items-center rounded-default transition-all bg-white",
|
|
250
247
|
// Vertical Padding
|
|
251
248
|
this.size === "lg" ? "py-2" : "py-1",
|
|
252
249
|
// States
|
|
253
250
|
!this.disabled && !this.readonly ? "hover:bg-neutral-200" : "",
|
|
254
251
|
this.readonly && "bg-neutral-100",
|
|
255
|
-
|
|
256
|
-
textColor,
|
|
257
|
-
!this.value && "input--empty",
|
|
258
|
-
this.noSpinButtons && "input--no-spin-buttons",
|
|
259
|
-
isFirefox && "input--is-firefox"
|
|
252
|
+
textColor
|
|
260
253
|
)}">${slots["left"] ? html`<slot name="left" part="left" class="${cx("inline-flex", this.size === "sm" ? "mr-1" : "mr-2", iconColor, iconSize)}"></slot>` : ""} <input part="input" id="input" class="${cx(
|
|
261
254
|
"min-w-0 flex-grow focus:outline-none bg-transparent placeholder-neutral-700",
|
|
262
255
|
this.size === "sm" ? "h-6" : "h-8",
|
|
263
256
|
textSize
|
|
264
|
-
)}" type="${this.type === "password" && this.passwordVisible ? "text" : this.type}" title="${this.title}" name="${ifDefined(this.name)}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" ?required="${this.required}" placeholder="${ifDefined(this.placeholder)}" minlength="${ifDefined(this.minlength)}" maxlength="${ifDefined(this.maxlength)}" min="${ifDefined(this.min)}" max="${ifDefined(this.max)}" step="${ifDefined(this.step)}" .value="${live(this.value)}" autocapitalize="${ifDefined(this.type === "password" ? "off" : this.autocapitalize)}" autocomplete="${ifDefined(this.type === "password" ? "off" : this.autocomplete)}" autocorrect="${ifDefined(this.type === "password" ? "off" : this.autocorrect)}" ?autofocus="${this.autofocus}" spellcheck="${this.spellcheck}" pattern="${ifDefined(this.pattern)}" enterkeyhint="${ifDefined(this.enterkeyhint)}" inputmode="${ifDefined(this.inputmode)}" aria-describedby="help-text" @change="${this.handleChange}" @input="${this.handleInput}" @invalid="${this.handleInvalid}" @keydown="${this.handleKeyDown}" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("flex justify-center ", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.passwordToggle && this.type === "password" ? html`<button aria-label="${this.localize.term(this.passwordVisible ? "hidePassword" : "showPassword")}" part="password-toggle-button" class="flex items-center" type="button" @click="${this.handlePasswordToggle}" tabindex="-1">${this.passwordVisible ? html`<slot name="show-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye"></sd-icon></slot>` : html`<slot name="hide-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye-crossed-out"></sd-icon></slot>`}</button>` : ""} ${(this.type === "date" || this.type === "datetime-local") && !isFirefox ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="calendar"></sd-icon>` : ""} ${this.type === "time" ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="clock"></sd-icon>` : ""} ${
|
|
257
|
+
)}" type="${this.type === "password" && this.passwordVisible ? "text" : this.type}" title="${this.title}" name="${ifDefined(this.name)}" ?disabled="${this.disabled}" ?readonly="${this.readonly}" ?required="${this.required}" placeholder="${ifDefined(this.placeholder)}" minlength="${ifDefined(this.minlength)}" maxlength="${ifDefined(this.maxlength)}" min="${ifDefined(this.min)}" max="${ifDefined(this.max)}" step="${ifDefined(this.step)}" .value="${live(this.value)}" autocapitalize="${ifDefined(this.type === "password" ? "off" : this.autocapitalize)}" autocomplete="${ifDefined(this.type === "password" ? "off" : this.autocomplete)}" autocorrect="${ifDefined(this.type === "password" ? "off" : this.autocorrect)}" ?autofocus="${this.autofocus}" spellcheck="${this.spellcheck}" pattern="${ifDefined(this.pattern)}" enterkeyhint="${ifDefined(this.enterkeyhint)}" inputmode="${ifDefined(this.inputmode)}" aria-describedby="help-text" @change="${this.handleChange}" @input="${this.handleInput}" @invalid="${this.handleInvalid}" @keydown="${this.handleKeyDown}" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("flex justify-center ", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.passwordToggle && this.type === "password" ? html`<button aria-label="${this.localize.term(this.passwordVisible ? "hidePassword" : "showPassword")}" part="password-toggle-button" class="flex items-center" type="button" @click="${this.handlePasswordToggle}" tabindex="-1">${this.passwordVisible ? html`<slot name="show-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye"></sd-icon></slot>` : html`<slot name="hide-password-icon"><sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="eye-crossed-out"></sd-icon></slot>`}</button>` : ""} ${(this.type === "date" || this.type === "datetime-local") && !isFirefox ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="calendar"></sd-icon>` : ""} ${this.type === "time" ? html`<sd-icon class="${cx(iconColor, iconMarginLeft, iconSize)}" library="system" name="clock"></sd-icon>` : ""} ${this.showInvalidStyle ? html`<sd-icon class="${cx("text-error", iconMarginLeft, iconSize)}" library="system" name="risk"></sd-icon>` : ""} ${this.showValidStyle ? html`<sd-icon class="${cx("text-success", iconMarginLeft, iconSize)}" library="system" name="confirm"></sd-icon>` : ""} ${slots["right"] ? html`<slot name="right" part="right" class="${cx("inline-flex", iconColor, iconMarginLeft, iconSize)}"></slot>` : ""}</div></div><slot name="help-text" part="form-control-help-text" id="help-text" class="${cx("text-sm text-neutral-700", hasHelpText ? "block" : "hidden")}" aria-hidden="${!hasHelpText}">${this.helpText}</slot></div>${this.formControlController.renderInvalidMessage()}`;
|
|
265
258
|
}
|
|
266
259
|
};
|
|
267
260
|
SdInput.styles = [
|
|
268
261
|
componentStyles,
|
|
269
|
-
formControlStyles,
|
|
270
262
|
SolidElement.styles,
|
|
271
|
-
css`:host{position:relative;box-sizing:border-box;display:inline-block;width:100%;text-align:left}:host([vertical]){display:block}:host([required]) #label
|
|
263
|
+
css`:host{position:relative;box-sizing:border-box;display:inline-block;width:100%;text-align:left}:host([vertical]){display:block}:host([required]) #label::after{content:' *'}details summary::-webkit-details-marker{display:none}input::-webkit-inner-spin-button,input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}input[type=time]::-webkit-calendar-picker-indicator{background:0 0}details summary::-webkit-details-marker,input[type=date]::-webkit-calendar-picker-indicator,input[type=datetime-local]::-webkit-calendar-picker-indicator,input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-results-button,input[type=search]::-webkit-search-results-decoration{display:none}`
|
|
272
264
|
];
|
|
273
265
|
__decorateClass([
|
|
274
266
|
query("#input")
|
|
275
267
|
], SdInput.prototype, "input", 2);
|
|
268
|
+
__decorateClass([
|
|
269
|
+
query("#invalid-message")
|
|
270
|
+
], SdInput.prototype, "invalidMessage", 2);
|
|
276
271
|
__decorateClass([
|
|
277
272
|
state()
|
|
278
273
|
], SdInput.prototype, "hasFocus", 2);
|
|
274
|
+
__decorateClass([
|
|
275
|
+
state()
|
|
276
|
+
], SdInput.prototype, "showValidStyle", 2);
|
|
277
|
+
__decorateClass([
|
|
278
|
+
state()
|
|
279
|
+
], SdInput.prototype, "showInvalidStyle", 2);
|
|
279
280
|
__decorateClass([
|
|
280
281
|
property({ reflect: true })
|
|
281
282
|
], SdInput.prototype, "type", 2);
|
|
@@ -7,7 +7,6 @@ import { query, state, property } from "lit/decorators.js";
|
|
|
7
7
|
import { watch } from "../../internal/watch.js";
|
|
8
8
|
import componentStyles from "../../styles/component.styles.js";
|
|
9
9
|
import cx from "classix";
|
|
10
|
-
import formControlStyles from "../../styles/form-control.styles.js";
|
|
11
10
|
import SolidElement from "../../internal/solid-element.js";
|
|
12
11
|
var __defProp = Object.defineProperty;
|
|
13
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -100,7 +99,6 @@ let SdOption = class extends SolidElement {
|
|
|
100
99
|
};
|
|
101
100
|
SdOption.styles = [
|
|
102
101
|
componentStyles,
|
|
103
|
-
formControlStyles,
|
|
104
102
|
SolidElement.styles,
|
|
105
103
|
css`:host{position:relative;display:block;width:100%;outline:2px solid transparent!important;outline-offset:2px!important}`
|
|
106
104
|
];
|
|
@@ -82,13 +82,13 @@ let SdRadio = class extends SolidElement {
|
|
|
82
82
|
}[this.size]
|
|
83
83
|
)}"><span part="${`${this.checked ? "control--checked" : "control--unchecked"}`}" class="${cx(
|
|
84
84
|
"flex-initial shrink-0 relative inline-flex items-center justify-center border rounded-full bg-white h-4 w-4",
|
|
85
|
-
this.disabled
|
|
85
|
+
this.disabled ? "border-neutral-500" : this.invalid ? "border-error hover:border-error-400 group-hover:border-error-400" : this.checked ? "border-accent hover:border-accent-550 group-hover:border-accent-550" : "border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200"
|
|
86
86
|
)}">${this.checked ? html`<span part="checked" class="${cx(
|
|
87
87
|
"rounded-full inline-flex text-white border bg-accent h-2.5 w-2.5",
|
|
88
|
-
this.disabled
|
|
88
|
+
this.disabled ? "bg-neutral-500" : this.invalid ? "bg-error hover:bg-error-400 group-hover:bg-error-400" : this.checked ? "bg-accent hover:bg-accent-550 group-hover:bg-accent-550" : "bg-neutral-800"
|
|
89
89
|
)}"></span>` : ""}</span><slot part="label" class="${cx(
|
|
90
90
|
"ml-2 select-none inline-block",
|
|
91
|
-
this.disabled
|
|
91
|
+
this.disabled ? "text-neutral-500" : this.invalid ? "text-error" : "text-black"
|
|
92
92
|
)}"></slot></span>`;
|
|
93
93
|
}
|
|
94
94
|
};
|
|
@@ -12,11 +12,12 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
|
|
|
12
12
|
private validationTimeout;
|
|
13
13
|
defaultSlot: HTMLSlotElement;
|
|
14
14
|
validationInput: HTMLInputElement;
|
|
15
|
+
invalidMessage: HTMLDivElement;
|
|
15
16
|
private hasButtonGroup;
|
|
16
17
|
defaultValue: string;
|
|
17
|
-
|
|
18
|
-
private errorText;
|
|
18
|
+
showInvalidStyle: boolean;
|
|
19
19
|
label: string;
|
|
20
|
+
boldLabel: boolean;
|
|
20
21
|
name: string;
|
|
21
22
|
value: string;
|
|
22
23
|
size: 'lg' | 'sm';
|
|
@@ -30,7 +31,7 @@ export default class SdRadioGroup extends SolidElement implements SolidFormContr
|
|
|
30
31
|
private getAllRadios;
|
|
31
32
|
private handleRadioClick;
|
|
32
33
|
private handleKeyDown;
|
|
33
|
-
|
|
34
|
+
focus(): void;
|
|
34
35
|
private handleInvalid;
|
|
35
36
|
private syncRadioElements;
|
|
36
37
|
private syncRadios;
|
|
@@ -7,6 +7,7 @@ import { watch } from "../../internal/watch.js";
|
|
|
7
7
|
import componentStyles from "../../styles/component.styles.js";
|
|
8
8
|
import cx from "classix";
|
|
9
9
|
import SdButtonGroup from "../../_components/button-group/button-group.js";
|
|
10
|
+
import SdRadio from "../radio/radio.js";
|
|
10
11
|
import SolidElement from "../../internal/solid-element.js";
|
|
11
12
|
var __defProp = Object.defineProperty;
|
|
12
13
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -27,9 +28,9 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
27
28
|
this.customValidityMessage = "";
|
|
28
29
|
this.hasButtonGroup = false;
|
|
29
30
|
this.defaultValue = "";
|
|
30
|
-
this.
|
|
31
|
-
this.errorText = "";
|
|
31
|
+
this.showInvalidStyle = false;
|
|
32
32
|
this.label = "";
|
|
33
|
+
this.boldLabel = false;
|
|
33
34
|
this.name = "option";
|
|
34
35
|
this.value = "";
|
|
35
36
|
this.size = "lg";
|
|
@@ -42,13 +43,10 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
42
43
|
const isRequiredAndEmpty = this.required && !this.value;
|
|
43
44
|
const hasCustomValidityMessage = this.customValidityMessage !== "";
|
|
44
45
|
if (hasCustomValidityMessage) {
|
|
45
|
-
this.invalid = true;
|
|
46
46
|
return customErrorValidityState;
|
|
47
47
|
} else if (isRequiredAndEmpty) {
|
|
48
|
-
this.invalid = true;
|
|
49
48
|
return valueMissingValidityState;
|
|
50
49
|
}
|
|
51
|
-
this.invalid = false;
|
|
52
50
|
return validValidityState;
|
|
53
51
|
}
|
|
54
52
|
/** Gets the validation message */
|
|
@@ -56,10 +54,8 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
56
54
|
const isRequiredAndEmpty = this.required && !this.value;
|
|
57
55
|
const hasCustomValidityMessage = this.customValidityMessage !== "";
|
|
58
56
|
if (hasCustomValidityMessage) {
|
|
59
|
-
console.log("this.customValidityMessage", this.customValidityMessage);
|
|
60
57
|
return this.customValidityMessage;
|
|
61
58
|
} else if (isRequiredAndEmpty) {
|
|
62
|
-
console.log("this.validationInput.validationMessage", this.validationInput);
|
|
63
59
|
return this.validationInput.validationMessage;
|
|
64
60
|
}
|
|
65
61
|
return "";
|
|
@@ -123,7 +119,8 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
123
119
|
}
|
|
124
120
|
event.preventDefault();
|
|
125
121
|
}
|
|
126
|
-
|
|
122
|
+
/** Move focus to the checked radio (or the first one if none are checked) */
|
|
123
|
+
focus() {
|
|
127
124
|
const radios = this.getAllRadios();
|
|
128
125
|
const checked = radios.find((radio) => radio.checked);
|
|
129
126
|
const radioToFocus = checked || radios[0];
|
|
@@ -134,6 +131,7 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
134
131
|
handleInvalid(event) {
|
|
135
132
|
this.formControlController.setValidity(false);
|
|
136
133
|
this.formControlController.emitInvalidEvent(event);
|
|
134
|
+
this.invalidMessage.textContent = event.target.validationMessage;
|
|
137
135
|
}
|
|
138
136
|
async syncRadioElements() {
|
|
139
137
|
var _a, _b;
|
|
@@ -144,8 +142,8 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
144
142
|
await radio.updateComplete;
|
|
145
143
|
radio.checked = radio.value === this.value;
|
|
146
144
|
radio.size = this.size;
|
|
147
|
-
if (
|
|
148
|
-
radio.invalid = this.
|
|
145
|
+
if (radio instanceof SdRadio) {
|
|
146
|
+
radio.invalid = this.showInvalidStyle;
|
|
149
147
|
}
|
|
150
148
|
})
|
|
151
149
|
);
|
|
@@ -215,10 +213,8 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
215
213
|
return this.formControlController.getForm();
|
|
216
214
|
}
|
|
217
215
|
/** Checks for validity and shows the browser's validation message if the control is invalid. */
|
|
218
|
-
// TODO: https://github.com/solid-design-system/solid/issues/501
|
|
219
216
|
reportValidity() {
|
|
220
217
|
const isValid = this.validity.valid;
|
|
221
|
-
this.errorText = this.customValidityMessage || isValid ? "" : this.validationInput.validationMessage;
|
|
222
218
|
this.formControlController.setValidity(isValid);
|
|
223
219
|
this.validationInput.hidden = true;
|
|
224
220
|
clearTimeout(this.validationTimeout);
|
|
@@ -232,39 +228,38 @@ let SdRadioGroup = class extends SolidElement {
|
|
|
232
228
|
/** Sets a custom validation message. Pass an empty string to restore validity. */
|
|
233
229
|
setCustomValidity(message = "") {
|
|
234
230
|
this.customValidityMessage = message;
|
|
235
|
-
this.errorText = message;
|
|
236
231
|
this.validationInput.setCustomValidity(message);
|
|
237
232
|
this.formControlController.updateValidity();
|
|
238
233
|
}
|
|
239
234
|
render() {
|
|
240
235
|
const hasLabelSlot = this.hasSlotController.test("label");
|
|
241
|
-
const hasErrorTextSlot = this.hasSlotController.test("error-text");
|
|
242
236
|
const hasLabel = this.label ? true : !!hasLabelSlot;
|
|
243
|
-
const hasErrorText = this.errorText ? true : !!hasErrorTextSlot;
|
|
244
237
|
const defaultSlot = html`<slot @slotchange="${this.syncRadios}" @click="${this.handleRadioClick}" @keydown="${this.handleKeyDown}"></slot>`;
|
|
245
238
|
return html`<fieldset part="form-control" class="${cx(
|
|
246
|
-
"border-0 p-0 m-0",
|
|
247
|
-
hasErrorText && "text-error",
|
|
239
|
+
"border-0 p-0 m-0 flex flex-col",
|
|
248
240
|
{
|
|
249
241
|
/* sizes, fonts */
|
|
250
242
|
sm: "text-sm",
|
|
251
243
|
lg: "text-base"
|
|
252
244
|
}[this.size]
|
|
253
|
-
)}" role="radiogroup" aria-labelledby="label" aria-errormessage="error-text"><label part="form-control-label" id="label" class="${cx(
|
|
254
|
-
"
|
|
255
|
-
|
|
245
|
+
)}" role="radiogroup" aria-labelledby="label" aria-errormessage="error-text"><label part="form-control-label" id="label" class="${cx(
|
|
246
|
+
"mb-2 p-0 leading-normal text-black text-left",
|
|
247
|
+
!hasLabel && "hidden",
|
|
248
|
+
this.boldLabel && "font-bold"
|
|
249
|
+
)}" @click="${this.focus}" aria-hidden="${hasLabel ? "false" : "true"}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
|
|
250
|
+
"flex",
|
|
256
251
|
{
|
|
257
252
|
vertical: "flex-col",
|
|
258
253
|
horizontal: "flex-row"
|
|
259
254
|
}[this.orientation]
|
|
260
|
-
)}"><div class="sr-only"><
|
|
255
|
+
)}"><div class="sr-only"><label><input id="validation-input" type="text" ?required="${this.required}" tabindex="-1" hidden @invalid="${this.handleInvalid}"></label></div>${this.hasButtonGroup ? html`<sd-button-group part="button-group" exportparts="base:button-group__base" role="presentation">${defaultSlot}</sd-button-group>` : defaultSlot}</div></fieldset>${this.formControlController.renderInvalidMessage()}`;
|
|
261
256
|
}
|
|
262
257
|
};
|
|
263
258
|
SdRadioGroup.dependencies = { "sd-button-group": SdButtonGroup };
|
|
264
259
|
SdRadioGroup.styles = [
|
|
265
260
|
componentStyles,
|
|
266
261
|
SolidElement.styles,
|
|
267
|
-
css`:host{display:block}:host([orientation=vertical]) ::slotted(sd-radio){margin-bottom:var(--sd-spacing-2,.5rem);display:flex}:host([orientation=vertical]) ::slotted(sd-radio:last-of-type){margin-bottom:var(--sd-spacing-0,0)}:host([orientation=horizontal]) ::slotted(sd-radio){margin-right:var(--sd-spacing-6,1.5rem)}:host([orientation=horizontal]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio){margin-right:var(--sd-spacing-4,1rem)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([required]) #label
|
|
262
|
+
css`:host{display:block}:host([orientation=vertical]) ::slotted(sd-radio){margin-bottom:var(--sd-spacing-2,.5rem);display:flex}:host([orientation=vertical]) ::slotted(sd-radio:last-of-type){margin-bottom:var(--sd-spacing-0,0)}:host([orientation=horizontal]) ::slotted(sd-radio){margin-right:var(--sd-spacing-6,1.5rem)}:host([orientation=horizontal]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio){margin-right:var(--sd-spacing-4,1rem)}:host([orientation=horizontal]):host([size=sm]) ::slotted(sd-radio:last-of-type){margin-right:var(--sd-spacing-0,0)}:host([required]) #label::after{content:' *'}`
|
|
268
263
|
];
|
|
269
264
|
__decorateClass([
|
|
270
265
|
query("slot:not([name])")
|
|
@@ -272,6 +267,9 @@ __decorateClass([
|
|
|
272
267
|
__decorateClass([
|
|
273
268
|
query("#validation-input")
|
|
274
269
|
], SdRadioGroup.prototype, "validationInput", 2);
|
|
270
|
+
__decorateClass([
|
|
271
|
+
query("#invalid-message")
|
|
272
|
+
], SdRadioGroup.prototype, "invalidMessage", 2);
|
|
275
273
|
__decorateClass([
|
|
276
274
|
state()
|
|
277
275
|
], SdRadioGroup.prototype, "hasButtonGroup", 2);
|
|
@@ -280,13 +278,13 @@ __decorateClass([
|
|
|
280
278
|
], SdRadioGroup.prototype, "defaultValue", 2);
|
|
281
279
|
__decorateClass([
|
|
282
280
|
state()
|
|
283
|
-
], SdRadioGroup.prototype, "
|
|
284
|
-
__decorateClass([
|
|
285
|
-
state()
|
|
286
|
-
], SdRadioGroup.prototype, "errorText", 2);
|
|
281
|
+
], SdRadioGroup.prototype, "showInvalidStyle", 2);
|
|
287
282
|
__decorateClass([
|
|
288
283
|
property()
|
|
289
284
|
], SdRadioGroup.prototype, "label", 2);
|
|
285
|
+
__decorateClass([
|
|
286
|
+
property({ type: Boolean, reflect: true })
|
|
287
|
+
], SdRadioGroup.prototype, "boldLabel", 2);
|
|
290
288
|
__decorateClass([
|
|
291
289
|
property()
|
|
292
290
|
], SdRadioGroup.prototype, "name", 2);
|
|
@@ -309,7 +307,7 @@ __decorateClass([
|
|
|
309
307
|
watch("size", { waitUntilFirstUpdate: true })
|
|
310
308
|
], SdRadioGroup.prototype, "handleSizeChange", 1);
|
|
311
309
|
__decorateClass([
|
|
312
|
-
watch("
|
|
310
|
+
watch("showInvalidStyle", { waitUntilFirstUpdate: true })
|
|
313
311
|
], SdRadioGroup.prototype, "handleInvalidChange", 1);
|
|
314
312
|
__decorateClass([
|
|
315
313
|
watch("value")
|
|
@@ -22,13 +22,14 @@ export default class SdSelect extends SolidElement implements SolidFormControl {
|
|
|
22
22
|
displayInput: HTMLInputElement;
|
|
23
23
|
valueInput: HTMLInputElement;
|
|
24
24
|
listbox: HTMLSlotElement;
|
|
25
|
+
invalidMessage: HTMLDivElement;
|
|
25
26
|
private hasFocus;
|
|
26
27
|
hasHover: boolean;
|
|
27
28
|
private displayLabel;
|
|
28
29
|
private currentOption;
|
|
29
30
|
private selectedOptions;
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
showValidStyle: boolean;
|
|
32
|
+
showInvalidStyle: boolean;
|
|
32
33
|
defaultValue: string | string[];
|
|
33
34
|
open: boolean;
|
|
34
35
|
size: 'lg' | 'md' | 'sm';
|
|
@@ -51,7 +52,6 @@ export default class SdSelect extends SolidElement implements SolidFormControl {
|
|
|
51
52
|
get validity(): ValidityState;
|
|
52
53
|
get validationMessage(): string;
|
|
53
54
|
connectedCallback(): void;
|
|
54
|
-
updated(): void;
|
|
55
55
|
private addOpenListeners;
|
|
56
56
|
private removeOpenListeners;
|
|
57
57
|
private handleFocus;
|
|
@@ -13,7 +13,6 @@ import { waitForEvent } from "../../internal/event.js";
|
|
|
13
13
|
import { watch } from "../../internal/watch.js";
|
|
14
14
|
import componentStyles from "../../styles/component.styles.js";
|
|
15
15
|
import cx from "classix";
|
|
16
|
-
import formControlStyles from "../../styles/form-control.styles.js";
|
|
17
16
|
import SdIcon from "../icon/icon.js";
|
|
18
17
|
import SdPopup from "../popup/popup.js";
|
|
19
18
|
import SdTag from "../tag/tag.js";
|
|
@@ -42,12 +41,12 @@ let SdSelect = class extends SolidElement {
|
|
|
42
41
|
this.hasHover = false;
|
|
43
42
|
this.displayLabel = "";
|
|
44
43
|
this.selectedOptions = [];
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
44
|
+
this.showValidStyle = false;
|
|
45
|
+
this.showInvalidStyle = false;
|
|
47
46
|
this.defaultValue = "";
|
|
48
47
|
this.open = false;
|
|
49
48
|
this.size = "lg";
|
|
50
|
-
this.label = "
|
|
49
|
+
this.label = "";
|
|
51
50
|
this.placeholder = this.localize.term("selectDefaultPlaceholder");
|
|
52
51
|
this.helpText = "";
|
|
53
52
|
this.placement = "bottom";
|
|
@@ -187,15 +186,6 @@ let SdSelect = class extends SolidElement {
|
|
|
187
186
|
this.applySizeToOptions();
|
|
188
187
|
this.open = false;
|
|
189
188
|
}
|
|
190
|
-
/** Checks for the presence of the attributes 'data-user-valid' or 'data-user-invalid' and updates the corresponding state for reactive conditional styling. */
|
|
191
|
-
updated() {
|
|
192
|
-
if (this.hasAttribute("data-user-valid") && this.checkValidity()) {
|
|
193
|
-
this.isValid = true;
|
|
194
|
-
}
|
|
195
|
-
if (this.hasAttribute("data-user-invalid") && !this.checkValidity()) {
|
|
196
|
-
this.isInvalid = true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
189
|
addOpenListeners() {
|
|
200
190
|
document.addEventListener("focusin", this.handleDocumentFocusIn);
|
|
201
191
|
document.addEventListener("keydown", this.handleDocumentKeyDown);
|
|
@@ -373,6 +363,7 @@ let SdSelect = class extends SolidElement {
|
|
|
373
363
|
handleInvalid(event) {
|
|
374
364
|
this.formControlController.setValidity(false);
|
|
375
365
|
this.formControlController.emitInvalidEvent(event);
|
|
366
|
+
this.invalidMessage.textContent = event.target.validationMessage;
|
|
376
367
|
}
|
|
377
368
|
handleMouseEnter() {
|
|
378
369
|
this.hasHover = true;
|
|
@@ -494,7 +485,7 @@ let SdSelect = class extends SolidElement {
|
|
|
494
485
|
const hasLabel = this.label ? true : !!slots["label"];
|
|
495
486
|
const hasHelpText = this.helpText ? true : !!slots["helpText"];
|
|
496
487
|
const hasClearIcon = this.clearable && !this.disabled && this.value.length > 0;
|
|
497
|
-
const selectState = this.disabled ? "disabled" : this.hasFocus && this.
|
|
488
|
+
const selectState = this.disabled ? "disabled" : this.hasFocus && this.showInvalidStyle ? "activeInvalid" : this.hasFocus && this.showValidStyle ? "activeValid" : this.hasFocus || this.open ? "active" : this.showInvalidStyle ? "invalid" : this.showValidStyle ? "valid" : "default";
|
|
498
489
|
const cursorStyles = this.disabled ? "cursor-not-allowed" : "cursor-pointer";
|
|
499
490
|
const iconMarginLeft = { sm: "ml-1", md: "ml-2", lg: "ml-2" }[this.size];
|
|
500
491
|
const iconSize = {
|
|
@@ -503,9 +494,12 @@ let SdSelect = class extends SolidElement {
|
|
|
503
494
|
lg: "text-xl"
|
|
504
495
|
}[this.size];
|
|
505
496
|
return html`<div part="form-control" class="${cx(
|
|
506
|
-
"
|
|
497
|
+
"relative text-left",
|
|
507
498
|
cursorStyles,
|
|
508
499
|
this.size === "sm" ? "text-sm" : "text-base",
|
|
500
|
+
this.open && "z-50"
|
|
501
|
+
)}"><label id="label" part="form-control-label" class="${hasLabel && "inline-block mb-2"}" aria-hidden="${hasLabel ? "false" : "true"}" @click="${this.handleLabelClick}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
|
|
502
|
+
"relative w-full bg-white",
|
|
509
503
|
{
|
|
510
504
|
disabled: "text-neutral-500",
|
|
511
505
|
readonly: "text-black",
|
|
@@ -515,9 +509,8 @@ let SdSelect = class extends SolidElement {
|
|
|
515
509
|
invalid: "text-error",
|
|
516
510
|
valid: "text-success",
|
|
517
511
|
default: "text-black"
|
|
518
|
-
}[selectState]
|
|
519
|
-
|
|
520
|
-
)}"><label id="label" part="form-control-label" class="${hasLabel && "inline-block mb-2"}" aria-hidden="${hasLabel ? "false" : "true"}" @click="${this.handleLabelClick}"><slot name="label" class="${cx(this.disabled && "text-black")}">${this.label}</slot></label><div part="form-control-input" class="${cx("relative w-full bg-white")}"><div part="border" class="${cx(
|
|
512
|
+
}[selectState]
|
|
513
|
+
)}"><div part="border" class="${cx(
|
|
521
514
|
"absolute top-0 w-full h-full pointer-events-none border rounded-default",
|
|
522
515
|
this.hasHover && "bg-neutral-200",
|
|
523
516
|
{
|
|
@@ -545,10 +538,10 @@ let SdSelect = class extends SolidElement {
|
|
|
545
538
|
"appearance-none outline-none flex-grow bg-transparent",
|
|
546
539
|
cursorStyles,
|
|
547
540
|
this.multiple && this.useTags && this.value.length > 0 ? "hidden" : ""
|
|
548
|
-
)}" type="text" placeholder="${this.placeholder}" .disabled="${this.disabled}" .value="${this.displayLabel}" autocomplete="off" spellcheck="false" autocapitalize="off" readonly="readonly" aria-controls="listbox" aria-expanded="${this.open ? "true" : "false"}" aria-haspopup="listbox" aria-labelledby="label" aria-disabled="${this.disabled ? "true" : "false"}" aria-describedby="help-text" role="combobox" tabindex="0" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${this.multiple && this.useTags ? html`<div part="tags" class="flex-grow flex flex-wrap items-center gap-1">${this.tags}</div>` : ""} <input class="${cx("value-input absolute top-0 left-0 w-full h-full opacity-0 -z-10", cursorStyles)}" type="text" ?disabled="${this.disabled}" ?required="${this.required}" .value="${Array.isArray(this.value) ? this.value.join(", ") : this.value}" tabindex="-1" aria-hidden="true" @focus="${() => this.focus()}" @invalid="${this.handleInvalid}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("select__clear flex justify-center", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @mousedown="${this.handleClearMouseDown}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.
|
|
541
|
+
)}" type="text" placeholder="${this.placeholder}" .disabled="${this.disabled}" .value="${this.displayLabel}" autocomplete="off" spellcheck="false" autocapitalize="off" readonly="readonly" aria-controls="listbox" aria-expanded="${this.open ? "true" : "false"}" aria-haspopup="listbox" aria-labelledby="label" aria-disabled="${this.disabled ? "true" : "false"}" aria-describedby="help-text" role="combobox" tabindex="0" @focus="${this.handleFocus}" @blur="${this.handleBlur}"> ${this.multiple && this.useTags ? html`<div part="tags" class="flex-grow flex flex-wrap items-center gap-1">${this.tags}</div>` : ""} <input class="${cx("value-input absolute top-0 left-0 w-full h-full opacity-0 -z-10", cursorStyles)}" type="text" ?disabled="${this.disabled}" ?required="${this.required}" .value="${Array.isArray(this.value) ? this.value.join(", ") : this.value}" tabindex="-1" aria-hidden="true" @focus="${() => this.focus()}" @invalid="${this.handleInvalid}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("select__clear flex justify-center", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @mousedown="${this.handleClearMouseDown}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-neutral-500", iconSize)}" library="system" name="closing-round"></sd-icon></slot></button>` : ""} ${this.showInvalidStyle ? html`<sd-icon class="${cx("text-error", iconMarginLeft, iconSize)}" library="system" name="risk"></sd-icon>` : ""} ${this.showValidStyle ? html`<sd-icon class="${cx("text-success", iconMarginLeft, iconSize)}" library="system" name="confirm"></sd-icon>` : ""}<slot name="expand-icon" part="expand-icon" class="${cx("inline-flex ml-2 transition-all", this.open ? "rotate-180" : "rotate-0", iconSize)}"><sd-icon name="chevron-down" part="chevron" library="system" color="currentColor"></sd-icon></slot></div><div id="listbox" role="listbox" aria-expanded="${this.open ? "true" : "false"}" aria-multiselectable="${this.multiple ? "true" : "false"}" aria-labelledby="label" part="listbox" class="${cx(
|
|
549
542
|
"bg-white px-2 py-3 relative",
|
|
550
543
|
this.currentPlacement === "bottom" ? "border-r-2 border-b-2 border-l-2 rounded-br-default rounded-bl-default" : "border-r-2 border-t-2 border-l-2 rounded-tr-default rounded-tl-default"
|
|
551
|
-
)}" tabindex="-1" @mouseup="${this.handleOptionClick}" @slotchange="${this.handleDefaultSlotChange}"><slot></slot></div></sd-popup></div><div class="text-sm text-neutral-700" part="form-control-help-text" id="help-text" aria-hidden="${hasHelpText ? "false" : "true"}"><slot name="help-text">${this.helpText}</slot></div></div
|
|
544
|
+
)}" tabindex="-1" @mouseup="${this.handleOptionClick}" @slotchange="${this.handleDefaultSlotChange}"><slot></slot></div></sd-popup></div><div class="text-sm text-neutral-700" part="form-control-help-text" id="help-text" aria-hidden="${hasHelpText ? "false" : "true"}"><slot name="help-text">${this.helpText}</slot></div></div>${this.formControlController.renderInvalidMessage()}`;
|
|
552
545
|
}
|
|
553
546
|
};
|
|
554
547
|
SdSelect.dependencies = {
|
|
@@ -558,7 +551,6 @@ SdSelect.dependencies = {
|
|
|
558
551
|
};
|
|
559
552
|
SdSelect.styles = [
|
|
560
553
|
componentStyles,
|
|
561
|
-
formControlStyles,
|
|
562
554
|
SolidElement.styles,
|
|
563
555
|
css`:host{position:relative;display:block;width:100%}:host([required]) #label::after{content:' *'}sd-popup::part(popup){overflow-y:scroll}sd-tag::part(base){border-radius:var(--sd-border-radius-default,.25rem);padding-left:var(--sd-spacing-1,.25rem);padding-right:var(--sd-spacing-1,.25rem)}sd-tag[size=lg]::part(base){padding-left:var(--sd-spacing-2,.5rem);padding-right:var(--sd-spacing-2,.5rem)}sd-tag[disabled=false]::part(base):hover{--tw-bg-opacity:1;background-color:rgb(var(--sd-color-primary-100,236 240 249) / var(--tw-bg-opacity))}`
|
|
564
556
|
];
|
|
@@ -580,6 +572,9 @@ __decorateClass([
|
|
|
580
572
|
__decorateClass([
|
|
581
573
|
query('[part="listbox"]')
|
|
582
574
|
], SdSelect.prototype, "listbox", 2);
|
|
575
|
+
__decorateClass([
|
|
576
|
+
query("#invalid-message")
|
|
577
|
+
], SdSelect.prototype, "invalidMessage", 2);
|
|
583
578
|
__decorateClass([
|
|
584
579
|
state()
|
|
585
580
|
], SdSelect.prototype, "hasFocus", 2);
|
|
@@ -597,10 +592,10 @@ __decorateClass([
|
|
|
597
592
|
], SdSelect.prototype, "selectedOptions", 2);
|
|
598
593
|
__decorateClass([
|
|
599
594
|
state()
|
|
600
|
-
], SdSelect.prototype, "
|
|
595
|
+
], SdSelect.prototype, "showValidStyle", 2);
|
|
601
596
|
__decorateClass([
|
|
602
597
|
state()
|
|
603
|
-
], SdSelect.prototype, "
|
|
598
|
+
], SdSelect.prototype, "showInvalidStyle", 2);
|
|
604
599
|
__decorateClass([
|
|
605
600
|
defaultValue()
|
|
606
601
|
], SdSelect.prototype, "defaultValue", 2);
|