@felleslosninger/minid-elements 0.0.126 → 0.0.127
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/README.md +37 -22
- package/dist/components/button.component.d.ts +7 -2
- package/dist/components/button.component.d.ts.map +1 -1
- package/dist/components/button.js +4 -8
- package/dist/components/button.js.map +1 -1
- package/dist/components/checkbox.component.d.ts +6 -0
- package/dist/components/checkbox.component.d.ts.map +1 -1
- package/dist/components/checkbox.js +31 -0
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/radio-button.component.d.ts +1 -1
- package/dist/components/radio-button.component.d.ts.map +1 -1
- package/dist/components/radio-button.js +3 -3
- package/dist/components/radio-button.js.map +1 -1
- package/dist/components/radio-group.component.d.ts +13 -5
- package/dist/components/radio-group.component.d.ts.map +1 -1
- package/dist/components/radio-group.js +75 -59
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/radio.component.d.ts +9 -7
- package/dist/components/radio.component.d.ts.map +1 -1
- package/dist/components/radio.js +45 -80
- package/dist/components/radio.js.map +1 -1
- package/dist/designsystemet-tailwind.css +9 -1
- package/dist/icons/arrow-right-left.svg +1 -1
- package/dist/icons/cpu-fill.svg +3 -0
- package/dist/icons/cpu.svg +3 -0
- package/dist/icons/expand-vertical.svg +3 -0
- package/dist/icons/expand.svg +1 -1
- package/dist/icons/file-jpeg-fill.svg +5 -0
- package/dist/icons/file-jpeg.svg +4 -0
- package/dist/icons/file-png-fill.svg +6 -0
- package/dist/icons/file-png.svg +4 -0
- package/dist/icons/line-height.svg +3 -0
- package/dist/icons/medical-thermometer-fill.svg +3 -0
- package/dist/icons/medical-thermometer.svg +3 -0
- package/dist/icons/questionmark-circle-fill.svg +3 -0
- package/dist/icons/questionmark-circle.svg +3 -0
- package/dist/icons/seal-xmark.svg +1 -1
- package/dist/icons/shield-checkmark-fill.svg +3 -0
- package/dist/icons/shield-checkmark.svg +3 -0
- package/dist/icons/shrink.svg +1 -1
- package/dist/icons/sort-down.svg +3 -0
- package/dist/icons/sort-up.svg +3 -0
- package/dist/icons/space-horizontal.svg +3 -0
- package/dist/icons/space-vertical.svg +3 -0
- package/dist/icons/square-grid-fill.svg +3 -0
- package/dist/icons/square-grid.svg +3 -0
- package/dist/icons/thumb-down-fill.svg +1 -1
- package/dist/icons/thumb-down.svg +1 -1
- package/dist/icons/truck-percent-fill.svg +3 -0
- package/dist/icons/truck-percent.svg +3 -0
- package/dist/mixins/tailwind.mixin.js +1 -1
- package/dist/mixins/tailwind.mixin.js.map +1 -1
- package/dist/types/icon-name.d.ts +1 -1
- package/dist/types/icon-name.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -2,9 +2,11 @@ import { css, LitElement, html } from "lit";
|
|
|
2
2
|
import { property, state, customElement } from "lit/decorators.js";
|
|
3
3
|
import { styled } from "../mixins/tailwind.mixin.js";
|
|
4
4
|
import "./label.js";
|
|
5
|
-
import { ConstraintsValidationMixin } from "../mixins/form-controller.mixin.js";
|
|
6
5
|
import { classMap } from "lit/directives/class-map.js";
|
|
7
6
|
import { watch } from "../internal/watch.js";
|
|
7
|
+
import { FormControlMixin } from "../mixins/form-control.mixin.js";
|
|
8
|
+
import { HasSlotController } from "../internal/slot.js";
|
|
9
|
+
import { requiredValidator } from "../mixins/validators.js";
|
|
8
10
|
var __defProp = Object.defineProperty;
|
|
9
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
12
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -20,34 +22,42 @@ const styles = [
|
|
|
20
22
|
:host {
|
|
21
23
|
display: block;
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
.fds-label {
|
|
25
|
-
margin-bottom: 1rem;
|
|
26
|
-
}
|
|
27
25
|
`
|
|
28
26
|
];
|
|
29
|
-
let MinidRadioGroup = class extends
|
|
27
|
+
let MinidRadioGroup = class extends FormControlMixin(
|
|
30
28
|
styled(LitElement, styles)
|
|
31
29
|
) {
|
|
32
30
|
constructor() {
|
|
33
31
|
super(...arguments);
|
|
34
|
-
this.
|
|
32
|
+
this.hasSlotController = new HasSlotController(this, "label");
|
|
33
|
+
this.validationId = `radio-group-${MinidRadioGroup._uniqueId++}`;
|
|
34
|
+
this.name = null;
|
|
35
35
|
this.value = null;
|
|
36
36
|
this.label = "";
|
|
37
|
-
this.size = "md";
|
|
38
37
|
this.labelhidden = false;
|
|
39
38
|
this.disabled = false;
|
|
39
|
+
this.required = false;
|
|
40
|
+
this.invalidmessage = "";
|
|
40
41
|
this.hasButtonRadios = false;
|
|
41
42
|
this.defaultValue = null;
|
|
42
43
|
}
|
|
44
|
+
get validationTarget() {
|
|
45
|
+
const radio = this.querySelector(
|
|
46
|
+
":is(mid-radio):not([disabled])"
|
|
47
|
+
);
|
|
48
|
+
return radio ?? void 0;
|
|
49
|
+
}
|
|
50
|
+
static get formcontrolValidators() {
|
|
51
|
+
return [requiredValidator];
|
|
52
|
+
}
|
|
43
53
|
firstUpdated(_changedProperties) {
|
|
44
54
|
super.firstUpdated(_changedProperties);
|
|
45
55
|
this.defaultValue = this.value;
|
|
46
|
-
this.
|
|
56
|
+
this.setValue(this.value);
|
|
47
57
|
}
|
|
48
|
-
|
|
58
|
+
resetFormControl() {
|
|
49
59
|
this.value = this.defaultValue;
|
|
50
|
-
this.
|
|
60
|
+
this.setValue(this.value);
|
|
51
61
|
this.updateCheckedRadio();
|
|
52
62
|
}
|
|
53
63
|
async syncRadioElements() {
|
|
@@ -60,7 +70,6 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
60
70
|
radios.map(async (radio) => {
|
|
61
71
|
await radio.updateComplete;
|
|
62
72
|
radio.checked = radio.value === this.value;
|
|
63
|
-
radio.size = this.size;
|
|
64
73
|
})
|
|
65
74
|
);
|
|
66
75
|
if (radios.length > 0 && !radios.some((radio) => radio.checked)) {
|
|
@@ -70,7 +79,7 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
70
79
|
buttonRadio.setAttribute("tabindex", "0");
|
|
71
80
|
}
|
|
72
81
|
} else {
|
|
73
|
-
radios[0].
|
|
82
|
+
radios[0].input.setAttribute("tabindex", "0");
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
}
|
|
@@ -110,14 +119,14 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
110
119
|
this.getAllRadios().forEach((radio) => {
|
|
111
120
|
radio.checked = false;
|
|
112
121
|
if (!this.hasButtonRadios) {
|
|
113
|
-
radio.
|
|
122
|
+
radio.input.setAttribute("tabindex", "-1");
|
|
114
123
|
}
|
|
115
124
|
});
|
|
116
125
|
this.value = radios[index].value;
|
|
117
126
|
radios[index].checked = true;
|
|
118
|
-
this.
|
|
127
|
+
this.setValue(this.value);
|
|
119
128
|
if (!this.hasButtonRadios) {
|
|
120
|
-
radios[index].
|
|
129
|
+
radios[index].input.setAttribute("tabindex", "0");
|
|
121
130
|
radios[index].focus();
|
|
122
131
|
} else {
|
|
123
132
|
radios[index].shadowRoot.querySelector("button").focus();
|
|
@@ -133,11 +142,7 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
133
142
|
event.preventDefault();
|
|
134
143
|
}
|
|
135
144
|
getAllRadios() {
|
|
136
|
-
return Array.from(
|
|
137
|
-
this.querySelectorAll(
|
|
138
|
-
"mid-radio, mid-radio-button"
|
|
139
|
-
)
|
|
140
|
-
);
|
|
145
|
+
return Array.from(this.querySelectorAll("mid-radio"));
|
|
141
146
|
}
|
|
142
147
|
updateCheckedRadio() {
|
|
143
148
|
const radios = this.getAllRadios();
|
|
@@ -155,7 +160,7 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
155
160
|
return;
|
|
156
161
|
}
|
|
157
162
|
this.value = target.value;
|
|
158
|
-
this.
|
|
163
|
+
this.setValue(this.value);
|
|
159
164
|
this.updateCheckedRadio();
|
|
160
165
|
if (this.value !== oldValue) {
|
|
161
166
|
this.dispatchEvent(
|
|
@@ -186,6 +191,11 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
186
191
|
}
|
|
187
192
|
});
|
|
188
193
|
}
|
|
194
|
+
handleInvalidChange() {
|
|
195
|
+
this.getAllRadios().forEach((radio) => {
|
|
196
|
+
radio.invalid = !!this.invalidmessage;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
189
199
|
/**
|
|
190
200
|
* Sets focus on the radio-group.
|
|
191
201
|
*/
|
|
@@ -199,52 +209,52 @@ let MinidRadioGroup = class extends ConstraintsValidationMixin(
|
|
|
199
209
|
}
|
|
200
210
|
}
|
|
201
211
|
render() {
|
|
212
|
+
const hasLabelSlot = this.hasSlotController.test("label");
|
|
213
|
+
const hasLabel = this.label ? true : !!hasLabelSlot;
|
|
202
214
|
return html`
|
|
203
|
-
<label
|
|
204
|
-
part="form-control-label"
|
|
205
|
-
id="label"
|
|
206
|
-
class="class=${classMap({
|
|
207
|
-
"fds-label": true,
|
|
208
|
-
"fds-label--spacing": true,
|
|
209
|
-
"fds-label--sm": this.size === "sm",
|
|
210
|
-
"fds-label--md": this.size === "md",
|
|
211
|
-
"fds-label--lg": this.size === "lg",
|
|
212
|
-
"sr-only": this.labelhidden
|
|
213
|
-
})}"
|
|
214
|
-
@click=${this.handleLabelClick}
|
|
215
|
-
>
|
|
216
|
-
${this.label}
|
|
217
|
-
</label>
|
|
218
215
|
<fieldset
|
|
219
|
-
class="
|
|
220
|
-
"fds-togglegroup": this.hasButtonRadios
|
|
221
|
-
})} flex"
|
|
216
|
+
class="flex flex-col gap-2"
|
|
222
217
|
part="form-control"
|
|
223
218
|
role="radiogroup"
|
|
224
219
|
aria-labelledby="label"
|
|
220
|
+
aria-errormessage="${this.validationId}"
|
|
225
221
|
>
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
aria-label=${this.label}
|
|
222
|
+
<label
|
|
223
|
+
part="form-control-label"
|
|
224
|
+
id="label"
|
|
225
|
+
class="class=${classMap({
|
|
226
|
+
"sr-only": this.labelhidden,
|
|
227
|
+
"mb-2": hasLabel
|
|
228
|
+
})} mid-label"
|
|
229
|
+
@click=${this.handleLabelClick}
|
|
235
230
|
>
|
|
236
|
-
<slot
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
231
|
+
<slot name="label">${this.label}</slot>
|
|
232
|
+
</label>
|
|
233
|
+
<slot
|
|
234
|
+
class="flex flex-col flex-wrap gap-3.5"
|
|
235
|
+
@slotchange=${this.syncRadios}
|
|
236
|
+
@click=${this.handleRadioClick}
|
|
237
|
+
@keydown=${this.handleKeyDown}
|
|
238
|
+
></slot>
|
|
242
239
|
</fieldset>
|
|
240
|
+
<div
|
|
241
|
+
class="text-danger-subtle mt-2 flex gap-1"
|
|
242
|
+
id="${this.validationId}"
|
|
243
|
+
aria-live="polite"
|
|
244
|
+
?hidden=${!this.invalidmessage}
|
|
245
|
+
>
|
|
246
|
+
<mid-icon
|
|
247
|
+
name="xmark-octagon-fill"
|
|
248
|
+
class="mt-1 min-h-6 min-w-6"
|
|
249
|
+
></mid-icon>
|
|
250
|
+
${this.invalidmessage}
|
|
251
|
+
</div>
|
|
243
252
|
`;
|
|
244
253
|
}
|
|
245
254
|
};
|
|
255
|
+
MinidRadioGroup._uniqueId = 0;
|
|
246
256
|
__decorateClass([
|
|
247
|
-
property()
|
|
257
|
+
property({ reflect: true })
|
|
248
258
|
], MinidRadioGroup.prototype, "name", 2);
|
|
249
259
|
__decorateClass([
|
|
250
260
|
property({ reflect: true })
|
|
@@ -252,15 +262,18 @@ __decorateClass([
|
|
|
252
262
|
__decorateClass([
|
|
253
263
|
property()
|
|
254
264
|
], MinidRadioGroup.prototype, "label", 2);
|
|
255
|
-
__decorateClass([
|
|
256
|
-
property()
|
|
257
|
-
], MinidRadioGroup.prototype, "size", 2);
|
|
258
265
|
__decorateClass([
|
|
259
266
|
property({ type: Boolean })
|
|
260
267
|
], MinidRadioGroup.prototype, "labelhidden", 2);
|
|
261
268
|
__decorateClass([
|
|
262
269
|
property({ type: Boolean })
|
|
263
270
|
], MinidRadioGroup.prototype, "disabled", 2);
|
|
271
|
+
__decorateClass([
|
|
272
|
+
property({ type: Boolean, reflect: true })
|
|
273
|
+
], MinidRadioGroup.prototype, "required", 2);
|
|
274
|
+
__decorateClass([
|
|
275
|
+
property()
|
|
276
|
+
], MinidRadioGroup.prototype, "invalidmessage", 2);
|
|
264
277
|
__decorateClass([
|
|
265
278
|
state()
|
|
266
279
|
], MinidRadioGroup.prototype, "hasButtonRadios", 2);
|
|
@@ -276,6 +289,9 @@ __decorateClass([
|
|
|
276
289
|
__decorateClass([
|
|
277
290
|
watch("disabled")
|
|
278
291
|
], MinidRadioGroup.prototype, "handleDisabledChange", 1);
|
|
292
|
+
__decorateClass([
|
|
293
|
+
watch("invalidmessage")
|
|
294
|
+
], MinidRadioGroup.prototype, "handleInvalidChange", 1);
|
|
279
295
|
MinidRadioGroup = __decorateClass([
|
|
280
296
|
customElement("mid-radio-group")
|
|
281
297
|
], MinidRadioGroup);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio-group.js","sources":["../../src/components/radio-group.component.ts"],"sourcesContent":["import { css, html, LitElement, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin';\nimport './label.component';\nimport { ConstraintsValidationMixin } from '../mixins/form-controller.mixin';\nimport { MinidRadioButton } from '../components/radio-button.component';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { watch } from '../internal/watch';\nimport { MinidRadio } from '../components/radio.component';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-radio-group': MinidRadioGroup;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n\n .fds-label {\n margin-bottom: 1rem;\n }\n `,\n];\n\n/**\n *\n * @slot -- The default slot where `<mid-radio>` or `<mid-radio-button>` elements are placed.\n *\n * @event mid-change - Emitted when the selected value changes\n * @event mid-input - Emitted when radio group recieves input\n *\n * @csspart form-control-label - Select the label element\n * @csspart form-control - Select the fieldset containing the radios\n * @csspart base - Select the container around the radios\n */\n@customElement('mid-radio-group')\nexport class MinidRadioGroup extends ConstraintsValidationMixin(\n styled(LitElement, styles)\n) {\n /**\n * The name of the radio group.\n */\n @property()\n name = 'option';\n\n /**\n * The current value of the radio group.\n */\n @property({ reflect: true })\n value: string | null = null;\n\n @property()\n label = '';\n\n @property()\n size: 'sm' | 'md' | 'lg' = 'md';\n\n @property({ type: Boolean })\n labelhidden = false;\n\n @property({ type: Boolean })\n disabled = false;\n\n @state()\n private hasButtonRadios = false;\n\n @state()\n defaultValue: string | null = null;\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n this.defaultValue = this.value;\n this.setFormValue(this.value);\n }\n\n protected formResetCallback() {\n this.value = this.defaultValue;\n this.setFormValue(this.value);\n this.updateCheckedRadio();\n }\n\n private async syncRadioElements() {\n const radios = this.getAllRadios();\n this.hasButtonRadios = radios.some(\n (radio) => radio.tagName.toLowerCase() === 'mid-radio-button'\n );\n\n await Promise.all(\n // Sync the checked state and size\n radios.map(async (radio) => {\n await radio.updateComplete;\n radio.checked = radio.value === this.value;\n radio.size = this.size;\n })\n );\n\n if (radios.length > 0 && !radios.some((radio) => radio.checked)) {\n if (this.hasButtonRadios) {\n const buttonRadio = radios[0].shadowRoot?.querySelector('button');\n if (buttonRadio) {\n buttonRadio.setAttribute('tabindex', '0');\n }\n } else {\n radios[0].element.setAttribute('tabindex', '0');\n }\n }\n }\n\n private syncRadios() {\n if (\n customElements.get('mid-radio') &&\n customElements.get('mid-radio-button')\n ) {\n this.syncRadioElements();\n return;\n }\n\n if (customElements.get('mid-radio')) {\n this.syncRadioElements();\n } else {\n customElements.whenDefined('mid-radio').then(() => this.syncRadios());\n }\n\n if (customElements.get('mid-radio-button')) {\n this.syncRadioElements();\n } else {\n // Rerun this handler when <mid-radio> or <mid-radio-button> is registered\n customElements\n .whenDefined('mid-radio-button')\n .then(() => this.syncRadios());\n }\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n if (\n !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(\n event.key\n )\n ) {\n return;\n }\n\n const radios = this.getAllRadios().filter((radio) => !radio.disabled);\n const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0];\n const incr =\n event.key === ' '\n ? 0\n : ['ArrowUp', 'ArrowLeft'].includes(event.key)\n ? -1\n : 1;\n const oldValue = this.value;\n let index = radios.indexOf(checkedRadio) + incr;\n\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index > radios.length - 1) {\n index = 0;\n }\n\n this.getAllRadios().forEach((radio) => {\n radio.checked = false;\n\n if (!this.hasButtonRadios) {\n radio.element.setAttribute('tabindex', '-1');\n }\n });\n\n this.value = radios[index].value;\n radios[index].checked = true;\n this.setFormValue(this.value);\n\n if (!this.hasButtonRadios) {\n radios[index].element.setAttribute('tabindex', '0');\n radios[index].focus();\n } else {\n radios[index].shadowRoot!.querySelector('button')!.focus();\n }\n\n if (this.value !== oldValue) {\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n event.preventDefault();\n }\n\n private getAllRadios() {\n return Array.from(\n this.querySelectorAll<MinidRadioButton | MinidRadio>(\n 'mid-radio, mid-radio-button'\n )\n );\n }\n\n private updateCheckedRadio() {\n const radios = this.getAllRadios();\n radios.forEach((radio) => {\n radio.checked = radio.value === this.value;\n });\n }\n\n private handleLabelClick() {\n this.focus();\n }\n\n private handleRadioClick(event: MouseEvent) {\n const target = (event.target as HTMLElement).closest<\n MinidRadioButton | MinidRadio\n >('mid-radio, mid-radio-button')!;\n // const radios = this.getAllRadios();\n\n const oldValue = this.value;\n\n if (!target || target.disabled) {\n return;\n }\n\n this.value = target.value;\n this.setFormValue(this.value);\n\n this.updateCheckedRadio();\n\n if (this.value !== oldValue) {\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n }\n\n @watch('size', { waitUntilFirstUpdate: true })\n handleSizeChange() {\n this.syncRadios();\n }\n\n @watch('value')\n handleValueChange() {\n if (this.hasUpdated) {\n this.updateCheckedRadio();\n }\n }\n\n @watch('disabled')\n handleDisabledChange() {\n const radios = this.getAllRadios();\n const every = radios.every((radio) => radio.disabled);\n const some = radios.some((radio) => radio.disabled);\n radios.forEach((radio) => {\n if (every === some) {\n radio.disabled = this.disabled;\n } else if (this.disabled) {\n radio.disabled = true;\n }\n });\n }\n\n /**\n * Sets focus on the radio-group.\n */\n public focus(options?: FocusOptions) {\n const radios = this.getAllRadios();\n const checked = radios.find((radio) => radio.checked);\n const firstEnabledRadio = radios.find((radio) => !radio.disabled);\n\n const radioToFocus = checked || firstEnabledRadio;\n\n // Call focus for the checked radio\n // If no radio is checked, focus the first one that is not disabled\n if (radioToFocus) {\n radioToFocus.focus(options);\n }\n }\n\n override render() {\n return html`\n <label\n part=\"form-control-label\"\n id=\"label\"\n class=\"class=${classMap({\n 'fds-label': true,\n 'fds-label--spacing': true,\n 'fds-label--sm': this.size === 'sm',\n 'fds-label--md': this.size === 'md',\n 'fds-label--lg': this.size === 'lg',\n 'sr-only': this.labelhidden,\n })}\"\n @click=${this.handleLabelClick}\n >\n ${this.label}\n </label>\n <fieldset\n class=\"${classMap({\n 'fds-togglegroup': this.hasButtonRadios,\n })} flex\"\n part=\"form-control\"\n role=\"radiogroup\"\n aria-labelledby=\"label\"\n >\n <div\n class=\"${classMap({\n grid: true,\n 'gap-3': true,\n 'fds-togglegroup__content': this.hasButtonRadios,\n })}\"\n part=\"base\"\n role=\"presentation\"\n aria-label=${this.label}\n >\n <slot\n @slotchange=${this.syncRadios}\n @click=${this.handleRadioClick}\n @keydown=${this.handleKeyDown}\n ></slot>\n </div>\n </fieldset>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"radio-group.js","sources":["../../src/components/radio-group.component.ts"],"sourcesContent":["import { css, html, LitElement, type PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { styled } from '../mixins/tailwind.mixin';\nimport './label.component';\nimport { MinidRadioButton } from '../components/radio-button.component';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { watch } from '../internal/watch';\nimport { MinidRadio } from '../components/radio.component';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport { HasSlotController } from '../internal/slot';\nimport { requiredValidator } from 'src/mixins/validators';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-radio-group': MinidRadioGroup;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: block;\n }\n `,\n];\n\n/**\n *\n * @slot -- The default slot where `<mid-radio>` or `<mid-radio-button>` elements are placed.\n *\n * @event mid-change - Emitted when the selected value changes\n * @event mid-input - Emitted when radio group recieves input\n *\n * @csspart form-control-label - Select the label element\n * @csspart form-control - Select the fieldset containing the radios\n * @csspart base - Select the container around the radios\n */\n@customElement('mid-radio-group')\nexport class MinidRadioGroup extends FormControlMixin(\n styled(LitElement, styles)\n) {\n private readonly hasSlotController = new HasSlotController(this, 'label');\n private readonly validationId = `radio-group-${MinidRadioGroup._uniqueId++}`;\n private static _uniqueId = 0;\n /**\n * The name of the radio group, submitted as a name/value pair with form data.\n */\n @property({ reflect: true })\n name: string | null = null;\n\n /**\n * The current value of the radio group.\n */\n @property({ reflect: true })\n value: string | null = null;\n\n @property()\n label = '';\n\n @property({ type: Boolean })\n labelhidden = false;\n\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n required = false;\n\n @property()\n invalidmessage = '';\n\n @state()\n private hasButtonRadios = false;\n\n @state()\n defaultValue: string | null = null;\n\n get validationTarget() {\n const radio = this.querySelector<MinidRadio>(\n ':is(mid-radio):not([disabled])'\n );\n return radio ?? undefined;\n }\n\n static get formcontrolValidators() {\n return [requiredValidator];\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n super.firstUpdated(_changedProperties);\n this.defaultValue = this.value;\n this.setValue(this.value);\n }\n\n resetFormControl() {\n this.value = this.defaultValue;\n this.setValue(this.value);\n this.updateCheckedRadio();\n }\n\n private async syncRadioElements() {\n const radios = this.getAllRadios();\n this.hasButtonRadios = radios.some(\n (radio) => radio.tagName.toLowerCase() === 'mid-radio-button'\n );\n\n await Promise.all(\n // Sync the checked state and size\n radios.map(async (radio) => {\n await radio.updateComplete;\n radio.checked = radio.value === this.value;\n })\n );\n\n if (radios.length > 0 && !radios.some((radio) => radio.checked)) {\n if (this.hasButtonRadios) {\n const buttonRadio = radios[0].shadowRoot?.querySelector('button');\n if (buttonRadio) {\n buttonRadio.setAttribute('tabindex', '0');\n }\n } else {\n radios[0].input.setAttribute('tabindex', '0');\n }\n }\n }\n\n private syncRadios() {\n if (\n customElements.get('mid-radio') &&\n customElements.get('mid-radio-button')\n ) {\n this.syncRadioElements();\n return;\n }\n\n if (customElements.get('mid-radio')) {\n this.syncRadioElements();\n } else {\n customElements.whenDefined('mid-radio').then(() => this.syncRadios());\n }\n\n if (customElements.get('mid-radio-button')) {\n this.syncRadioElements();\n } else {\n // Rerun this handler when <mid-radio> or <mid-radio-button> is registered\n customElements\n .whenDefined('mid-radio-button')\n .then(() => this.syncRadios());\n }\n }\n\n private handleKeyDown(event: KeyboardEvent) {\n if (\n !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(\n event.key\n )\n ) {\n return;\n }\n\n const radios = this.getAllRadios().filter((radio) => !radio.disabled);\n const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0];\n const incr =\n event.key === ' '\n ? 0\n : ['ArrowUp', 'ArrowLeft'].includes(event.key)\n ? -1\n : 1;\n const oldValue = this.value;\n let index = radios.indexOf(checkedRadio) + incr;\n\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index > radios.length - 1) {\n index = 0;\n }\n\n this.getAllRadios().forEach((radio) => {\n radio.checked = false;\n\n if (!this.hasButtonRadios) {\n radio.input.setAttribute('tabindex', '-1');\n }\n });\n\n this.value = radios[index].value;\n radios[index].checked = true;\n this.setValue(this.value);\n\n if (!this.hasButtonRadios) {\n radios[index].input.setAttribute('tabindex', '0');\n radios[index].focus();\n } else {\n radios[index].shadowRoot!.querySelector('button')!.focus();\n }\n\n if (this.value !== oldValue) {\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n\n event.preventDefault();\n }\n\n private getAllRadios() {\n return Array.from(this.querySelectorAll<MinidRadio>('mid-radio'));\n }\n\n private updateCheckedRadio() {\n const radios = this.getAllRadios();\n radios.forEach((radio) => {\n radio.checked = radio.value === this.value;\n });\n }\n\n private handleLabelClick() {\n this.focus();\n }\n\n private handleRadioClick(event: MouseEvent) {\n const target = (event.target as HTMLElement).closest<\n MinidRadioButton | MinidRadio\n >('mid-radio, mid-radio-button')!;\n // const radios = this.getAllRadios();\n\n const oldValue = this.value;\n\n if (!target || target.disabled) {\n return;\n }\n\n this.value = target.value;\n this.setValue(this.value);\n\n this.updateCheckedRadio();\n\n if (this.value !== oldValue) {\n this.dispatchEvent(\n new Event('mid-change', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new Event('mid-input', { bubbles: true, composed: true })\n );\n }\n }\n\n @watch('size', { waitUntilFirstUpdate: true })\n handleSizeChange() {\n this.syncRadios();\n }\n\n @watch('value')\n handleValueChange() {\n if (this.hasUpdated) {\n this.updateCheckedRadio();\n }\n }\n\n @watch('disabled')\n handleDisabledChange() {\n const radios = this.getAllRadios();\n const every = radios.every((radio) => radio.disabled);\n const some = radios.some((radio) => radio.disabled);\n radios.forEach((radio) => {\n if (every === some) {\n radio.disabled = this.disabled;\n } else if (this.disabled) {\n radio.disabled = true;\n }\n });\n }\n\n @watch('invalidmessage')\n handleInvalidChange() {\n this.getAllRadios().forEach((radio) => {\n radio.invalid = !!this.invalidmessage;\n });\n }\n\n /**\n * Sets focus on the radio-group.\n */\n public focus(options?: FocusOptions) {\n const radios = this.getAllRadios();\n const checked = radios.find((radio) => radio.checked);\n const firstEnabledRadio = radios.find((radio) => !radio.disabled);\n\n const radioToFocus = checked || firstEnabledRadio;\n\n // Call focus for the checked radio\n // If no radio is checked, focus the first one that is not disabled\n if (radioToFocus) {\n radioToFocus.focus(options);\n }\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotController.test('label');\n const hasLabel = this.label ? true : !!hasLabelSlot;\n\n return html`\n <fieldset\n class=\"flex flex-col gap-2\"\n part=\"form-control\"\n role=\"radiogroup\"\n aria-labelledby=\"label\"\n aria-errormessage=\"${this.validationId}\"\n >\n <label\n part=\"form-control-label\"\n id=\"label\"\n class=\"class=${classMap({\n 'sr-only': this.labelhidden,\n 'mb-2': hasLabel,\n })} mid-label\"\n @click=${this.handleLabelClick}\n >\n <slot name=\"label\">${this.label}</slot>\n </label>\n <slot\n class=\"flex flex-col flex-wrap gap-3.5\"\n @slotchange=${this.syncRadios}\n @click=${this.handleRadioClick}\n @keydown=${this.handleKeyDown}\n ></slot>\n </fieldset>\n <div\n class=\"text-danger-subtle mt-2 flex gap-1\"\n id=\"${this.validationId}\"\n aria-live=\"polite\"\n ?hidden=${!this.invalidmessage}\n >\n <mid-icon\n name=\"xmark-octagon-fill\"\n class=\"mt-1 min-h-6 min-w-6\"\n ></mid-icon>\n ${this.invalidmessage}\n </div>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ declare global {
|
|
|
4
4
|
'mid-radio': MinidRadio;
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
|
-
declare const MinidRadio_base: typeof LitElement;
|
|
7
|
+
declare const MinidRadio_base: import('../types/mixin-constructor.ts').Constructor<import('../types/form-control.ts').FormControlInterface> & typeof LitElement;
|
|
8
8
|
/**
|
|
9
9
|
*
|
|
10
10
|
* @slot -- The radio's label
|
|
@@ -16,7 +16,10 @@ declare const MinidRadio_base: typeof LitElement;
|
|
|
16
16
|
* @csspart label - Select the label element
|
|
17
17
|
*/
|
|
18
18
|
export declare class MinidRadio extends MinidRadio_base {
|
|
19
|
-
|
|
19
|
+
input: HTMLInputElement;
|
|
20
|
+
/**
|
|
21
|
+
* The name of the radio, used to bind together multiple radios.
|
|
22
|
+
*/
|
|
20
23
|
name: string;
|
|
21
24
|
/**
|
|
22
25
|
* The radio button's checked state.
|
|
@@ -30,13 +33,12 @@ export declare class MinidRadio extends MinidRadio_base {
|
|
|
30
33
|
* Disables the radio button.
|
|
31
34
|
*/
|
|
32
35
|
disabled: boolean;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*/
|
|
37
|
-
size: 'sm' | 'md' | 'lg';
|
|
36
|
+
invalid: boolean;
|
|
37
|
+
shouldFormValueUpdate(): boolean;
|
|
38
|
+
get validationTarget(): HTMLInputElement;
|
|
38
39
|
constructor();
|
|
39
40
|
connectedCallback(): void;
|
|
41
|
+
private handleKeydown;
|
|
40
42
|
private handleBlur;
|
|
41
43
|
private handleFocus;
|
|
42
44
|
private handleClick;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.component.d.ts","sourceRoot":"","sources":["../../src/components/radio.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAO5C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,UAAU,CAAC;KACzB;CACF;;
|
|
1
|
+
{"version":3,"file":"radio.component.d.ts","sourceRoot":"","sources":["../../src/components/radio.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAO5C,OAAO,0BAA0B,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,UAAU,CAAC;KACzB;CACF;;AAcD;;;;;;;;;GASG;AACH,qBACa,UAAW,SAAQ,eAA4C;IAE1E,KAAK,EAAG,gBAAgB,CAAC;IAEzB;;OAEG;IAEH,IAAI,SAAY;IAEhB;;OAEG;IAEH,OAAO,UAAS;IAEhB;;OAEG;IAEH,KAAK,SAAM;IAEX;;OAEG;IAEH,QAAQ,UAAS;IAGjB,OAAO,UAAS;IAEhB,qBAAqB,IAAI,OAAO;IAIhC,IAAI,gBAAgB,qBAEnB;;IASD,iBAAiB;IAQjB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,WAAW;IAYnB,oBAAoB;IAKpB,iBAAiB;IAIjB;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY;IAInB,MAAM;CAwBhB"}
|
package/dist/components/radio.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { css, LitElement, html } from "lit";
|
|
2
2
|
import { query, property, customElement } from "lit/decorators.js";
|
|
3
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
4
3
|
import { live } from "lit/directives/live.js";
|
|
4
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
5
5
|
import { watch } from "../internal/watch.js";
|
|
6
6
|
import { styled } from "../mixins/tailwind.mixin.js";
|
|
7
|
+
import { FormControlMixin } from "../mixins/form-control.mixin.js";
|
|
8
|
+
import "./icon/icon.js";
|
|
7
9
|
var __defProp = Object.defineProperty;
|
|
8
10
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
11
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -17,78 +19,48 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
17
19
|
const styles = [
|
|
18
20
|
css`
|
|
19
21
|
:host {
|
|
20
|
-
|
|
21
|
-
--color-border: #7a818c;
|
|
22
|
-
|
|
23
|
-
color: white;
|
|
24
|
-
padding: 0.25rem 0;
|
|
25
|
-
display: grid;
|
|
26
|
-
grid-template-columns: auto 1fr;
|
|
27
|
-
gap: 0.5rem;
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
font-weight: 400;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
:host > * {
|
|
22
|
+
display: inline-flex;
|
|
33
23
|
cursor: pointer;
|
|
34
24
|
}
|
|
35
|
-
|
|
36
|
-
:host:has(input:focus-visible) {
|
|
37
|
-
--fds-focus-border-width: 3px;
|
|
38
|
-
box-shadow: 0 0 0 var(--fds-focus-border-width)
|
|
39
|
-
var(--fds-semantic-border-focus-boxshadow);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
:host:has(input:disabled),
|
|
43
|
-
:host:has(input:disabled) > * {
|
|
25
|
+
:host:has(input:disabled) {
|
|
44
26
|
cursor: not-allowed;
|
|
45
27
|
}
|
|
46
|
-
|
|
47
|
-
:host:has(input:disabled) > * {
|
|
48
|
-
opacity: 0.3;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.label {
|
|
52
|
-
font-weight: 400;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.radio {
|
|
56
|
-
-webkit-appearance: none;
|
|
57
|
-
appearance: none;
|
|
58
|
-
|
|
59
|
-
border-radius: 999px;
|
|
60
|
-
display: grid;
|
|
61
|
-
place-content: center;
|
|
62
|
-
border: 2px solid var(--color-border);
|
|
63
|
-
transform: translateY(-0.075em);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.radio:checked {
|
|
67
|
-
border-color: var(--color-checked);
|
|
68
|
-
background:
|
|
69
|
-
radial-gradient(circle closest-side, currentcolor 45%, transparent 50%),
|
|
70
|
-
var(--color-checked);
|
|
71
|
-
}
|
|
72
28
|
`
|
|
73
29
|
];
|
|
74
|
-
let MinidRadio = class extends styled(LitElement, styles) {
|
|
30
|
+
let MinidRadio = class extends FormControlMixin(styled(LitElement, styles)) {
|
|
75
31
|
constructor() {
|
|
76
32
|
super();
|
|
77
33
|
this.name = "option";
|
|
78
34
|
this.checked = false;
|
|
79
35
|
this.value = "";
|
|
80
36
|
this.disabled = false;
|
|
81
|
-
this.
|
|
37
|
+
this.invalid = false;
|
|
82
38
|
this.addEventListener("blur", this.handleBlur);
|
|
83
39
|
this.addEventListener("click", this.handleClick);
|
|
84
40
|
this.addEventListener("focus", this.handleFocus);
|
|
85
41
|
}
|
|
42
|
+
shouldFormValueUpdate() {
|
|
43
|
+
return this.checked;
|
|
44
|
+
}
|
|
45
|
+
get validationTarget() {
|
|
46
|
+
return this.input;
|
|
47
|
+
}
|
|
86
48
|
connectedCallback() {
|
|
87
49
|
super.connectedCallback();
|
|
88
50
|
this.setAttribute("role", "presentation");
|
|
89
51
|
this.setAttribute("aria-disabled", this.disabled ? "true" : "false");
|
|
90
52
|
this.classList.add("rounded");
|
|
91
53
|
}
|
|
54
|
+
handleKeydown(event) {
|
|
55
|
+
const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
|
56
|
+
if (event.key === "Enter" && !hasModifier) {
|
|
57
|
+
setTimeout(() => {
|
|
58
|
+
if (!event.defaultPrevented && !event.isComposing) {
|
|
59
|
+
this.form.requestSubmit();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
92
64
|
handleBlur() {
|
|
93
65
|
this.classList.remove("shadow-focus-visible");
|
|
94
66
|
this.dispatchEvent(
|
|
@@ -111,55 +83,48 @@ let MinidRadio = class extends styled(LitElement, styles) {
|
|
|
111
83
|
return;
|
|
112
84
|
}
|
|
113
85
|
this.checked = true;
|
|
86
|
+
this.dispatchEvent(new Event("mid-change"));
|
|
114
87
|
}
|
|
115
88
|
handleDisabledChange() {
|
|
116
89
|
this.setAttribute("aria-disabled", this.disabled ? "true" : "false");
|
|
117
90
|
}
|
|
118
91
|
handleCheckChange() {
|
|
119
|
-
this.
|
|
92
|
+
this.input.checked = this.checked;
|
|
120
93
|
}
|
|
121
94
|
/**
|
|
122
95
|
* Sets focus on the radio button.
|
|
123
96
|
*/
|
|
124
97
|
focus(options) {
|
|
125
|
-
this.
|
|
98
|
+
this.input.focus(options);
|
|
126
99
|
}
|
|
127
100
|
render() {
|
|
128
101
|
return html`
|
|
129
|
-
<input
|
|
130
|
-
type="radio"
|
|
131
|
-
part="radio"
|
|
132
|
-
name="${this.name}"
|
|
133
|
-
class="${classMap({
|
|
134
|
-
radio: true,
|
|
135
|
-
"h-7": this.size === "lg",
|
|
136
|
-
"w-7": this.size === "lg",
|
|
137
|
-
"w-6": this.size === "md",
|
|
138
|
-
"h-6": this.size === "md",
|
|
139
|
-
"w-5": this.size === "sm",
|
|
140
|
-
"h-5": this.size === "sm"
|
|
141
|
-
})} shadow-none"
|
|
142
|
-
?checked=${live(this.checked)}
|
|
143
|
-
?disabled=${this.disabled}
|
|
144
|
-
/>
|
|
145
102
|
<label
|
|
146
103
|
part="label"
|
|
147
|
-
class="
|
|
148
|
-
label: true,
|
|
149
|
-
"fds-label": true,
|
|
150
|
-
"fds-label--sm": this.size === "sm",
|
|
151
|
-
"fds-label--md": this.size === "md",
|
|
152
|
-
"fds-label--lg": this.size === "lg"
|
|
153
|
-
})}"
|
|
104
|
+
class="has-disabled:opacity-disabled grid cursor-pointer grid-cols-[auto_1fr] gap-2 has-disabled:cursor-not-allowed"
|
|
154
105
|
>
|
|
106
|
+
<input
|
|
107
|
+
type="radio"
|
|
108
|
+
part="radio"
|
|
109
|
+
name="${this.name}"
|
|
110
|
+
class="${classMap({
|
|
111
|
+
"bg-neutral": !this.invalid,
|
|
112
|
+
"border-neutral": !this.invalid,
|
|
113
|
+
"bg-danger-tinted": this.invalid,
|
|
114
|
+
"border-danger-base": this.invalid
|
|
115
|
+
})} checked:bg-accent-base checked:before:bg-neutral focus-visible:focus-ring-sm checked:border-accent-base my-0.5 grid size-6 cursor-pointer appearance-none place-content-center rounded-full border-2 p-0.5 shadow-none before:size-2.5 before:scale-0 before:rounded-full before:transition-transform before:duration-100 checked:before:scale-100 disabled:cursor-not-allowed"
|
|
116
|
+
?checked=${live(this.checked)}
|
|
117
|
+
?disabled=${this.disabled}
|
|
118
|
+
@keydown=${this.handleKeydown}
|
|
119
|
+
/>
|
|
155
120
|
<slot></slot>
|
|
156
121
|
</label>
|
|
157
122
|
`;
|
|
158
123
|
}
|
|
159
124
|
};
|
|
160
125
|
__decorateClass([
|
|
161
|
-
query("
|
|
162
|
-
], MinidRadio.prototype, "
|
|
126
|
+
query('input[type="radio"]')
|
|
127
|
+
], MinidRadio.prototype, "input", 2);
|
|
163
128
|
__decorateClass([
|
|
164
129
|
property()
|
|
165
130
|
], MinidRadio.prototype, "name", 2);
|
|
@@ -173,8 +138,8 @@ __decorateClass([
|
|
|
173
138
|
property({ type: Boolean, reflect: true })
|
|
174
139
|
], MinidRadio.prototype, "disabled", 2);
|
|
175
140
|
__decorateClass([
|
|
176
|
-
property({
|
|
177
|
-
], MinidRadio.prototype, "
|
|
141
|
+
property({ type: Boolean })
|
|
142
|
+
], MinidRadio.prototype, "invalid", 2);
|
|
178
143
|
__decorateClass([
|
|
179
144
|
watch("disabled", { waitUntilFirstUpdate: true })
|
|
180
145
|
], MinidRadio.prototype, "handleDisabledChange", 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.js","sources":["../../src/components/radio.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport {
|
|
1
|
+
{"version":3,"file":"radio.js","sources":["../../src/components/radio.component.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { live } from 'lit/directives/live.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { watch } from '../internal/watch';\nimport { styled } from '../mixins/tailwind.mixin';\nimport { FormControlMixin } from '../mixins/form-control.mixin';\nimport './icon/icon.component.ts';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mid-radio': MinidRadio;\n }\n}\n\nconst styles = [\n css`\n :host {\n display: inline-flex;\n cursor: pointer;\n }\n :host:has(input:disabled) {\n cursor: not-allowed;\n }\n `,\n];\n\n/**\n *\n * @slot -- The radio's label\n *\n * @event mid-blur - Emitted when the control loses focus.\n * @event mid-focus - Emitted when the control gains focus.\n *\n * @csspart radio - Select the radio input element\n * @csspart label - Select the label element\n */\n@customElement('mid-radio')\nexport class MinidRadio extends FormControlMixin(styled(LitElement, styles)) {\n @query('input[type=\"radio\"]')\n input!: HTMLInputElement;\n\n /**\n * The name of the radio, used to bind together multiple radios.\n */\n @property()\n name = 'option';\n\n /**\n * The radio button's checked state.\n */\n @property({ type: Boolean, reflect: true })\n checked = false;\n\n /**\n * The radio's value. When selected, the radio group will receive this value.\n */\n @property()\n value = '';\n\n /**\n * Disables the radio button.\n */\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean })\n invalid = false;\n\n shouldFormValueUpdate(): boolean {\n return this.checked;\n }\n\n get validationTarget() {\n return this.input;\n }\n\n constructor() {\n super();\n this.addEventListener('blur', this.handleBlur);\n this.addEventListener('click', this.handleClick);\n this.addEventListener('focus', this.handleFocus);\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'presentation');\n this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');\n\n this.classList.add('rounded');\n }\n\n private handleKeydown(event: KeyboardEvent) {\n const hasModifier =\n event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;\n\n // Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before\n // submitting to allow users to cancel the keydown event if they need to\n if (event.key === 'Enter' && !hasModifier) {\n setTimeout(() => {\n //\n // When using an Input Method Editor (IME), pressing enter will cause the form to submit unexpectedly. One way\n // to check for this is to look at event.isComposing, which will be true when the IME is open.\n if (!event.defaultPrevented && !event.isComposing) {\n this.form.requestSubmit();\n }\n });\n }\n }\n\n private handleBlur() {\n this.classList.remove('shadow-focus-visible');\n this.dispatchEvent(\n new Event('mid-blur', { composed: true, bubbles: true })\n );\n }\n\n private handleFocus() {\n if (this.disabled) {\n return;\n }\n\n this.focus();\n this.dispatchEvent(\n new Event('mid-focus', { composed: true, bubbles: true })\n );\n }\n\n private handleClick(event: MouseEvent) {\n if (this.disabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n this.checked = true;\n this.dispatchEvent(new Event('mid-change'));\n }\n\n @watch('disabled', { waitUntilFirstUpdate: true })\n handleDisabledChange() {\n this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');\n }\n\n @watch('checked', { waitUntilFirstUpdate: true })\n handleCheckChange() {\n this.input.checked = this.checked;\n }\n\n /**\n * Sets focus on the radio button.\n */\n focus(options?: FocusOptions) {\n this.input.focus(options);\n }\n\n override render() {\n return html`\n <label\n part=\"label\"\n class=\"has-disabled:opacity-disabled grid cursor-pointer grid-cols-[auto_1fr] gap-2 has-disabled:cursor-not-allowed\"\n >\n <input\n type=\"radio\"\n part=\"radio\"\n name=\"${this.name}\"\n class=\"${classMap({\n 'bg-neutral': !this.invalid,\n 'border-neutral': !this.invalid,\n 'bg-danger-tinted': this.invalid,\n 'border-danger-base': this.invalid,\n })} checked:bg-accent-base checked:before:bg-neutral focus-visible:focus-ring-sm checked:border-accent-base my-0.5 grid size-6 cursor-pointer appearance-none place-content-center rounded-full border-2 p-0.5 shadow-none before:size-2.5 before:scale-0 before:rounded-full before:transition-transform before:duration-100 checked:before:scale-100 disabled:cursor-not-allowed\"\n ?checked=${live(this.checked)}\n ?disabled=${this.disabled}\n @keydown=${this.handleKeydown}\n />\n <slot></slot>\n </label>\n `;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -355,11 +355,19 @@
|
|
|
355
355
|
@apply border-accent-base bg-accent-tinted;
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
-
.mid-menu-item:focus {
|
|
358
|
+
.mid-menu-item:focus-visible {
|
|
359
359
|
@apply border-accent-base bg-accent-tinted outline-0;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
362
|
.mid-menu-item:active {
|
|
363
363
|
@apply border-accent-base bg-accent-tinted;
|
|
364
364
|
}
|
|
365
|
+
|
|
366
|
+
.mid-button {
|
|
367
|
+
@apply bg-accent-base text-accent-base-contrast hover:bg-accent-base-hover active:bg-accent-base-active focus-visible:focus-ring leading-sm flex h-fit min-h-12 min-w-12 grow cursor-pointer items-center justify-center gap-2 rounded border border-transparent px-4 py-2 font-medium;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.mid-label {
|
|
371
|
+
@apply inline-block font-medium;
|
|
372
|
+
}
|
|
365
373
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
<svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.53015 21.0304C7.23725 21.3233 6.76238 21.3233 6.46949 21.0304L2.96949 17.5304C2.67659 17.2375 2.67659 16.7627 2.96949 16.4698L6.46949 12.9698C6.76238 12.6769 7.23725 12.6769 7.53015 12.9698C7.82304 13.2627 7.82304 13.7375 7.53015 14.0304L5.31048 16.2501L14.4998 16.2501C14.914 16.2501 15.2498 16.5859 15.2498 17.0001C15.2498 17.4143 14.914 17.7501 14.4998 17.7501L5.31048 17.7501L7.53015 19.9698C7.82304 20.2627 7.82304 20.7375 7.53015 21.0304ZM16.4695 11.0304C16.1766 10.7375 16.1766 10.2627 16.4695 9.96976L18.6892 7.75009L9.49982 7.75009C9.0856 7.75009 8.74982 7.4143 8.74982 7.00009C8.74982 6.58588 9.0856 6.25009 9.49982 6.25009L18.6892 6.25009L16.4695 4.03042C16.1766 3.73753 16.1766 3.26266 16.4695 2.96976C16.7624 2.67687 17.2373 2.67687 17.5301 2.96976L21.0301 6.46976C21.1708 6.61041 21.2498 6.80118 21.2498 7.00009C21.2498 7.19901 21.1708 7.38977 21.0301 7.53042L17.5301 11.0304C17.2373 11.3233 16.7624 11.3233 16.4695 11.0304Z" fill="currentColor"/>
|
|
3
3
|
</svg>
|