@reliability-design/web 1.4.5 → 1.4.6
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/rel-alert/rel-alert.ts +1 -1
- package/dist/components/rel-autocomplete/rel-autocomplete.ts +33 -2
- package/dist/components/rel-badge/rel-badge.ts +6 -1
- package/dist/components/rel-calendar/rel-calendar.ts +64 -18
- package/dist/components/rel-carousel/rel-carousel.ts +25 -2
- package/dist/components/rel-chip/rel-chip.ts +31 -20
- package/dist/components/rel-date-picker/date-parse.test.ts +116 -0
- package/dist/components/rel-date-picker/date-parse.ts +178 -0
- package/dist/components/rel-date-picker/rel-date-picker.ts +529 -90
- package/dist/components/rel-drawer/rel-drawer.ts +6 -3
- package/dist/components/rel-menu/rel-menu.ts +6 -0
- package/dist/components/rel-otp/rel-otp.ts +12 -2
- package/dist/components/rel-pagination/rel-pagination.ts +13 -0
- package/dist/components/rel-popover/rel-popover.ts +33 -2
- package/dist/components/rel-progress/rel-progress.ts +13 -4
- package/dist/components/rel-radio/README.md +6 -3
- package/dist/components/rel-radio/rel-radio.ts +236 -60
- package/dist/components/rel-range-picker/rel-range-picker.ts +452 -95
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +5 -1
- package/dist/components/rel-select/rel-select.ts +44 -13
- package/dist/components/rel-sheet/rel-sheet.ts +163 -18
- package/dist/components/rel-sidebar/rel-sidebar.ts +7 -1
- package/dist/components/rel-skeleton/rel-skeleton.ts +9 -0
- package/dist/components/rel-slider/rel-slider.ts +6 -3
- package/dist/components/rel-snackbar/rel-snackbar.ts +20 -16
- package/dist/components/rel-stepper/rel-stepper.ts +3 -1
- package/dist/components/rel-switch/rel-switch.ts +3 -1
- package/dist/components/rel-textfield/rel-textfield.ts +263 -75
- package/dist/components/rel-time-picker/rel-time-picker.ts +450 -94
- package/dist/components/rel-time-picker/time-parse.test.ts +67 -0
- package/dist/components/rel-time-picker/time-parse.ts +85 -0
- package/dist/components/rel-toast/rel-toast.ts +4 -2
- package/dist/components/rel-tooltip/README.md +13 -5
- package/dist/components/rel-tooltip/rel-tooltip.ts +3 -0
- package/dist/components/rel-upload/rel-upload.ts +25 -0
- package/dist/index.d.mts +241 -11
- package/dist/index.d.ts +241 -11
- package/dist/index.js +2573 -598
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2614 -640
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { LitElement, html, css } from "lit";
|
|
1
|
+
import { LitElement, html, css, nothing, type PropertyValues } from "lit";
|
|
2
2
|
import { customElement, property } from "lit/decorators.js";
|
|
3
|
+
import "@reliability-design/icons/rel-icon";
|
|
3
4
|
import type { Orientation } from "../rel-stepper/rel-stepper.js";
|
|
4
5
|
|
|
5
6
|
export interface RadioOption {
|
|
@@ -7,8 +8,17 @@ export interface RadioOption {
|
|
|
7
8
|
label: string;
|
|
8
9
|
supportingText?: string;
|
|
9
10
|
disabled?: boolean;
|
|
11
|
+
/** rel-icon name rendered before the label (Figma Has Icon/Avatar, Type=Icon). */
|
|
12
|
+
icon?: string;
|
|
13
|
+
/** 1–2 initials rendered as a circular chip before the label (Type=Avatar).
|
|
14
|
+
* Ignored when `icon` is also set. */
|
|
15
|
+
avatar?: string;
|
|
10
16
|
}
|
|
11
17
|
|
|
18
|
+
type RadioSize = "small" | "medium" | "large";
|
|
19
|
+
type RadioDensity = "compact" | "comfortable";
|
|
20
|
+
type RadioAlignment = "leading" | "trailing";
|
|
21
|
+
|
|
12
22
|
@customElement("rel-radio")
|
|
13
23
|
export class RelRadio extends LitElement {
|
|
14
24
|
@property({ type: Array }) options: RadioOption[] = [];
|
|
@@ -19,9 +29,23 @@ export class RelRadio extends LitElement {
|
|
|
19
29
|
* a column; `"horizontal"` lays them out in a wrapping row. */
|
|
20
30
|
@property({ type: String, reflect: true }) orientation: Orientation = "vertical";
|
|
21
31
|
|
|
22
|
-
/** Control scale. `"medium"` (default) = 20px
|
|
23
|
-
* `"
|
|
24
|
-
|
|
32
|
+
/** Control scale (Figma Size). `"medium"` (default, Figma M) = 20px control
|
|
33
|
+
* with body-lg labels; `"large"` (Figma L) = 24px control with body-xl
|
|
34
|
+
* labels; `"small"` (Figma S) = 20px control with body-md labels — S and M
|
|
35
|
+
* share the control size in the spec, only typography steps down. */
|
|
36
|
+
@property({ type: String, reflect: true }) size: RadioSize = "medium";
|
|
37
|
+
|
|
38
|
+
/** Supporting-text layout (Figma Density). `"compact"` (default) puts the
|
|
39
|
+
* supporting text on its own line under the row, indented past the control;
|
|
40
|
+
* `"comfortable"` stacks label + supporting text beside the control. */
|
|
41
|
+
@property({ type: String, reflect: true }) density: RadioDensity = "compact";
|
|
42
|
+
|
|
43
|
+
/** Control position (Figma Layout). `"leading"` (default) renders the
|
|
44
|
+
* control before the label; `"trailing"` pushes it to the far edge of the
|
|
45
|
+
* row. Trailing has no compact layout in the spec, so it always renders
|
|
46
|
+
* with comfortable density. Meant for vertical orientation — trailing
|
|
47
|
+
* options stretch to the group's full width. */
|
|
48
|
+
@property({ type: String, reflect: true }) alignment: RadioAlignment = "leading";
|
|
25
49
|
|
|
26
50
|
@property({ type: String, reflect: true })
|
|
27
51
|
selectedValue: string | null = null;
|
|
@@ -33,6 +57,9 @@ export class RelRadio extends LitElement {
|
|
|
33
57
|
|
|
34
58
|
@property({ type: String }) errorMessage = "";
|
|
35
59
|
|
|
60
|
+
/** Accessible name for the radiogroup (it renders no visible group label). */
|
|
61
|
+
@property({ type: String, attribute: "field-aria-label" }) fieldAriaLabel?: string;
|
|
62
|
+
|
|
36
63
|
@property({ type: String }) value = "";
|
|
37
64
|
|
|
38
65
|
checked = false;
|
|
@@ -63,6 +90,12 @@ export class RelRadio extends LitElement {
|
|
|
63
90
|
gap: var(--rel-spacing-xs) var(--rel-spacing-xl);
|
|
64
91
|
}
|
|
65
92
|
|
|
93
|
+
/* Trailing alignment — options stretch so the control can sit on the far
|
|
94
|
+
edge of the group's width. */
|
|
95
|
+
:host([alignment="trailing"]) .rel-radio-group {
|
|
96
|
+
align-items: stretch;
|
|
97
|
+
}
|
|
98
|
+
|
|
66
99
|
.rel-radio-option {
|
|
67
100
|
display: inline-flex;
|
|
68
101
|
flex-direction: column;
|
|
@@ -71,23 +104,11 @@ export class RelRadio extends LitElement {
|
|
|
71
104
|
}
|
|
72
105
|
|
|
73
106
|
.rel-radio-option.disabled {
|
|
74
|
-
|
|
75
|
-
|
|
107
|
+
/* Figma State=Disabled: whole option at 40% opacity, colors unchanged. */
|
|
108
|
+
opacity: 0.4;
|
|
76
109
|
cursor: not-allowed !important;
|
|
77
110
|
}
|
|
78
111
|
|
|
79
|
-
.rel-radio-option:not(.disabled):hover .radio-custom {
|
|
80
|
-
border-color: var(--rel-text-body);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.rel-radio-option:not(.disabled):hover .radio-label {
|
|
84
|
-
color: var(--rel-text-body);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.rel-radio-option:not(.disabled):hover .radio-supporting {
|
|
88
|
-
color: var(--rel-text-caption);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
112
|
.rel-radio-option:focus-within:has(input:focus-visible) {
|
|
92
113
|
outline: 1.5px solid var(--rel-border-focus);
|
|
93
114
|
outline-offset: 1px;
|
|
@@ -104,7 +125,17 @@ export class RelRadio extends LitElement {
|
|
|
104
125
|
position: relative;
|
|
105
126
|
display: flex;
|
|
106
127
|
align-items: center;
|
|
107
|
-
|
|
128
|
+
/* Compact row rhythm (control ↔ label). Comfortable widens to 12px. */
|
|
129
|
+
gap: var(--rel-spacing-xs);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.rel-radio-option.comfortable .radio-main {
|
|
133
|
+
gap: var(--rel-spacing-sm);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
:host([alignment="trailing"]) .radio-main {
|
|
137
|
+
flex-direction: row-reverse;
|
|
138
|
+
justify-content: space-between;
|
|
108
139
|
}
|
|
109
140
|
|
|
110
141
|
input {
|
|
@@ -117,63 +148,163 @@ export class RelRadio extends LitElement {
|
|
|
117
148
|
pointer-events: none;
|
|
118
149
|
}
|
|
119
150
|
|
|
151
|
+
/* Control box (Figma .Radio Control) — the drawn ring is inset inside a
|
|
152
|
+
larger hit/spacing box: 16px ring in a 20px box (M/S), 20px ring in a
|
|
153
|
+
24px box (L). Indent math below uses the BOX size. */
|
|
120
154
|
.radio-custom {
|
|
121
155
|
width: 20px;
|
|
122
156
|
height: 20px;
|
|
123
|
-
|
|
124
|
-
|
|
157
|
+
display: inline-flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
justify-content: center;
|
|
125
160
|
position: relative;
|
|
126
161
|
flex-shrink: 0;
|
|
127
162
|
}
|
|
128
163
|
|
|
129
|
-
|
|
164
|
+
.radio-custom::before {
|
|
165
|
+
content: "";
|
|
166
|
+
box-sizing: border-box;
|
|
167
|
+
width: 16px;
|
|
168
|
+
height: 16px;
|
|
169
|
+
border: 2px solid var(--rel-text-default);
|
|
170
|
+
border-radius: 50%;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.radio-custom::after {
|
|
130
174
|
content: "";
|
|
131
175
|
position: absolute;
|
|
132
|
-
|
|
133
|
-
|
|
176
|
+
width: 8px;
|
|
177
|
+
height: 8px;
|
|
134
178
|
border-radius: 50%;
|
|
179
|
+
background: var(--rel-text-default);
|
|
180
|
+
display: none;
|
|
135
181
|
}
|
|
136
182
|
|
|
137
|
-
.radio-
|
|
183
|
+
input:checked + .radio-custom::after {
|
|
184
|
+
display: block;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Comfortable density — label and supporting text stack beside the control. */
|
|
188
|
+
.stack {
|
|
189
|
+
display: flex;
|
|
190
|
+
flex-direction: column;
|
|
191
|
+
min-width: 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.label-line {
|
|
195
|
+
display: flex;
|
|
196
|
+
align-items: center;
|
|
197
|
+
gap: var(--rel-spacing-xs);
|
|
198
|
+
min-width: 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Optional label prefix — icon tracks the label's color in every state
|
|
202
|
+
(rel-icon inherits currentColor). */
|
|
203
|
+
.radio-prefix {
|
|
204
|
+
flex-shrink: 0;
|
|
138
205
|
color: var(--rel-text-default);
|
|
206
|
+
}
|
|
139
207
|
|
|
140
|
-
|
|
208
|
+
.radio-avatar {
|
|
209
|
+
flex-shrink: 0;
|
|
210
|
+
width: 20px;
|
|
211
|
+
height: 20px;
|
|
212
|
+
border-radius: 50%;
|
|
213
|
+
display: inline-flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
background: var(--rel-bg-neutral-inverse-2);
|
|
217
|
+
color: var(--rel-text-inverse);
|
|
218
|
+
font-family: var(--rel-body-xs-semibold-font-family);
|
|
219
|
+
font-weight: var(--rel-body-xs-semibold-font-weight);
|
|
220
|
+
font-size: var(--rel-body-xs-semibold-font-size);
|
|
221
|
+
line-height: 1;
|
|
222
|
+
letter-spacing: var(--rel-body-xs-semibold-letter-spacing);
|
|
223
|
+
}
|
|
141
224
|
|
|
225
|
+
.radio-label {
|
|
226
|
+
color: var(--rel-text-default);
|
|
227
|
+
font-family: var(--rel-body-lg-regular-font-family);
|
|
142
228
|
font-weight: var(--rel-body-lg-regular-font-weight);
|
|
143
|
-
|
|
144
229
|
font-size: var(--rel-body-lg-regular-font-size);
|
|
145
|
-
|
|
146
230
|
line-height: var(--rel-body-lg-regular-line-height);
|
|
147
|
-
|
|
148
231
|
letter-spacing: var(--rel-body-lg-regular-letter-spacing);
|
|
149
|
-
|
|
150
232
|
}
|
|
151
233
|
|
|
152
234
|
.radio-supporting {
|
|
153
|
-
margin-left: 28px;
|
|
154
235
|
color: var(--rel-text-caption);
|
|
155
|
-
|
|
156
236
|
font-family: var(--rel-body-sm-regular-font-family);
|
|
157
|
-
|
|
158
237
|
font-weight: var(--rel-body-sm-regular-font-weight);
|
|
159
|
-
|
|
160
238
|
font-size: var(--rel-body-sm-regular-font-size);
|
|
161
|
-
|
|
162
239
|
line-height: var(--rel-body-sm-regular-line-height);
|
|
163
|
-
|
|
164
240
|
letter-spacing: var(--rel-body-sm-regular-letter-spacing);
|
|
241
|
+
}
|
|
165
242
|
|
|
243
|
+
/* Compact density — supporting text sits under the whole row, indented
|
|
244
|
+
past the control box (box width + row gap). */
|
|
245
|
+
.radio-supporting.indent {
|
|
246
|
+
padding-left: 28px;
|
|
166
247
|
}
|
|
167
248
|
|
|
168
|
-
/*
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
249
|
+
/* Hover (Figma State=Hover) — ring, dot, label, and prefix icon shift
|
|
250
|
+
text-default → text-body; supporting text stays caption. Scoped away
|
|
251
|
+
from disabled and error so those keep their own colors. */
|
|
252
|
+
.rel-radio-option:not(.disabled):not(.error-unchecked):not(.error-checked):hover .radio-custom::before {
|
|
253
|
+
border-color: var(--rel-text-body);
|
|
173
254
|
}
|
|
174
255
|
|
|
175
|
-
:
|
|
176
|
-
|
|
256
|
+
.rel-radio-option:not(.disabled):not(.error-unchecked):not(.error-checked):hover .radio-custom::after {
|
|
257
|
+
background: var(--rel-text-body);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.rel-radio-option:not(.disabled):not(.error-unchecked):not(.error-checked):hover .radio-label,
|
|
261
|
+
.rel-radio-option:not(.disabled):not(.error-unchecked):not(.error-checked):hover .radio-prefix {
|
|
262
|
+
color: var(--rel-text-body);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* Size variants (medium is the base scale above). */
|
|
266
|
+
:host([size="large"]) .radio-custom {
|
|
267
|
+
width: 24px;
|
|
268
|
+
height: 24px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
:host([size="large"]) .radio-custom::before {
|
|
272
|
+
width: 20px;
|
|
273
|
+
height: 20px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
:host([size="large"]) .radio-custom::after {
|
|
277
|
+
width: 10px;
|
|
278
|
+
height: 10px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
:host([size="large"]) .radio-label {
|
|
282
|
+
font-family: var(--rel-body-xl-regular-font-family);
|
|
283
|
+
font-weight: var(--rel-body-xl-regular-font-weight);
|
|
284
|
+
font-size: var(--rel-body-xl-regular-font-size);
|
|
285
|
+
line-height: var(--rel-body-xl-regular-line-height);
|
|
286
|
+
letter-spacing: var(--rel-body-xl-regular-letter-spacing);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
:host([size="large"]) .radio-supporting {
|
|
290
|
+
font-family: var(--rel-body-md-regular-font-family);
|
|
291
|
+
font-weight: var(--rel-body-md-regular-font-weight);
|
|
292
|
+
font-size: var(--rel-body-md-regular-font-size);
|
|
293
|
+
line-height: var(--rel-body-md-regular-line-height);
|
|
294
|
+
letter-spacing: var(--rel-body-md-regular-letter-spacing);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
:host([size="large"]) .radio-supporting.indent {
|
|
298
|
+
padding-left: 32px;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
:host([size="large"]) .radio-avatar {
|
|
302
|
+
width: 24px;
|
|
303
|
+
height: 24px;
|
|
304
|
+
font-family: var(--rel-body-sm-semibold-font-family);
|
|
305
|
+
font-weight: var(--rel-body-sm-semibold-font-weight);
|
|
306
|
+
font-size: var(--rel-body-sm-semibold-font-size);
|
|
307
|
+
letter-spacing: var(--rel-body-sm-semibold-letter-spacing);
|
|
177
308
|
}
|
|
178
309
|
|
|
179
310
|
:host([size="small"]) .radio-label {
|
|
@@ -185,7 +316,6 @@ export class RelRadio extends LitElement {
|
|
|
185
316
|
}
|
|
186
317
|
|
|
187
318
|
:host([size="small"]) .radio-supporting {
|
|
188
|
-
margin-left: 24px;
|
|
189
319
|
font-family: var(--rel-body-xs-regular-font-family);
|
|
190
320
|
font-weight: var(--rel-body-xs-regular-font-weight);
|
|
191
321
|
font-size: var(--rel-body-xs-regular-font-size);
|
|
@@ -193,21 +323,17 @@ export class RelRadio extends LitElement {
|
|
|
193
323
|
letter-spacing: var(--rel-body-xs-regular-letter-spacing);
|
|
194
324
|
}
|
|
195
325
|
|
|
196
|
-
/* Error state (Figma State=Error,
|
|
197
|
-
|
|
198
|
-
.rel-radio-option.error-
|
|
326
|
+
/* Error state (Figma State=Error) — ring, dot, and supporting text go
|
|
327
|
+
danger; the label (and prefix) keep their default color. */
|
|
328
|
+
.rel-radio-option.error-unchecked .radio-custom::before,
|
|
329
|
+
.rel-radio-option.error-checked .radio-custom::before {
|
|
199
330
|
border-color: var(--rel-border-danger);
|
|
200
331
|
}
|
|
201
332
|
|
|
202
|
-
.rel-radio-option.error-checked
|
|
333
|
+
.rel-radio-option.error-checked .radio-custom::after {
|
|
203
334
|
background: var(--rel-text-danger);
|
|
204
335
|
}
|
|
205
336
|
|
|
206
|
-
.rel-radio-option.error-unchecked .radio-label,
|
|
207
|
-
.rel-radio-option.error-checked .radio-label {
|
|
208
|
-
color: var(--rel-text-danger);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
337
|
.rel-radio-option.error-unchecked .radio-supporting,
|
|
212
338
|
.rel-radio-option.error-checked .radio-supporting {
|
|
213
339
|
color: var(--rel-text-danger);
|
|
@@ -229,8 +355,29 @@ export class RelRadio extends LitElement {
|
|
|
229
355
|
letter-spacing: var(--rel-body-sm-regular-letter-spacing);
|
|
230
356
|
|
|
231
357
|
}
|
|
358
|
+
|
|
359
|
+
.error-message.empty {
|
|
360
|
+
margin-top: 0;
|
|
361
|
+
}
|
|
232
362
|
`;
|
|
233
363
|
|
|
364
|
+
protected willUpdate(changed: PropertyValues<this>) {
|
|
365
|
+
if (
|
|
366
|
+
(changed.has("alignment") || changed.has("density")) &&
|
|
367
|
+
this.alignment === "trailing" &&
|
|
368
|
+
this.density === "compact"
|
|
369
|
+
) {
|
|
370
|
+
console.warn(
|
|
371
|
+
'[rel-radio] density="compact" has no trailing layout; rendering comfortable density.'
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** Trailing has no compact layout in the spec — trailing wins. */
|
|
377
|
+
private get effectiveDensity(): RadioDensity {
|
|
378
|
+
return this.alignment === "trailing" ? "comfortable" : this.density;
|
|
379
|
+
}
|
|
380
|
+
|
|
234
381
|
private onChange(value: string) {
|
|
235
382
|
if (this.disabled) return;
|
|
236
383
|
|
|
@@ -253,11 +400,27 @@ export class RelRadio extends LitElement {
|
|
|
253
400
|
return this.selectedValue !== null && this.selectedValue !== "";
|
|
254
401
|
}
|
|
255
402
|
|
|
403
|
+
private renderPrefix(option: RadioOption) {
|
|
404
|
+
if (option.icon) {
|
|
405
|
+
return html`<rel-icon
|
|
406
|
+
name="${option.icon}"
|
|
407
|
+
size="${this.size === "large" ? "lg" : "md"}"
|
|
408
|
+
class="radio-prefix"
|
|
409
|
+
></rel-icon>`;
|
|
410
|
+
}
|
|
411
|
+
if (option.avatar) {
|
|
412
|
+
return html`<span class="radio-avatar" aria-hidden="true">${option.avatar}</span>`;
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
|
|
256
417
|
private renderOption(option: RadioOption) {
|
|
257
418
|
const isChecked = this.selectedValue === option.value;
|
|
258
419
|
const isDisabled = this.disabled || option.disabled;
|
|
420
|
+
const comfortable = this.effectiveDensity === "comfortable";
|
|
259
421
|
const classes = [
|
|
260
422
|
"rel-radio-option",
|
|
423
|
+
comfortable ? "comfortable" : "compact",
|
|
261
424
|
isDisabled ? "disabled" : "",
|
|
262
425
|
this.error && !this.hasSelection ? "error-unchecked" : "",
|
|
263
426
|
this.error && isChecked ? "error-checked" : "",
|
|
@@ -265,6 +428,19 @@ export class RelRadio extends LitElement {
|
|
|
265
428
|
.filter(Boolean)
|
|
266
429
|
.join(" ");
|
|
267
430
|
|
|
431
|
+
const labelLine = html`
|
|
432
|
+
<span class="label-line">
|
|
433
|
+
${this.renderPrefix(option)}
|
|
434
|
+
<span part="label" class="radio-label">${option.label}</span>
|
|
435
|
+
</span>
|
|
436
|
+
`;
|
|
437
|
+
|
|
438
|
+
const supporting = option.supportingText
|
|
439
|
+
? html`<div class="radio-supporting ${comfortable ? "" : "indent"}">
|
|
440
|
+
${option.supportingText}
|
|
441
|
+
</div>`
|
|
442
|
+
: null;
|
|
443
|
+
|
|
268
444
|
return html`
|
|
269
445
|
<label class="${classes}">
|
|
270
446
|
<div class="radio-main">
|
|
@@ -277,12 +453,12 @@ export class RelRadio extends LitElement {
|
|
|
277
453
|
@blur="${() => this._onTouched()}"
|
|
278
454
|
/>
|
|
279
455
|
<span class="radio-custom"></span>
|
|
280
|
-
|
|
456
|
+
${comfortable
|
|
457
|
+
? html`<span class="stack">${labelLine}${supporting}</span>`
|
|
458
|
+
: labelLine}
|
|
281
459
|
</div>
|
|
282
460
|
|
|
283
|
-
${
|
|
284
|
-
? html`<div class="radio-supporting">${option.supportingText}</div>`
|
|
285
|
-
: ""}
|
|
461
|
+
${comfortable ? null : supporting}
|
|
286
462
|
</label>
|
|
287
463
|
`;
|
|
288
464
|
}
|
|
@@ -294,12 +470,12 @@ export class RelRadio extends LitElement {
|
|
|
294
470
|
class="rel-radio-group"
|
|
295
471
|
role="radiogroup"
|
|
296
472
|
aria-orientation="${this.orientation}"
|
|
473
|
+
aria-label="${this.fieldAriaLabel ?? nothing}"
|
|
474
|
+
aria-describedby="radio-error"
|
|
297
475
|
>
|
|
298
476
|
${this.options.map((o) => this.renderOption(o))}
|
|
299
477
|
</div>
|
|
300
|
-
${this.error && this.errorMessage
|
|
301
|
-
? html`<div class="error-message">${this.errorMessage}</div>`
|
|
302
|
-
: ""}
|
|
478
|
+
<div class="${this.error && this.errorMessage ? "error-message" : "error-message empty"}" id="radio-error" aria-live="polite">${this.error && this.errorMessage ? this.errorMessage : ""}</div>
|
|
303
479
|
`;
|
|
304
480
|
}
|
|
305
481
|
}
|