@jack-henry/jh-elements 2.0.0-beta.13 → 2.0.0-beta.15
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/NOTICE +1 -1
- package/README.md +2 -2
- package/components/badge/badge.js +4 -4
- package/components/button/button.js +106 -52
- package/components/card/card.js +4 -4
- package/components/checkbox/checkbox.js +19 -31
- package/components/checkbox-group/checkbox-group.js +12 -20
- package/components/divider/divider.js +5 -5
- package/components/element/element.js +94 -0
- package/components/icon/icon.js +14 -12
- package/components/input/input.js +72 -74
- package/components/input-email/input-email.js +1 -1
- package/components/input-password/input-password.js +10 -19
- package/components/input-search/input-search.js +2 -2
- package/components/input-telephone/input-telephone.js +1 -1
- package/components/input-textarea/input-textarea.js +4 -13
- package/components/input-url/input-url.js +1 -1
- package/components/list-group/list-group.js +6 -13
- package/components/list-item/list-item.js +131 -143
- package/components/menu/menu.js +5 -8
- package/components/notification/notification.js +19 -21
- package/components/progress/progress.js +62 -56
- package/components/radio/radio.js +8 -21
- package/components/radio-group/radio-group.js +16 -31
- package/components/select/select.js +51 -30
- package/components/switch/switch.js +9 -22
- package/components/table/table.js +21 -29
- package/components/table-data-cell/table-data-cell.js +7 -9
- package/components/table-header-cell/table-header-cell.js +15 -25
- package/components/table-row/table-row.js +5 -8
- package/components/tag/tag.js +12 -14
- package/components/tag-group/tag-group.js +5 -7
- package/components/toast/toast.js +5 -14
- package/components/tooltip/tooltip.js +8 -9
- package/custom-elements.json +350 -215
- package/jsconfig.json +1 -1
- package/package.json +11 -15
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { css, html } from 'lit';
|
|
6
6
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
7
|
+
import { JhElement } from '../element/element.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @cssprop --jh-progress-label-color - The label text color. Defaults to `--jh-color-content-primary-enabled`.
|
|
@@ -11,11 +12,11 @@ import { ifDefined } from 'lit/directives/if-defined.js';
|
|
|
11
12
|
* @cssprop --jh-progress-track-color - The track color. Defaults to `--jh-color-control-enabled`.
|
|
12
13
|
* @cssprop --jh-progress-track-border-radius - The track border-radius. Defaults to `--jh-border-radius-50`.
|
|
13
14
|
* @cssprop --jh-progress-indicator-color - The indicator color. Defaults to `--jh-color-content-brand-enabled`.
|
|
15
|
+
* @cssprop --jh-progress-track-size-linear - The height of the linear progress bar track. Defaults to the size-based height.
|
|
16
|
+
* @cssprop --jh-progress-track-size-circular - The width and height of the circular progress indicator. Defaults to the size-based dimensions.
|
|
14
17
|
* @customElement jh-progress
|
|
15
18
|
*/
|
|
16
|
-
export class JhProgress extends
|
|
17
|
-
/** @type {ElementInternals} */
|
|
18
|
-
#internals;
|
|
19
|
+
export class JhProgress extends JhElement {
|
|
19
20
|
|
|
20
21
|
/** @type {string} */
|
|
21
22
|
#label;
|
|
@@ -87,14 +88,26 @@ export class JhProgress extends LitElement {
|
|
|
87
88
|
);
|
|
88
89
|
overflow: hidden;
|
|
89
90
|
}
|
|
91
|
+
:host([size='x-small']) .linear-progress-bar {
|
|
92
|
+
--progress-linear-height: var(--jh-dimension-25);
|
|
93
|
+
}
|
|
90
94
|
:host([size='small']) .linear-progress-bar {
|
|
91
|
-
height: var(--jh-dimension-50);
|
|
95
|
+
--progress-linear-height: var(--jh-dimension-50);
|
|
92
96
|
}
|
|
93
97
|
:host([size='medium']) .linear-progress-bar {
|
|
94
|
-
height: var(--jh-dimension-100);
|
|
98
|
+
--progress-linear-height: var(--jh-dimension-100);
|
|
95
99
|
}
|
|
96
100
|
:host([size='large']) .linear-progress-bar {
|
|
97
|
-
height: var(--jh-dimension-200);
|
|
101
|
+
--progress-linear-height: var(--jh-dimension-200);
|
|
102
|
+
}
|
|
103
|
+
:host([size='x-large']) .linear-progress-bar {
|
|
104
|
+
--progress-linear-height: var(--jh-dimension-300);
|
|
105
|
+
}
|
|
106
|
+
:host([size='xx-large']) .linear-progress-bar {
|
|
107
|
+
--progress-linear-height: var(--jh-dimension-400);
|
|
108
|
+
}
|
|
109
|
+
:host .linear-progress-bar {
|
|
110
|
+
height: var(--jh-progress-track-size-linear, var(--progress-linear-height));
|
|
98
111
|
}
|
|
99
112
|
:host .linear-progress-bar-value {
|
|
100
113
|
background-color: var(
|
|
@@ -110,30 +123,40 @@ export class JhProgress extends LitElement {
|
|
|
110
123
|
align-items: center;
|
|
111
124
|
}
|
|
112
125
|
:host([type='circular']) .text-content {
|
|
113
|
-
margin-top: var(--jh-dimension-
|
|
126
|
+
margin-top: var(--jh-dimension-100);
|
|
127
|
+
margin-bottom: 0;
|
|
114
128
|
display: flex;
|
|
115
129
|
flex-direction: column;
|
|
116
130
|
}
|
|
117
131
|
svg {
|
|
118
132
|
transform: rotate(-90deg);
|
|
119
|
-
width: var(--progress-size);
|
|
120
|
-
height: var(--progress-size);
|
|
133
|
+
width: var(--jh-progress-track-size-circular, var(--progress-circular-size));
|
|
134
|
+
height: var(--jh-progress-track-size-circular, var(--progress-circular-size));
|
|
121
135
|
overflow: visible;
|
|
122
136
|
}
|
|
137
|
+
:host([size='x-small']) svg {
|
|
138
|
+
--progress-circular-size: var(--jh-dimension-400);
|
|
139
|
+
}
|
|
123
140
|
:host([size='small']) svg {
|
|
124
|
-
--progress-size: var(--jh-dimension-
|
|
141
|
+
--progress-circular-size: var(--jh-dimension-500);
|
|
125
142
|
}
|
|
126
143
|
:host([size='medium']) svg {
|
|
127
|
-
--progress-size: var(--jh-dimension-
|
|
128
|
-
margin-bottom: 1px;
|
|
144
|
+
--progress-circular-size: var(--jh-dimension-600);
|
|
129
145
|
}
|
|
130
146
|
:host([size='large']) svg {
|
|
131
|
-
--progress-size: var(--jh-dimension-
|
|
132
|
-
|
|
147
|
+
--progress-circular-size: var(--jh-dimension-900);
|
|
148
|
+
}
|
|
149
|
+
:host([size='x-large']) svg {
|
|
150
|
+
--progress-circular-size: var(--jh-dimension-1400);
|
|
151
|
+
}
|
|
152
|
+
:host([size='xx-large']) svg {
|
|
153
|
+
--progress-circular-size: var(--jh-dimension-2100);
|
|
133
154
|
}
|
|
155
|
+
/* circle with virtual sizes for viewBox */
|
|
134
156
|
circle {
|
|
135
157
|
transform-origin: 50% 50%;
|
|
136
158
|
fill: none;
|
|
159
|
+
stroke-width: 1.5;
|
|
137
160
|
}
|
|
138
161
|
.circular-progress-bar {
|
|
139
162
|
stroke: var(--jh-progress-track-color, var(--jh-color-control-enabled));
|
|
@@ -145,18 +168,6 @@ export class JhProgress extends LitElement {
|
|
|
145
168
|
var(--jh-color-content-brand-enabled)
|
|
146
169
|
);
|
|
147
170
|
}
|
|
148
|
-
:host([size='small']) circle {
|
|
149
|
-
stroke-width: 1;
|
|
150
|
-
stroke-dasharray: 37.8px;
|
|
151
|
-
}
|
|
152
|
-
:host([size='medium']) circle {
|
|
153
|
-
stroke-width: 2;
|
|
154
|
-
stroke-dasharray: 50.3px;
|
|
155
|
-
}
|
|
156
|
-
:host([size='large']) circle {
|
|
157
|
-
stroke-width: 4;
|
|
158
|
-
stroke-dasharray: 100.8px;
|
|
159
|
-
}
|
|
160
171
|
:host([type='circular']) div {
|
|
161
172
|
text-align: center;
|
|
162
173
|
}
|
|
@@ -202,29 +213,28 @@ export class JhProgress extends LitElement {
|
|
|
202
213
|
|
|
203
214
|
constructor() {
|
|
204
215
|
super();
|
|
205
|
-
this.#internals = this.attachInternals();
|
|
206
216
|
/** @type {Boolean} */
|
|
207
217
|
this.indeterminate = false;
|
|
208
218
|
/** @type {?string} */
|
|
209
219
|
this.label = null;
|
|
210
|
-
/** @type {'small'|'medium'|'large'} */
|
|
220
|
+
/** @type { 'x-small'|'small'|'medium'|'large'|'x-large'|'xx-large'} */
|
|
211
221
|
this.size = 'medium';
|
|
212
222
|
/** @type {'linear'|'circular'} */
|
|
213
223
|
this.type = 'linear';
|
|
214
224
|
/** @type {Boolean} */
|
|
215
225
|
this.hideValue = false;
|
|
216
226
|
/** @type {?string} */
|
|
217
|
-
this
|
|
227
|
+
this.internals.ariaLabel;
|
|
218
228
|
/** @type {number} */
|
|
219
|
-
this
|
|
229
|
+
this.internals.ariaValueMax;
|
|
220
230
|
/** @type {number} */
|
|
221
|
-
this
|
|
231
|
+
this.internals.ariaValueMin;
|
|
222
232
|
/** @type {?number} */
|
|
223
|
-
this
|
|
233
|
+
this.internals.ariaValueNow;
|
|
224
234
|
/** @type {?string} */
|
|
225
|
-
this
|
|
235
|
+
this.internals.ariaValueText;
|
|
226
236
|
/** @type {?string} */
|
|
227
|
-
this
|
|
237
|
+
this.internals.role = 'progressbar';
|
|
228
238
|
/** @type {?string} */
|
|
229
239
|
this.accessibleLabel = null;
|
|
230
240
|
/** @type {?number} */
|
|
@@ -251,10 +261,10 @@ export class JhProgress extends LitElement {
|
|
|
251
261
|
|
|
252
262
|
// Shared setter for elementInternals properties
|
|
253
263
|
#setAttribute(ariaAttribute, newValue) {
|
|
254
|
-
const oldValue = this
|
|
264
|
+
const oldValue = this.internals[ariaAttribute];
|
|
255
265
|
|
|
256
266
|
if (newValue !== oldValue) {
|
|
257
|
-
this
|
|
267
|
+
this.internals[ariaAttribute] = newValue;
|
|
258
268
|
}
|
|
259
269
|
this.requestUpdate(ariaAttribute, oldValue);
|
|
260
270
|
}
|
|
@@ -275,7 +285,7 @@ export class JhProgress extends LitElement {
|
|
|
275
285
|
}
|
|
276
286
|
|
|
277
287
|
get accessibleLabel() {
|
|
278
|
-
return this
|
|
288
|
+
return this.internals.ariaLabel;
|
|
279
289
|
}
|
|
280
290
|
|
|
281
291
|
set accessibleLabel(newValue) {
|
|
@@ -283,7 +293,7 @@ export class JhProgress extends LitElement {
|
|
|
283
293
|
}
|
|
284
294
|
|
|
285
295
|
get min() {
|
|
286
|
-
return this
|
|
296
|
+
return this.internals.ariaValueMin;
|
|
287
297
|
}
|
|
288
298
|
|
|
289
299
|
set min(newValue) {
|
|
@@ -291,7 +301,7 @@ export class JhProgress extends LitElement {
|
|
|
291
301
|
}
|
|
292
302
|
|
|
293
303
|
get max() {
|
|
294
|
-
return this
|
|
304
|
+
return this.internals.ariaValueMax;
|
|
295
305
|
}
|
|
296
306
|
|
|
297
307
|
set max(newValue) {
|
|
@@ -299,7 +309,7 @@ export class JhProgress extends LitElement {
|
|
|
299
309
|
}
|
|
300
310
|
|
|
301
311
|
get accessibleValueText() {
|
|
302
|
-
return this
|
|
312
|
+
return this.internals.ariaValueText;
|
|
303
313
|
}
|
|
304
314
|
|
|
305
315
|
set accessibleValueText(newValue) {
|
|
@@ -307,14 +317,14 @@ export class JhProgress extends LitElement {
|
|
|
307
317
|
}
|
|
308
318
|
|
|
309
319
|
get value() {
|
|
310
|
-
return this
|
|
320
|
+
return this.internals.ariaValueNow;
|
|
311
321
|
}
|
|
312
322
|
|
|
313
323
|
set value(newValue) {
|
|
314
324
|
this.#setAttribute('ariaValueNow', newValue);
|
|
315
325
|
}
|
|
316
326
|
|
|
317
|
-
#getCircularIndicator(
|
|
327
|
+
#getCircularIndicator(indeterminate, percentage) {
|
|
318
328
|
let percentComplete;
|
|
319
329
|
|
|
320
330
|
if (indeterminate) {
|
|
@@ -324,26 +334,23 @@ export class JhProgress extends LitElement {
|
|
|
324
334
|
} else {
|
|
325
335
|
percentComplete = percentage;
|
|
326
336
|
}
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
large: [16, 16, 100.8],
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
const [r, axis, c] = circle[size];
|
|
337
|
+
// circle with virtual sizes for viewBox to allow for scaling.
|
|
338
|
+
const axis = 12;
|
|
339
|
+
const viewBoxSize = axis * 2;
|
|
340
|
+
const r = 9.75;
|
|
341
|
+
const c = +(2 * Math.PI * r).toFixed(1);
|
|
336
342
|
|
|
337
343
|
let percentOfCircleFilled = c - (c * Number(percentComplete)) / 100;
|
|
338
344
|
|
|
339
345
|
return html`
|
|
340
|
-
<svg>
|
|
346
|
+
<svg viewBox="0 0 ${viewBoxSize} ${viewBoxSize}" xmlns="http://www.w3.org/2000/svg">
|
|
341
347
|
<circle
|
|
342
348
|
class="circular-progress-bar"
|
|
343
349
|
r=${r}
|
|
344
350
|
cx=${axis}
|
|
345
351
|
cy=${axis}
|
|
346
352
|
c=${c}
|
|
353
|
+
style="stroke-dasharray: ${c}"
|
|
347
354
|
></circle>
|
|
348
355
|
<circle
|
|
349
356
|
class="circular-progress-bar-value"
|
|
@@ -351,7 +358,7 @@ export class JhProgress extends LitElement {
|
|
|
351
358
|
cx=${axis}
|
|
352
359
|
cy=${axis}
|
|
353
360
|
c=${c}
|
|
354
|
-
style="stroke-dashoffset
|
|
361
|
+
style="stroke-dasharray: ${c}; stroke-dashoffset: ${percentOfCircleFilled}"
|
|
355
362
|
></circle>
|
|
356
363
|
</svg>
|
|
357
364
|
`;
|
|
@@ -388,7 +395,6 @@ export class JhProgress extends LitElement {
|
|
|
388
395
|
indicator = this.#getLinearIndicator(percentage);
|
|
389
396
|
} else if (this.type === 'circular') {
|
|
390
397
|
indicator = this.#getCircularIndicator(
|
|
391
|
-
this.size,
|
|
392
398
|
this.indeterminate,
|
|
393
399
|
percentage
|
|
394
400
|
);
|
|
@@ -414,4 +420,4 @@ export class JhProgress extends LitElement {
|
|
|
414
420
|
}
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
|
|
423
|
+
JhProgress.register('jh-progress', JhProgress);
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
let id = 0;
|
|
5
|
+
import { css, html } from 'lit';
|
|
6
|
+
import { JhElement } from '../element/element.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @cssprop --jh-radio-opacity-disabled - The radio opacity when disabled. Defaults to `--jh-opacity-disabled`.
|
|
@@ -64,12 +63,7 @@ let id = 0;
|
|
|
64
63
|
*
|
|
65
64
|
* @customElement jh-radio */
|
|
66
65
|
|
|
67
|
-
export class JhRadio extends
|
|
68
|
-
|
|
69
|
-
/** @type {?Number} */
|
|
70
|
-
#id;
|
|
71
|
-
/** @type {ElementInternals} */
|
|
72
|
-
#internals;
|
|
66
|
+
export class JhRadio extends JhElement {
|
|
73
67
|
|
|
74
68
|
static get styles() {
|
|
75
69
|
return css`
|
|
@@ -321,8 +315,7 @@ export class JhRadio extends LitElement {
|
|
|
321
315
|
|
|
322
316
|
constructor() {
|
|
323
317
|
super();
|
|
324
|
-
this
|
|
325
|
-
this.#internals.role = 'radio';
|
|
318
|
+
this.internals.role = 'radio';
|
|
326
319
|
/** @type {?string} */
|
|
327
320
|
this.accessibleLabel = null;
|
|
328
321
|
/** @type {?boolean} */
|
|
@@ -342,14 +335,13 @@ export class JhRadio extends LitElement {
|
|
|
342
335
|
|
|
343
336
|
connectedCallback() {
|
|
344
337
|
super.connectedCallback();
|
|
345
|
-
this.#id = id++;
|
|
346
338
|
this.setAttribute('tabindex', '0');
|
|
347
339
|
this.setAttribute('aria-checked', `${this.checked}`);
|
|
348
340
|
if (this.accessibleLabel) {
|
|
349
341
|
this.setAttribute('aria-label', `${this.accessibleLabel}`);
|
|
350
342
|
}
|
|
351
343
|
if (this.helperText) {
|
|
352
|
-
this.setAttribute('aria-describedby', `radio-helper-text-${this
|
|
344
|
+
this.setAttribute('aria-describedby', `radio-helper-text-${this.uniqueId}`);
|
|
353
345
|
}
|
|
354
346
|
|
|
355
347
|
let observer = new MutationObserver(this.#updateArias.bind(this));
|
|
@@ -378,12 +370,7 @@ export class JhRadio extends LitElement {
|
|
|
378
370
|
if (this.checked) return;
|
|
379
371
|
|
|
380
372
|
this.checked = true;
|
|
381
|
-
|
|
382
|
-
bubbles: true,
|
|
383
|
-
composed: true,
|
|
384
|
-
cancelable: true,
|
|
385
|
-
};
|
|
386
|
-
this.dispatchEvent(new CustomEvent('jh-change', options));
|
|
373
|
+
this.dispatchCustomEvent('jh-change');
|
|
387
374
|
}
|
|
388
375
|
|
|
389
376
|
#handleKeydown(e) {
|
|
@@ -398,7 +385,7 @@ export class JhRadio extends LitElement {
|
|
|
398
385
|
|
|
399
386
|
if (this.helperText) {
|
|
400
387
|
helperText = html`
|
|
401
|
-
<p class="helper-text" id="radio-helper-text-${this
|
|
388
|
+
<p class="helper-text" id="radio-helper-text-${this.uniqueId}">
|
|
402
389
|
${this.helperText}
|
|
403
390
|
</p>
|
|
404
391
|
`;
|
|
@@ -419,4 +406,4 @@ export class JhRadio extends LitElement {
|
|
|
419
406
|
`;
|
|
420
407
|
}
|
|
421
408
|
}
|
|
422
|
-
|
|
409
|
+
JhRadio.register('jh-radio', JhRadio);
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { css, html } from 'lit';
|
|
6
6
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
7
|
+
import { JhElement } from '../element/element.js';
|
|
7
8
|
|
|
8
|
-
let id = 0;
|
|
9
9
|
/**
|
|
10
10
|
*
|
|
11
11
|
* @cssprop --jh-radio-group-label-color-text - The label text color. Defaults to `--jh-color-content-primary-enabled`.
|
|
@@ -21,19 +21,15 @@ let id = 0;
|
|
|
21
21
|
*
|
|
22
22
|
* @slot default - Use to insert `<jh-radio>` components(s).
|
|
23
23
|
*
|
|
24
|
-
* @event jh-change - Dispatched when the value of the radio group has changed.
|
|
24
|
+
* @event jh-change - Dispatched when the value of the radio group has changed. Event payload includes the `value` and can be accessed via `e.detail.state.value`.
|
|
25
25
|
*
|
|
26
26
|
* @customElement jh-radio-group
|
|
27
27
|
*/
|
|
28
|
-
export class JhRadioGroup extends
|
|
28
|
+
export class JhRadioGroup extends JhElement {
|
|
29
29
|
static get formAssociated() {
|
|
30
30
|
return true;
|
|
31
31
|
}
|
|
32
32
|
#checked;
|
|
33
|
-
/** @type {?Number} */
|
|
34
|
-
#id;
|
|
35
|
-
/** @type {ElementInternals} */
|
|
36
|
-
#internals;
|
|
37
33
|
/** @type {?string} */
|
|
38
34
|
#value;
|
|
39
35
|
|
|
@@ -208,7 +204,6 @@ export class JhRadioGroup extends LitElement {
|
|
|
208
204
|
}
|
|
209
205
|
constructor() {
|
|
210
206
|
super();
|
|
211
|
-
this.#internals = this.attachInternals();
|
|
212
207
|
/** @type {?string} */
|
|
213
208
|
this.accessibleLabel = null;
|
|
214
209
|
/** @type {boolean} */
|
|
@@ -237,11 +232,6 @@ export class JhRadioGroup extends LitElement {
|
|
|
237
232
|
this.addEventListener('focusout', this.#handleFocusOut);
|
|
238
233
|
}
|
|
239
234
|
|
|
240
|
-
connectedCallback() {
|
|
241
|
-
super.connectedCallback();
|
|
242
|
-
this.#id = id++;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
235
|
firstUpdated() {
|
|
246
236
|
this._syncDisabledToChildren();
|
|
247
237
|
}
|
|
@@ -257,12 +247,12 @@ export class JhRadioGroup extends LitElement {
|
|
|
257
247
|
* @type {?HTMLFormElement}
|
|
258
248
|
*/
|
|
259
249
|
get form() {
|
|
260
|
-
return this
|
|
250
|
+
return this.internals.form;
|
|
261
251
|
}
|
|
262
252
|
|
|
263
253
|
/** @ignore */
|
|
264
254
|
get validity() {
|
|
265
|
-
return this
|
|
255
|
+
return this.internals.validity;
|
|
266
256
|
}
|
|
267
257
|
|
|
268
258
|
/** @type {?string} */
|
|
@@ -274,7 +264,7 @@ export class JhRadioGroup extends LitElement {
|
|
|
274
264
|
const oldValue = this.#value;
|
|
275
265
|
if (newValue !== oldValue) {
|
|
276
266
|
this.#value = newValue;
|
|
277
|
-
this
|
|
267
|
+
this.internals.setFormValue(newValue);
|
|
278
268
|
}
|
|
279
269
|
this.requestUpdate('value', oldValue);
|
|
280
270
|
}
|
|
@@ -322,12 +312,7 @@ export class JhRadioGroup extends LitElement {
|
|
|
322
312
|
this.#checked = e.target;
|
|
323
313
|
this.#updateChecked();
|
|
324
314
|
|
|
325
|
-
|
|
326
|
-
bubbles: true,
|
|
327
|
-
composed: true,
|
|
328
|
-
cancelable: true,
|
|
329
|
-
};
|
|
330
|
-
this.dispatchEvent(new CustomEvent('jh-change', options));
|
|
315
|
+
this.dispatchCustomEvent('jh-change');
|
|
331
316
|
}
|
|
332
317
|
}
|
|
333
318
|
|
|
@@ -390,11 +375,11 @@ export class JhRadioGroup extends LitElement {
|
|
|
390
375
|
|
|
391
376
|
#getAriaDescribedBy() {
|
|
392
377
|
if (this.errorText && this.invalid && this.helperText && this.label) {
|
|
393
|
-
return `radio-group-error-${this
|
|
378
|
+
return `radio-group-error-${this.uniqueId} radio-group-helper-${this.uniqueId}`;
|
|
394
379
|
} else if (this.errorText && this.invalid) {
|
|
395
|
-
return `radio-group-error-${this
|
|
380
|
+
return `radio-group-error-${this.uniqueId}`;
|
|
396
381
|
} else if (this.helperText && this.label) {
|
|
397
|
-
return `radio-group-helper-${this
|
|
382
|
+
return `radio-group-helper-${this.uniqueId}`;
|
|
398
383
|
}
|
|
399
384
|
}
|
|
400
385
|
|
|
@@ -415,28 +400,28 @@ export class JhRadioGroup extends LitElement {
|
|
|
415
400
|
if (this.helperText) {
|
|
416
401
|
helperText = html`<p
|
|
417
402
|
class="helper-text"
|
|
418
|
-
id="radio-group-helper-${this
|
|
403
|
+
id="radio-group-helper-${this.uniqueId}"
|
|
419
404
|
>
|
|
420
405
|
${this.helperText}
|
|
421
406
|
</p>`;
|
|
422
407
|
}
|
|
423
408
|
|
|
424
409
|
if (this.label) {
|
|
425
|
-
label = html`<legend class="label" for="radio-group-label-${this
|
|
410
|
+
label = html`<legend class="label" for="radio-group-label-${this.uniqueId}">
|
|
426
411
|
${this.label}${indicator}
|
|
427
412
|
</legend>
|
|
428
413
|
${helperText}`;
|
|
429
414
|
}
|
|
430
415
|
|
|
431
416
|
if (this.invalid && this.errorText) {
|
|
432
|
-
errorText = html`<p class="error-text" id="radio-group-error-${this
|
|
417
|
+
errorText = html`<p class="error-text" id="radio-group-error-${this.uniqueId}">
|
|
433
418
|
${this.errorText}
|
|
434
419
|
</p>`;
|
|
435
420
|
}
|
|
436
421
|
return html`
|
|
437
422
|
<fieldset
|
|
438
423
|
role="radiogroup"
|
|
439
|
-
id=${ifDefined(this.label ? `radio-group-label-${this
|
|
424
|
+
id=${ifDefined(this.label ? `radio-group-label-${this.uniqueId}` : null)}
|
|
440
425
|
aria-describedby=${ifDefined(this.#getAriaDescribedBy())}
|
|
441
426
|
aria-disabled=${ifDefined(this.disabled ? 'true' : null)}
|
|
442
427
|
aria-required=${ifDefined(this.required ? 'true' : 'false')}
|
|
@@ -452,4 +437,4 @@ export class JhRadioGroup extends LitElement {
|
|
|
452
437
|
`;
|
|
453
438
|
}
|
|
454
439
|
}
|
|
455
|
-
|
|
440
|
+
JhRadioGroup.register('jh-radio-group', JhRadioGroup);
|
|
@@ -60,7 +60,7 @@ import { JhFilter } from './filtering.js';
|
|
|
60
60
|
* @slot jh-select-trigger-open - Use to replace the default chevron icon displayed when the select menu is open.
|
|
61
61
|
* @slot jh-select-trigger-closed - Use to replace the default chevron icon displayed when the select menu is closed.
|
|
62
62
|
*
|
|
63
|
-
* @event jh-change - Dispatched when the selected value changes.
|
|
63
|
+
* @event jh-change - Dispatched when the selected value changes. Event payload includes the `value` and can be accessed via `e.detail.state.value`.
|
|
64
64
|
*/
|
|
65
65
|
export class JhSelect extends JhInput {
|
|
66
66
|
/** @type {?string} */
|
|
@@ -243,17 +243,37 @@ export class JhSelect extends JhInput {
|
|
|
243
243
|
...item,
|
|
244
244
|
};
|
|
245
245
|
});
|
|
246
|
-
// These will be the same until we add search functionality, at which point #flatOptions will be the filtered list and #allOptions will remain the source of truth.
|
|
247
246
|
this.#flatOptions = this.#allOptions;
|
|
248
247
|
this.#activeIndex = null;
|
|
249
248
|
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
// If no value is set yet, use the selected flag as the initial default
|
|
250
|
+
if (this.value == null) {
|
|
251
|
+
const selectedOption = this.#flatOptions.find((opt) => opt.selected);
|
|
252
|
+
if (selectedOption) {
|
|
253
|
+
this.value = String(selectedOption.value);
|
|
254
|
+
this.#displayValue = selectedOption.label;
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
// Value already set — resolve display label from new options
|
|
258
|
+
this.#syncDisplayValue();
|
|
255
259
|
}
|
|
256
260
|
}
|
|
261
|
+
|
|
262
|
+
// Handle external value changes (e.g. .value = 'x' or value="x" attribute)
|
|
263
|
+
if (changedProperties.has('value') && !changedProperties.has('options')) {
|
|
264
|
+
this.#syncDisplayValue();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
#syncDisplayValue() {
|
|
269
|
+
if (this.value == null) {
|
|
270
|
+
this.#displayValue = null;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const match = this.#flatOptions.find(
|
|
274
|
+
(opt) => String(opt.value) === String(this.value)
|
|
275
|
+
);
|
|
276
|
+
this.#displayValue = match ? (match.label ?? String(match.value)) : null;
|
|
257
277
|
}
|
|
258
278
|
|
|
259
279
|
#getIndexFromId(elementId) {
|
|
@@ -299,7 +319,7 @@ export class JhSelect extends JhInput {
|
|
|
299
319
|
}
|
|
300
320
|
}
|
|
301
321
|
|
|
302
|
-
#handleOpenSelect() {
|
|
322
|
+
#handleOpenSelect({ keyboard = false } = {}) {
|
|
303
323
|
if (this.disabled || this.readonly || !this.#flatOptions.length) return;
|
|
304
324
|
if (!this.#inputWrapper || !this.#menuContainer) return;
|
|
305
325
|
|
|
@@ -310,8 +330,8 @@ export class JhSelect extends JhInput {
|
|
|
310
330
|
requestAnimationFrame(() => {
|
|
311
331
|
document.addEventListener('scroll', this.#boundDocumentScroll, true);
|
|
312
332
|
});
|
|
313
|
-
//
|
|
314
|
-
if (this.#activeIndex === null) {
|
|
333
|
+
// Only set active item on keyboard open to avoid showing focus ring on mouse open
|
|
334
|
+
if (keyboard && this.#activeIndex === null) {
|
|
315
335
|
const selectedIdx = this.#flatOptions.findIndex(
|
|
316
336
|
(opt) => String(opt.value) === String(this.value));
|
|
317
337
|
this.#setActiveItem(selectedIdx !== -1 ? selectedIdx : 0);
|
|
@@ -360,22 +380,26 @@ export class JhSelect extends JhInput {
|
|
|
360
380
|
if (e.ctrlKey || e.metaKey) return;
|
|
361
381
|
|
|
362
382
|
switch (e.key) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
case 'ArrowDown':
|
|
384
|
+
e.preventDefault();
|
|
385
|
+
if (!this.#open) {
|
|
386
|
+
this.#handleOpenSelect({ keyboard: true });
|
|
387
|
+
} else {
|
|
388
|
+
const selectedIdx = this.#flatOptions.findIndex(
|
|
389
|
+
(opt) => String(opt.value) === String(this.value));
|
|
390
|
+
this.#setActiveItem((this.#activeIndex ?? selectedIdx) + 1);
|
|
391
|
+
}
|
|
392
|
+
return;
|
|
371
393
|
|
|
372
394
|
case 'ArrowUp':
|
|
373
395
|
e.preventDefault();
|
|
374
396
|
if (!this.#open) {
|
|
375
|
-
this.#handleOpenSelect();
|
|
397
|
+
this.#handleOpenSelect({ keyboard: true });
|
|
376
398
|
} else {
|
|
399
|
+
const selectedIdx = this.#flatOptions.findIndex(
|
|
400
|
+
(opt) => String(opt.value) === String(this.value));
|
|
377
401
|
this.#setActiveItem(
|
|
378
|
-
this.#activeIndex
|
|
402
|
+
(this.#activeIndex ?? (selectedIdx !== -1 ? selectedIdx : this.#flatOptions.length)) - 1);
|
|
379
403
|
}
|
|
380
404
|
return;
|
|
381
405
|
|
|
@@ -383,11 +407,13 @@ export class JhSelect extends JhInput {
|
|
|
383
407
|
case ' ':
|
|
384
408
|
e.preventDefault();
|
|
385
409
|
if (!this.#open) {
|
|
386
|
-
this.#handleOpenSelect();
|
|
387
|
-
|
|
410
|
+
this.#handleOpenSelect({ keyboard: true });
|
|
411
|
+
} else if (this.#activeIndex !== null) {
|
|
388
412
|
this.#handleSelection(this.#activeIndex);
|
|
389
413
|
this.#handleCloseSelect();
|
|
390
|
-
|
|
414
|
+
} else {
|
|
415
|
+
this.#handleCloseSelect();
|
|
416
|
+
}
|
|
391
417
|
return;
|
|
392
418
|
|
|
393
419
|
case 'Escape':
|
|
@@ -454,12 +480,7 @@ export class JhSelect extends JhInput {
|
|
|
454
480
|
this.#scrollToActiveItem();
|
|
455
481
|
|
|
456
482
|
//dispatch a jh-change event when the selected value changes.
|
|
457
|
-
|
|
458
|
-
bubbles: true,
|
|
459
|
-
composed: true,
|
|
460
|
-
cancelable: true,
|
|
461
|
-
};
|
|
462
|
-
this.dispatchEvent(new CustomEvent('jh-change', options));
|
|
483
|
+
this.dispatchCustomEvent('jh-change');
|
|
463
484
|
}
|
|
464
485
|
}
|
|
465
486
|
|
|
@@ -657,4 +678,4 @@ export class JhSelect extends JhInput {
|
|
|
657
678
|
}
|
|
658
679
|
}
|
|
659
680
|
|
|
660
|
-
|
|
681
|
+
JhSelect.register('jh-select', JhSelect);
|