@solid-design-system/components 1.19.0 → 1.21.0
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/accordion-group.js +1 -1
- package/dist/components/es/accordion.js +1 -1
- package/dist/components/es/brandshape.js +1 -1
- package/dist/components/es/button.js +1 -1
- package/dist/components/es/carousel.js +2 -2
- package/dist/components/es/drawer.js +1 -1
- package/dist/components/es/dropdown.js +1 -1
- package/dist/components/es/form.js +1 -0
- package/dist/components/es/icon.js +3 -3
- package/dist/components/es/if-defined.js +2 -2
- package/dist/components/es/link.js +1 -1
- package/dist/components/es/lit-element.js +4 -4
- package/dist/components/es/navigation-item.js +2 -2
- package/dist/components/es/popup.js +1 -1
- package/dist/components/es/query-assigned-elements.js +6 -0
- package/dist/components/es/query.js +7 -2
- package/dist/components/es/radio-group.js +1 -0
- package/dist/components/es/radio.js +1 -0
- package/dist/components/es/solid-components2.js +1 -1
- package/dist/components/es/solid-element.js +2 -12
- package/dist/components/es/state.js +1 -1
- package/dist/components/es/static.js +1 -1
- package/dist/components/es/tag.js +1 -1
- package/dist/components/es/teaser.js +1 -1
- package/dist/components/es/video.js +1 -1
- package/dist/components/umd/solid-components.js +18 -18
- package/dist/custom-elements.json +1 -1
- package/dist/package/_components/button-group/button-group.d.ts +19 -0
- package/dist/package/_components/button-group/button-group.js +76 -0
- package/dist/package/_components/button-group/button-group.styles.d.ts +2 -0
- package/dist/package/_components/button-group/button-group.styles.js +6 -0
- package/dist/package/components/button/button.d.ts +4 -0
- package/dist/package/components/button/button.js +25 -3
- package/dist/package/components/radio/radio.d.ts +27 -0
- package/dist/package/components/radio/radio.js +130 -0
- package/dist/package/components/radio-group/radio-group.d.ts +52 -0
- package/dist/package/components/radio-group/radio-group.js +321 -0
- package/dist/package/internal/form.d.ts +7 -1
- package/dist/package/internal/form.js +110 -49
- package/dist/package/internal/solid-element.d.ts +2 -0
- package/dist/package/node_modules/.pnpm/{@shoelace-style_localize@3.1.0 → @shoelace-style_localize@3.1.2}/node_modules/@shoelace-style/localize/dist/index.js +1 -1
- package/dist/package/solid-components.d.ts +2 -0
- package/dist/package/solid-components.js +12 -8
- package/dist/package/styles/tailwind.css.js +1 -1
- package/dist/package/translations/en.js +1 -1
- package/dist/package/utilities/localize.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/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 -0
- package/dist/versioned-components/es/icon.js +3 -3
- package/dist/versioned-components/es/if-defined.js +2 -2
- package/dist/versioned-components/es/include.js +1 -1
- package/dist/versioned-components/es/link.js +1 -1
- package/dist/versioned-components/es/lit-element.js +4 -4
- package/dist/versioned-components/es/navigation-item.js +2 -2
- package/dist/versioned-components/es/popup.js +1 -1
- package/dist/versioned-components/es/query-assigned-elements.js +6 -0
- package/dist/versioned-components/es/query.js +7 -2
- package/dist/versioned-components/es/radio-group.js +1 -0
- package/dist/versioned-components/es/radio.js +1 -0
- package/dist/versioned-components/es/solid-components2.js +1 -1
- package/dist/versioned-components/es/solid-element.js +2 -12
- package/dist/versioned-components/es/spinner.js +1 -1
- package/dist/versioned-components/es/state.js +1 -1
- package/dist/versioned-components/es/static.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/video.js +1 -1
- package/dist/versioned-package/_components/button-group/button-group.d.ts +19 -0
- package/dist/versioned-package/_components/button-group/button-group.js +76 -0
- package/dist/versioned-package/_components/button-group/button-group.styles.d.ts +2 -0
- package/dist/versioned-package/_components/button-group/button-group.styles.js +6 -0
- 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 +5 -1
- package/dist/versioned-package/components/button/button.js +29 -7
- 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/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 +6 -6
- 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/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/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 +27 -0
- package/dist/versioned-package/components/radio/radio.js +130 -0
- package/dist/versioned-package/components/radio-group/radio-group.d.ts +52 -0
- package/dist/versioned-package/components/radio-group/radio-group.js +321 -0
- 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/tag/tag.d.ts +1 -1
- package/dist/versioned-package/components/tag/tag.js +2 -2
- package/dist/versioned-package/components/teaser/teaser.js +1 -1
- 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 +7 -1
- package/dist/versioned-package/internal/form.js +110 -49
- package/dist/versioned-package/internal/solid-element.d.ts +2 -0
- package/dist/versioned-package/node_modules/.pnpm/{@shoelace-style_localize@3.1.0 → @shoelace-style_localize@3.1.2}/node_modules/@shoelace-style/localize/dist/index.js +1 -1
- package/dist/versioned-package/solid-components.d.ts +2 -0
- package/dist/versioned-package/solid-components.js +12 -8
- package/dist/versioned-package/styles/tailwind.css.js +1 -1
- package/dist/versioned-package/translations/en.js +1 -1
- package/dist/versioned-package/utilities/localize.js +1 -1
- package/dist/versioned-styles/solid-styles.css +1 -1
- package/dist/vscode.html-custom-data.json +201 -21
- package/dist/web-types.json +910 -122
- package/package.json +51 -56
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { css, html } from "lit";
|
|
2
|
+
import { customElement } from "../../internal/register-custom-element.js";
|
|
3
|
+
import { FormControlController, customErrorValidityState, valueMissingValidityState, validValidityState } from "../../internal/form.js";
|
|
4
|
+
import { HasSlotController } from "../../internal/slot.js";
|
|
5
|
+
import { query, state, property } from "lit/decorators.js";
|
|
6
|
+
import { watch } from "../../internal/watch.js";
|
|
7
|
+
import componentStyles from "../../styles/component.styles.js";
|
|
8
|
+
import cx from "classix";
|
|
9
|
+
import SdButtonGroup from "../../_components/button-group/button-group.js";
|
|
10
|
+
import SolidElement from "../../internal/solid-element.js";
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
14
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
15
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
16
|
+
if (decorator = decorators[i])
|
|
17
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
18
|
+
if (kind && result)
|
|
19
|
+
__defProp(target, key, result);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
let SdRadioGroup = class extends SolidElement {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.formControlController = new FormControlController(this);
|
|
26
|
+
this.hasSlotController = new HasSlotController(this, "label", "error-text");
|
|
27
|
+
this.customValidityMessage = "";
|
|
28
|
+
this.hasButtonGroup = false;
|
|
29
|
+
this.defaultValue = "";
|
|
30
|
+
this.invalid = false;
|
|
31
|
+
this.errorText = "";
|
|
32
|
+
this.label = "";
|
|
33
|
+
this.name = "option";
|
|
34
|
+
this.value = "";
|
|
35
|
+
this.size = "lg";
|
|
36
|
+
this.form = "";
|
|
37
|
+
this.required = false;
|
|
38
|
+
this.orientation = "vertical";
|
|
39
|
+
}
|
|
40
|
+
/** Gets the validity state object */
|
|
41
|
+
get validity() {
|
|
42
|
+
const isRequiredAndEmpty = this.required && !this.value;
|
|
43
|
+
const hasCustomValidityMessage = this.customValidityMessage !== "";
|
|
44
|
+
if (hasCustomValidityMessage) {
|
|
45
|
+
this.invalid = true;
|
|
46
|
+
return customErrorValidityState;
|
|
47
|
+
} else if (isRequiredAndEmpty) {
|
|
48
|
+
this.invalid = true;
|
|
49
|
+
return valueMissingValidityState;
|
|
50
|
+
}
|
|
51
|
+
this.invalid = false;
|
|
52
|
+
return validValidityState;
|
|
53
|
+
}
|
|
54
|
+
/** Gets the validation message */
|
|
55
|
+
get validationMessage() {
|
|
56
|
+
const isRequiredAndEmpty = this.required && !this.value;
|
|
57
|
+
const hasCustomValidityMessage = this.customValidityMessage !== "";
|
|
58
|
+
if (hasCustomValidityMessage) {
|
|
59
|
+
console.log("this.customValidityMessage", this.customValidityMessage);
|
|
60
|
+
return this.customValidityMessage;
|
|
61
|
+
} else if (isRequiredAndEmpty) {
|
|
62
|
+
console.log("this.validationInput.validationMessage", this.validationInput);
|
|
63
|
+
return this.validationInput.validationMessage;
|
|
64
|
+
}
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
connectedCallback() {
|
|
68
|
+
super.connectedCallback();
|
|
69
|
+
this.defaultValue = this.value;
|
|
70
|
+
}
|
|
71
|
+
firstUpdated() {
|
|
72
|
+
this.formControlController.updateValidity();
|
|
73
|
+
}
|
|
74
|
+
getAllRadios() {
|
|
75
|
+
return [...this.querySelectorAll("sd-radio, sd-radio-button")];
|
|
76
|
+
}
|
|
77
|
+
handleRadioClick(event) {
|
|
78
|
+
const target = event.target.closest("sd-radio, sd-radio-button");
|
|
79
|
+
const radios = this.getAllRadios();
|
|
80
|
+
const oldValue = this.value;
|
|
81
|
+
if (target.disabled) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.value = target.value;
|
|
85
|
+
radios.forEach((radio) => radio.checked = radio === target);
|
|
86
|
+
if (this.value !== oldValue) {
|
|
87
|
+
this.emit("sd-change");
|
|
88
|
+
this.emit("sd-input");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
handleKeyDown(event) {
|
|
92
|
+
if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", " "].includes(event.key)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const radios = this.getAllRadios().filter((radio) => !radio.disabled);
|
|
96
|
+
const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0];
|
|
97
|
+
const incr = event.key === " " ? 0 : ["ArrowUp", "ArrowLeft"].includes(event.key) ? -1 : 1;
|
|
98
|
+
const oldValue = this.value;
|
|
99
|
+
let index = radios.indexOf(checkedRadio) + incr;
|
|
100
|
+
if (index < 0) {
|
|
101
|
+
index = radios.length - 1;
|
|
102
|
+
}
|
|
103
|
+
if (index > radios.length - 1) {
|
|
104
|
+
index = 0;
|
|
105
|
+
}
|
|
106
|
+
this.getAllRadios().forEach((radio) => {
|
|
107
|
+
radio.checked = false;
|
|
108
|
+
if (!this.hasButtonGroup) {
|
|
109
|
+
radio.tabIndex = -1;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
this.value = radios[index].value;
|
|
113
|
+
radios[index].checked = true;
|
|
114
|
+
if (!this.hasButtonGroup) {
|
|
115
|
+
radios[index].tabIndex = 0;
|
|
116
|
+
radios[index].focus();
|
|
117
|
+
} else {
|
|
118
|
+
radios[index].shadowRoot.querySelector("button").focus();
|
|
119
|
+
}
|
|
120
|
+
if (this.value !== oldValue) {
|
|
121
|
+
this.emit("sd-change");
|
|
122
|
+
this.emit("sd-input");
|
|
123
|
+
}
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
}
|
|
126
|
+
handleLabelClick() {
|
|
127
|
+
const radios = this.getAllRadios();
|
|
128
|
+
const checked = radios.find((radio) => radio.checked);
|
|
129
|
+
const radioToFocus = checked || radios[0];
|
|
130
|
+
if (radioToFocus) {
|
|
131
|
+
radioToFocus.focus();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
handleInvalid(event) {
|
|
135
|
+
this.formControlController.setValidity(false);
|
|
136
|
+
this.formControlController.emitInvalidEvent(event);
|
|
137
|
+
}
|
|
138
|
+
async syncRadioElements() {
|
|
139
|
+
var _a, _b;
|
|
140
|
+
const radios = this.getAllRadios();
|
|
141
|
+
await Promise.all(
|
|
142
|
+
// Sync the checked state and size
|
|
143
|
+
radios.map(async (radio) => {
|
|
144
|
+
await radio.updateComplete;
|
|
145
|
+
radio.checked = radio.value === this.value;
|
|
146
|
+
radio.size = this.size;
|
|
147
|
+
radio.invalid = this.invalid;
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
this.hasButtonGroup = radios.some((radio) => radio.tagName.toLowerCase() === "sd-radio-button");
|
|
151
|
+
if (!radios.some((radio) => radio.checked)) {
|
|
152
|
+
if (this.hasButtonGroup) {
|
|
153
|
+
const buttonRadio = (_a = radios[0].shadowRoot) == null ? void 0 : _a.querySelector("button");
|
|
154
|
+
if (buttonRadio) {
|
|
155
|
+
buttonRadio.tabIndex = 0;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
radios[0].tabIndex = 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (this.hasButtonGroup) {
|
|
162
|
+
const buttonGroup = (_b = this.shadowRoot) == null ? void 0 : _b.querySelector("sd-button-group");
|
|
163
|
+
if (buttonGroup) {
|
|
164
|
+
buttonGroup.disableRole = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
syncRadios() {
|
|
169
|
+
if (customElements.get("sd-radio") && customElements.get("sd-radio-button")) {
|
|
170
|
+
this.syncRadioElements();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (customElements.get("sd-radio")) {
|
|
174
|
+
this.syncRadioElements();
|
|
175
|
+
} else {
|
|
176
|
+
customElements.whenDefined("sd-radio").then(() => this.syncRadios());
|
|
177
|
+
}
|
|
178
|
+
if (customElements.get("sd-radio-button")) {
|
|
179
|
+
this.syncRadioElements();
|
|
180
|
+
} else {
|
|
181
|
+
customElements.whenDefined("sd-radio-button").then(() => this.syncRadios());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
updateCheckedRadio() {
|
|
185
|
+
const radios = this.getAllRadios();
|
|
186
|
+
radios.forEach((radio) => radio.checked = radio.value === this.value);
|
|
187
|
+
this.formControlController.setValidity(this.validity.valid);
|
|
188
|
+
}
|
|
189
|
+
handleSizeChange() {
|
|
190
|
+
this.syncRadios();
|
|
191
|
+
}
|
|
192
|
+
handleInvalidChange() {
|
|
193
|
+
this.syncRadios();
|
|
194
|
+
}
|
|
195
|
+
handleValueChange() {
|
|
196
|
+
if (this.hasUpdated) {
|
|
197
|
+
this.updateCheckedRadio();
|
|
198
|
+
this.reportValidity();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** Checks for validity but does not show a validation message. Returns `true` when valid and `false` when invalid. */
|
|
202
|
+
checkValidity() {
|
|
203
|
+
const isRequiredAndEmpty = this.required && !this.value;
|
|
204
|
+
const hasCustomValidityMessage = this.customValidityMessage !== "";
|
|
205
|
+
if (isRequiredAndEmpty || hasCustomValidityMessage) {
|
|
206
|
+
this.formControlController.emitInvalidEvent();
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
/** Gets the associated form, if one exists. */
|
|
212
|
+
getForm() {
|
|
213
|
+
return this.formControlController.getForm();
|
|
214
|
+
}
|
|
215
|
+
/** Checks for validity and shows the browser's validation message if the control is invalid. */
|
|
216
|
+
// TODO: https://github.com/solid-design-system/solid/issues/501
|
|
217
|
+
reportValidity() {
|
|
218
|
+
const isValid = this.validity.valid;
|
|
219
|
+
this.errorText = this.customValidityMessage || isValid ? "" : this.validationInput.validationMessage;
|
|
220
|
+
this.formControlController.setValidity(isValid);
|
|
221
|
+
this.validationInput.hidden = true;
|
|
222
|
+
clearTimeout(this.validationTimeout);
|
|
223
|
+
if (!isValid) {
|
|
224
|
+
this.validationInput.hidden = false;
|
|
225
|
+
this.validationInput.reportValidity();
|
|
226
|
+
this.validationTimeout = setTimeout(() => this.validationInput.hidden = true, 1e4);
|
|
227
|
+
}
|
|
228
|
+
return isValid;
|
|
229
|
+
}
|
|
230
|
+
/** Sets a custom validation message. Pass an empty string to restore validity. */
|
|
231
|
+
setCustomValidity(message = "") {
|
|
232
|
+
this.customValidityMessage = message;
|
|
233
|
+
this.errorText = message;
|
|
234
|
+
this.validationInput.setCustomValidity(message);
|
|
235
|
+
this.formControlController.updateValidity();
|
|
236
|
+
}
|
|
237
|
+
render() {
|
|
238
|
+
const hasLabelSlot = this.hasSlotController.test("label");
|
|
239
|
+
const hasErrorTextSlot = this.hasSlotController.test("error-text");
|
|
240
|
+
const hasLabel = this.label ? true : !!hasLabelSlot;
|
|
241
|
+
const hasErrorText = this.errorText ? true : !!hasErrorTextSlot;
|
|
242
|
+
const defaultSlot = html`<slot @slotchange="${this.syncRadios}" @click="${this.handleRadioClick}" @keydown="${this.handleKeyDown}"></slot>`;
|
|
243
|
+
return html`<fieldset part="form-control" class="${cx(
|
|
244
|
+
"form-control form-control--radio-group border-0 p-0 m-0",
|
|
245
|
+
hasLabel && "form-control--has-label",
|
|
246
|
+
hasErrorText && "text-error",
|
|
247
|
+
{
|
|
248
|
+
/* sizes, fonts */
|
|
249
|
+
sm: "text-sm",
|
|
250
|
+
lg: "text-base"
|
|
251
|
+
}[this.size]
|
|
252
|
+
)}" role="radiogroup" aria-labelledby="label" aria-errormessage="error-text"><label part="form-control-label" id="label" class="form-control__label mb-2 hidden p-0 font-bold leading-normal text-black" aria-hidden="${!hasLabel}" @click="${this.handleLabelClick}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="${cx(
|
|
253
|
+
"form-control-input flex",
|
|
254
|
+
this.invalid && "form-control-input--invalid text-error",
|
|
255
|
+
{
|
|
256
|
+
vertical: "form-control-input--vertical flex-col",
|
|
257
|
+
horizontal: "form-control-input--horizontal flex-row"
|
|
258
|
+
}[this.orientation]
|
|
259
|
+
)}"><div class="sr-only"><div id="error-message" aria-live="assertive">${this.errorText}</div><label class="radio-group__validation"><input type="text" class="radio-group__validation-input" ?required="${this.required}" tabindex="-1" hidden @invalid="${this.handleInvalid}"></label></div>${defaultSlot}</div></fieldset>`;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
SdRadioGroup.dependencies = { "sd-button-group": SdButtonGroup };
|
|
263
|
+
SdRadioGroup.styles = [
|
|
264
|
+
componentStyles,
|
|
265
|
+
SolidElement.styles,
|
|
266
|
+
css`:host{display:block}.form-control-input--vertical ::slotted(sd-radio){margin-bottom:8px;display:flex}.form-control-input--vertical ::slotted(sd-radio:last-of-type){margin-bottom:0}.form-control-input--horizontal ::slotted(sd-radio){margin-right:24px}.form-control-input--horizontal ::slotted(sd-radio:last-of-type){margin-right:0}.form-control--has-label .form-control__label{display:flex}:host([required]) .form-control--has-label .form-control__label::after{content:'*';margin-left:2px}`
|
|
267
|
+
];
|
|
268
|
+
__decorateClass([
|
|
269
|
+
query("slot:not([name])")
|
|
270
|
+
], SdRadioGroup.prototype, "defaultSlot", 2);
|
|
271
|
+
__decorateClass([
|
|
272
|
+
query(".radio-group__validation-input")
|
|
273
|
+
], SdRadioGroup.prototype, "validationInput", 2);
|
|
274
|
+
__decorateClass([
|
|
275
|
+
state()
|
|
276
|
+
], SdRadioGroup.prototype, "hasButtonGroup", 2);
|
|
277
|
+
__decorateClass([
|
|
278
|
+
state()
|
|
279
|
+
], SdRadioGroup.prototype, "defaultValue", 2);
|
|
280
|
+
__decorateClass([
|
|
281
|
+
state()
|
|
282
|
+
], SdRadioGroup.prototype, "invalid", 2);
|
|
283
|
+
__decorateClass([
|
|
284
|
+
state()
|
|
285
|
+
], SdRadioGroup.prototype, "errorText", 2);
|
|
286
|
+
__decorateClass([
|
|
287
|
+
property()
|
|
288
|
+
], SdRadioGroup.prototype, "label", 2);
|
|
289
|
+
__decorateClass([
|
|
290
|
+
property()
|
|
291
|
+
], SdRadioGroup.prototype, "name", 2);
|
|
292
|
+
__decorateClass([
|
|
293
|
+
property({ reflect: true })
|
|
294
|
+
], SdRadioGroup.prototype, "value", 2);
|
|
295
|
+
__decorateClass([
|
|
296
|
+
property({ reflect: true })
|
|
297
|
+
], SdRadioGroup.prototype, "size", 2);
|
|
298
|
+
__decorateClass([
|
|
299
|
+
property({ reflect: true })
|
|
300
|
+
], SdRadioGroup.prototype, "form", 2);
|
|
301
|
+
__decorateClass([
|
|
302
|
+
property({ type: Boolean, reflect: true })
|
|
303
|
+
], SdRadioGroup.prototype, "required", 2);
|
|
304
|
+
__decorateClass([
|
|
305
|
+
property({ reflect: true })
|
|
306
|
+
], SdRadioGroup.prototype, "orientation", 2);
|
|
307
|
+
__decorateClass([
|
|
308
|
+
watch("size", { waitUntilFirstUpdate: true })
|
|
309
|
+
], SdRadioGroup.prototype, "handleSizeChange", 1);
|
|
310
|
+
__decorateClass([
|
|
311
|
+
watch("invalid", { waitUntilFirstUpdate: true })
|
|
312
|
+
], SdRadioGroup.prototype, "handleInvalidChange", 1);
|
|
313
|
+
__decorateClass([
|
|
314
|
+
watch("value")
|
|
315
|
+
], SdRadioGroup.prototype, "handleValueChange", 1);
|
|
316
|
+
SdRadioGroup = __decorateClass([
|
|
317
|
+
customElement("sd-radio-group")
|
|
318
|
+
], SdRadioGroup);
|
|
319
|
+
export {
|
|
320
|
+
SdRadioGroup as default
|
|
321
|
+
};
|
|
@@ -10,6 +10,7 @@ export interface FormControlControllerOptions {
|
|
|
10
10
|
disabled: (input: SolidFormControl) => boolean;
|
|
11
11
|
reportValidity: (input: SolidFormControl) => boolean;
|
|
12
12
|
setValue: (input: SolidFormControl, value: unknown) => void;
|
|
13
|
+
assumeInteractionOn: string[];
|
|
13
14
|
}
|
|
14
15
|
export declare class FormControlController implements ReactiveController {
|
|
15
16
|
host: SolidFormControl & ReactiveControllerHost;
|
|
@@ -24,12 +25,17 @@ export declare class FormControlController implements ReactiveController {
|
|
|
24
25
|
private handleFormData;
|
|
25
26
|
private handleFormSubmit;
|
|
26
27
|
private handleFormReset;
|
|
27
|
-
private
|
|
28
|
+
private handleInteraction;
|
|
28
29
|
private reportFormValidity;
|
|
29
30
|
private setUserInteracted;
|
|
30
31
|
private doAction;
|
|
32
|
+
getForm(): HTMLFormElement | null;
|
|
31
33
|
reset(invoker?: HTMLInputElement | SdButton): void;
|
|
32
34
|
submit(invoker?: HTMLInputElement | SdButton): void;
|
|
33
35
|
setValidity(isValid: boolean): void;
|
|
34
36
|
updateValidity(): void;
|
|
37
|
+
emitInvalidEvent(originalInvalidEvent?: Event): void;
|
|
35
38
|
}
|
|
39
|
+
export declare const validValidityState: ValidityState;
|
|
40
|
+
export declare const valueMissingValidityState: ValidityState;
|
|
41
|
+
export declare const customErrorValidityState: ValidityState;
|
|
@@ -1,8 +1,52 @@
|
|
|
1
1
|
const formCollections = /* @__PURE__ */ new WeakMap();
|
|
2
|
-
const userInteractedControls = /* @__PURE__ */ new WeakMap();
|
|
3
2
|
const reportValidityOverloads = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
const userInteractedControls = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
const interactions = /* @__PURE__ */ new WeakMap();
|
|
4
5
|
class FormControlController {
|
|
5
6
|
constructor(host, options) {
|
|
7
|
+
this.handleFormData = (event) => {
|
|
8
|
+
const disabled = this.options.disabled(this.host);
|
|
9
|
+
const name = this.options.name(this.host);
|
|
10
|
+
const value = this.options.value(this.host);
|
|
11
|
+
const isButton = this.host.tagName.toLowerCase() === "sd-button";
|
|
12
|
+
if (!disabled && !isButton && typeof name === "string" && name.length > 0 && typeof value !== "undefined") {
|
|
13
|
+
if (Array.isArray(value)) {
|
|
14
|
+
value.forEach((val) => {
|
|
15
|
+
event.formData.append(name, val.toString());
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
event.formData.append(name, value.toString());
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
this.handleFormSubmit = (event) => {
|
|
23
|
+
var _a;
|
|
24
|
+
const disabled = this.options.disabled(this.host);
|
|
25
|
+
const reportValidity = this.options.reportValidity;
|
|
26
|
+
if (this.form && !this.form.noValidate) {
|
|
27
|
+
(_a = formCollections.get(this.form)) == null ? void 0 : _a.forEach((control) => {
|
|
28
|
+
this.setUserInteracted(control, true);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (this.form && !this.form.noValidate && !disabled && !reportValidity(this.host)) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
event.stopImmediatePropagation();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
this.handleFormReset = () => {
|
|
37
|
+
this.options.setValue(this.host, this.options.defaultValue(this.host));
|
|
38
|
+
this.setUserInteracted(this.host, false);
|
|
39
|
+
interactions.set(this.host, []);
|
|
40
|
+
};
|
|
41
|
+
this.handleInteraction = (event) => {
|
|
42
|
+
const emittedEvents = interactions.get(this.host);
|
|
43
|
+
if (!emittedEvents.includes(event.type)) {
|
|
44
|
+
emittedEvents.push(event.type);
|
|
45
|
+
}
|
|
46
|
+
if (emittedEvents.length === this.options.assumeInteractionOn.length) {
|
|
47
|
+
this.setUserInteracted(this.host, true);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
6
50
|
(this.host = host).addController(this);
|
|
7
51
|
this.options = {
|
|
8
52
|
form: (input) => {
|
|
@@ -21,26 +65,29 @@ class FormControlController {
|
|
|
21
65
|
disabled: (input) => input.disabled ?? false,
|
|
22
66
|
reportValidity: (input) => typeof input.reportValidity === "function" ? input.reportValidity() : true,
|
|
23
67
|
setValue: (input, value) => input.value = value,
|
|
68
|
+
assumeInteractionOn: ["sd-input"],
|
|
24
69
|
...options
|
|
25
70
|
};
|
|
26
|
-
this.handleFormData = this.handleFormData.bind(this);
|
|
27
|
-
this.handleFormSubmit = this.handleFormSubmit.bind(this);
|
|
28
|
-
this.handleFormReset = this.handleFormReset.bind(this);
|
|
29
|
-
this.reportFormValidity = this.reportFormValidity.bind(this);
|
|
30
|
-
this.handleUserInput = this.handleUserInput.bind(this);
|
|
31
71
|
}
|
|
32
72
|
hostConnected() {
|
|
33
73
|
const form = this.options.form(this.host);
|
|
34
74
|
if (form) {
|
|
35
75
|
this.attachForm(form);
|
|
36
76
|
}
|
|
37
|
-
this.host
|
|
77
|
+
interactions.set(this.host, []);
|
|
78
|
+
this.options.assumeInteractionOn.forEach((event) => {
|
|
79
|
+
this.host.addEventListener(event, this.handleInteraction);
|
|
80
|
+
});
|
|
38
81
|
}
|
|
39
82
|
hostDisconnected() {
|
|
40
83
|
this.detachForm();
|
|
41
|
-
|
|
84
|
+
interactions.delete(this.host);
|
|
85
|
+
this.options.assumeInteractionOn.forEach((event) => {
|
|
86
|
+
this.host.removeEventListener(event, this.handleInteraction);
|
|
87
|
+
});
|
|
42
88
|
}
|
|
43
89
|
hostUpdated() {
|
|
90
|
+
var _a;
|
|
44
91
|
const form = this.options.form(this.host);
|
|
45
92
|
if (!form) {
|
|
46
93
|
this.detachForm();
|
|
@@ -50,7 +97,7 @@ class FormControlController {
|
|
|
50
97
|
this.attachForm(form);
|
|
51
98
|
}
|
|
52
99
|
if (this.host.hasUpdated) {
|
|
53
|
-
this.setValidity(this.host.
|
|
100
|
+
this.setValidity((_a = this.host) == null ? void 0 : _a.validity.valid);
|
|
54
101
|
}
|
|
55
102
|
}
|
|
56
103
|
attachForm(form) {
|
|
@@ -86,43 +133,6 @@ class FormControlController {
|
|
|
86
133
|
}
|
|
87
134
|
this.form = void 0;
|
|
88
135
|
}
|
|
89
|
-
handleFormData(event) {
|
|
90
|
-
const disabled = this.options.disabled(this.host);
|
|
91
|
-
const name = this.options.name(this.host);
|
|
92
|
-
const value = this.options.value(this.host);
|
|
93
|
-
const isButton = this.host.tagName.toLowerCase() === "sd-button";
|
|
94
|
-
if (!disabled && !isButton && typeof name === "string" && name.length > 0 && typeof value !== "undefined") {
|
|
95
|
-
if (Array.isArray(value)) {
|
|
96
|
-
value.forEach((val) => {
|
|
97
|
-
event.formData.append(name, val.toString());
|
|
98
|
-
});
|
|
99
|
-
} else {
|
|
100
|
-
event.formData.append(name, value.toString());
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
handleFormSubmit(event) {
|
|
105
|
-
var _a;
|
|
106
|
-
const disabled = this.options.disabled(this.host);
|
|
107
|
-
const reportValidity = this.options.reportValidity;
|
|
108
|
-
if (this.form && !this.form.noValidate) {
|
|
109
|
-
(_a = formCollections.get(this.form)) == null ? void 0 : _a.forEach((control) => {
|
|
110
|
-
this.setUserInteracted(control, true);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
if (this.form && !this.form.noValidate && !disabled && !reportValidity(this.host)) {
|
|
114
|
-
event.preventDefault();
|
|
115
|
-
event.stopImmediatePropagation();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
handleFormReset() {
|
|
119
|
-
this.options.setValue(this.host, this.options.defaultValue(this.host));
|
|
120
|
-
this.setUserInteracted(this.host, false);
|
|
121
|
-
}
|
|
122
|
-
async handleUserInput() {
|
|
123
|
-
await this.host.updateComplete;
|
|
124
|
-
this.setUserInteracted(this.host, true);
|
|
125
|
-
}
|
|
126
136
|
reportFormValidity() {
|
|
127
137
|
if (this.form && !this.form.noValidate) {
|
|
128
138
|
const elements = this.form.querySelectorAll("*");
|
|
@@ -164,6 +174,10 @@ class FormControlController {
|
|
|
164
174
|
button.remove();
|
|
165
175
|
}
|
|
166
176
|
}
|
|
177
|
+
/** Returns the associated `<form>` element, if one exists. */
|
|
178
|
+
getForm() {
|
|
179
|
+
return this.form ?? null;
|
|
180
|
+
}
|
|
167
181
|
/** Resets the form, restoring all the control to their default value */
|
|
168
182
|
reset(invoker) {
|
|
169
183
|
this.doAction("reset", invoker);
|
|
@@ -198,15 +212,62 @@ class FormControlController {
|
|
|
198
212
|
}
|
|
199
213
|
}
|
|
200
214
|
/**
|
|
201
|
-
* Updates the form control's validity based on the current value of `host.
|
|
215
|
+
* Updates the form control's validity based on the current value of `host.validity.valid`. Call this when anything
|
|
202
216
|
* that affects constraint validation changes so the component receives the correct validity states.
|
|
203
217
|
*/
|
|
204
218
|
updateValidity() {
|
|
205
219
|
const host = this.host;
|
|
206
|
-
this.setValidity(host.
|
|
220
|
+
this.setValidity(host == null ? void 0 : host.validity.valid);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Dispatches a non-bubbling, cancelable custom event of type `sl-invalid`.
|
|
224
|
+
* If the `sl-invalid` event will be cancelled then the original `invalid`
|
|
225
|
+
* event (which may have been passed as argument) will also be cancelled.
|
|
226
|
+
* If no original `invalid` event has been passed then the `sl-invalid`
|
|
227
|
+
* event will be cancelled before being dispatched.
|
|
228
|
+
*/
|
|
229
|
+
emitInvalidEvent(originalInvalidEvent) {
|
|
230
|
+
const slInvalidEvent = new CustomEvent("sd-invalid", {
|
|
231
|
+
bubbles: false,
|
|
232
|
+
composed: false,
|
|
233
|
+
cancelable: true,
|
|
234
|
+
detail: {}
|
|
235
|
+
});
|
|
236
|
+
if (!originalInvalidEvent) {
|
|
237
|
+
slInvalidEvent.preventDefault();
|
|
238
|
+
}
|
|
239
|
+
if (!this.host.dispatchEvent(slInvalidEvent)) {
|
|
240
|
+
originalInvalidEvent == null ? void 0 : originalInvalidEvent.preventDefault();
|
|
241
|
+
}
|
|
207
242
|
}
|
|
208
243
|
}
|
|
244
|
+
const validValidityState = Object.freeze({
|
|
245
|
+
badInput: false,
|
|
246
|
+
customError: false,
|
|
247
|
+
patternMismatch: false,
|
|
248
|
+
rangeOverflow: false,
|
|
249
|
+
rangeUnderflow: false,
|
|
250
|
+
stepMismatch: false,
|
|
251
|
+
tooLong: false,
|
|
252
|
+
tooShort: false,
|
|
253
|
+
typeMismatch: false,
|
|
254
|
+
valid: true,
|
|
255
|
+
valueMissing: false
|
|
256
|
+
});
|
|
257
|
+
const valueMissingValidityState = Object.freeze({
|
|
258
|
+
...validValidityState,
|
|
259
|
+
valid: false,
|
|
260
|
+
valueMissing: true
|
|
261
|
+
});
|
|
262
|
+
const customErrorValidityState = Object.freeze({
|
|
263
|
+
...validValidityState,
|
|
264
|
+
valid: false,
|
|
265
|
+
customError: true
|
|
266
|
+
});
|
|
209
267
|
export {
|
|
210
268
|
FormControlController,
|
|
211
|
-
|
|
269
|
+
customErrorValidityState,
|
|
270
|
+
formCollections,
|
|
271
|
+
validValidityState,
|
|
272
|
+
valueMissingValidityState
|
|
212
273
|
};
|
|
@@ -20,6 +20,8 @@ export interface SolidFormControl extends SolidElement {
|
|
|
20
20
|
required?: boolean;
|
|
21
21
|
minlength?: number;
|
|
22
22
|
maxlength?: number;
|
|
23
|
+
readonly validity?: ValidityState;
|
|
24
|
+
readonly validationMessage?: string;
|
|
23
25
|
checkValidity: () => boolean;
|
|
24
26
|
reportValidity: () => boolean;
|
|
25
27
|
setCustomValidity: (message: string) => void;
|
|
@@ -50,7 +50,7 @@ let LocalizeController$1 = class LocalizeController {
|
|
|
50
50
|
}
|
|
51
51
|
getTranslationData(lang) {
|
|
52
52
|
var _a, _b;
|
|
53
|
-
const locale = new Intl.Locale(lang);
|
|
53
|
+
const locale = new Intl.Locale(lang.replace(/_/g, "-"));
|
|
54
54
|
const language = locale === null || locale === void 0 ? void 0 : locale.language.toLowerCase();
|
|
55
55
|
const region = (_b = (_a = locale === null || locale === void 0 ? void 0 : locale.region) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : "";
|
|
56
56
|
const primary = translations.get(`${language}-${region}`);
|
|
@@ -13,6 +13,8 @@ export { default as SdInclude } from './components/include/include';
|
|
|
13
13
|
export { default as SdLink } from './components/link/link';
|
|
14
14
|
export { default as SdNavigationItem } from './components/navigation-item/navigation-item';
|
|
15
15
|
export { default as SdPopup } from './components/popup/popup';
|
|
16
|
+
export { default as SdRadio } from './components/radio/radio';
|
|
17
|
+
export { default as SdRadioGroup } from './components/radio-group/radio-group';
|
|
16
18
|
export { default as SdSpinner } from './components/spinner/spinner';
|
|
17
19
|
export { default as SdTag } from './components/tag/tag';
|
|
18
20
|
export { default as SdTeaser } from './components/teaser/teaser';
|
|
@@ -13,10 +13,12 @@ import { default as default13 } from "./components/include/include.js";
|
|
|
13
13
|
import { default as default14 } from "./components/link/link.js";
|
|
14
14
|
import { default as default15 } from "./components/navigation-item/navigation-item.js";
|
|
15
15
|
import { default as default16 } from "./components/popup/popup.js";
|
|
16
|
-
import { default as default17 } from "./components/
|
|
17
|
-
import { default as default18 } from "./components/
|
|
18
|
-
import { default as default19 } from "./components/
|
|
19
|
-
import { default as default20 } from "./components/
|
|
16
|
+
import { default as default17 } from "./components/radio/radio.js";
|
|
17
|
+
import { default as default18 } from "./components/radio-group/radio-group.js";
|
|
18
|
+
import { default as default19 } from "./components/spinner/spinner.js";
|
|
19
|
+
import { default as default20 } from "./components/tag/tag.js";
|
|
20
|
+
import { default as default21 } from "./components/teaser/teaser.js";
|
|
21
|
+
import { default as default22 } from "./components/video/video.js";
|
|
20
22
|
import { registerIconLibrary, unregisterIconLibrary } from "./components/icon/library.js";
|
|
21
23
|
import { LocalizeController } from "./utilities/localize.js";
|
|
22
24
|
export {
|
|
@@ -36,10 +38,12 @@ export {
|
|
|
36
38
|
default14 as SdLink,
|
|
37
39
|
default15 as SdNavigationItem,
|
|
38
40
|
default16 as SdPopup,
|
|
39
|
-
default17 as
|
|
40
|
-
default18 as
|
|
41
|
-
default19 as
|
|
42
|
-
default20 as
|
|
41
|
+
default17 as SdRadio,
|
|
42
|
+
default18 as SdRadioGroup,
|
|
43
|
+
default19 as SdSpinner,
|
|
44
|
+
default20 as SdTag,
|
|
45
|
+
default21 as SdTeaser,
|
|
46
|
+
default22 as SdVideo,
|
|
43
47
|
registerIconLibrary,
|
|
44
48
|
unregisterIconLibrary
|
|
45
49
|
};
|