agnosticui-core 2.0.0-alpha.18 → 2.0.0-alpha.19

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.
@@ -113,9 +113,19 @@ export declare class AgRadio extends AgRadio_base implements RadioProps {
113
113
  */
114
114
  private _syncFormValue;
115
115
  /**
116
- * Sync validity to ElementInternals by delegating to the inner
117
- * <input type="radio">. The required constraint is met when any radio
118
- * in the group is checked; the browser handles this natively.
116
+ * Returns true if any ag-radio in this named group is checked.
117
+ * Uses the same DOM-traversal logic as uncheckOtherRadiosInGroup so it
118
+ * works whether the radios are in the document or nested inside a shadow root.
119
+ */
120
+ private _isGroupChecked;
121
+ /**
122
+ * Sync validity to ElementInternals.
123
+ *
124
+ * Shadow DOM isolation prevents the inner <input type="radio"> from seeing
125
+ * sibling ag-radio elements in separate shadow trees, so native delegation
126
+ * would report each unchecked required radio as invalid individually.
127
+ * Instead we query the DOM directly: a required radio group is valid when
128
+ * ANY radio with the same name is checked.
119
129
  */
120
130
  private _syncValidity;
121
131
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"_Radio.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/core/_Radio.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_Radio.d.ts","sourceRoot":"","sources":["../../../../src/components/Radio/core/_Radio.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,16 @@
1
1
  import { LitElement as p, css as b, nothing as c, html as h } from "lit";
2
- import { n as o } from "../../../property-CemaeiRl.js";
3
- import { formControlStyles as v } from "../../../shared/form-control-styles.js";
4
- import { createFormControlIds as f, buildAriaDescribedBy as w } from "../../../shared/form-control-utils.js";
5
- import { FaceMixin as m, syncInnerInputValidity as y } from "../../../shared/face-mixin.js";
6
- var k = Object.defineProperty, s = (g, r, i, d) => {
7
- for (var e = void 0, a = g.length - 1, l; a >= 0; a--)
8
- (l = g[a]) && (e = l(r, i, e) || e);
9
- return e && k(r, i, e), e;
2
+ import { n as s } from "../../../property-CemaeiRl.js";
3
+ import { formControlStyles as f } from "../../../shared/form-control-styles.js";
4
+ import { createFormControlIds as v, buildAriaDescribedBy as w } from "../../../shared/form-control-utils.js";
5
+ import { FaceMixin as m } from "../../../shared/face-mixin.js";
6
+ var y = Object.defineProperty, d = (u, e, a, t) => {
7
+ for (var r = void 0, i = u.length - 1, l; i >= 0; i--)
8
+ (l = u[i]) && (r = l(e, a, r) || r);
9
+ return r && y(e, a, r), r;
10
10
  }, n;
11
- const t = (n = class extends m(p) {
11
+ const o = (n = class extends m(p) {
12
12
  constructor() {
13
- super(...arguments), this.value = "", this.checked = !1, this.disabled = !1, this.size = "medium", this.theme = "primary", this.labelText = "", this.labelPosition = "end", this.label = "", this.labelHidden = !1, this.noLabel = !1, this.required = !1, this.invalid = !1, this.errorMessage = "", this.helpText = "", this._ids = f("ag-radio");
13
+ super(...arguments), this.value = "", this.checked = !1, this.disabled = !1, this.size = "medium", this.theme = "primary", this.labelText = "", this.labelPosition = "end", this.label = "", this.labelHidden = !1, this.noLabel = !1, this.required = !1, this.invalid = !1, this.errorMessage = "", this.helpText = "", this._ids = v("ag-radio");
14
14
  }
15
15
  // ─── FACE ─────────────────────────────────────────────────────────────────
16
16
  /**
@@ -23,12 +23,40 @@ const t = (n = class extends m(p) {
23
23
  this._internals.setFormValue(this.checked ? this.value : null);
24
24
  }
25
25
  /**
26
- * Sync validity to ElementInternals by delegating to the inner
27
- * <input type="radio">. The required constraint is met when any radio
28
- * in the group is checked; the browser handles this natively.
26
+ * Returns true if any ag-radio in this named group is checked.
27
+ * Uses the same DOM-traversal logic as uncheckOtherRadiosInGroup so it
28
+ * works whether the radios are in the document or nested inside a shadow root.
29
+ */
30
+ _isGroupChecked() {
31
+ if (this.checked) return !0;
32
+ let e = this.getRootNode();
33
+ for (; e && "host" in e; ) {
34
+ const t = e.host?.getRootNode();
35
+ if (t && t !== e)
36
+ e = t;
37
+ else
38
+ break;
39
+ }
40
+ const a = e instanceof Document ? e : document;
41
+ return Array.from(a.querySelectorAll(`ag-radio[name="${this.name}"]`)).some(
42
+ (t) => t.checked
43
+ );
44
+ }
45
+ /**
46
+ * Sync validity to ElementInternals.
47
+ *
48
+ * Shadow DOM isolation prevents the inner <input type="radio"> from seeing
49
+ * sibling ag-radio elements in separate shadow trees, so native delegation
50
+ * would report each unchecked required radio as invalid individually.
51
+ * Instead we query the DOM directly: a required radio group is valid when
52
+ * ANY radio with the same name is checked.
29
53
  */
30
54
  _syncValidity() {
31
- y(this._internals, this.inputRef);
55
+ if (!this.required) {
56
+ this._internals.setValidity({});
57
+ return;
58
+ }
59
+ this._isGroupChecked() ? this._internals.setValidity({}) : this._internals.setValidity({ valueMissing: !0 }, "Please select one of these options.");
32
60
  }
33
61
  /**
34
62
  * FACE lifecycle: called when the parent form is reset.
@@ -56,64 +84,64 @@ const t = (n = class extends m(p) {
56
84
  firstUpdated() {
57
85
  this.inputRef = this.shadowRoot?.querySelector(".radio-input"), this._syncFormValue(), this._syncValidity(), this._syncStates();
58
86
  }
59
- updated(r) {
60
- super.updated(r), r.has("checked") && (this._syncFormValue(), this._syncValidity(), this._syncStates());
87
+ updated(e) {
88
+ super.updated(e), e.has("checked") && (this._syncFormValue(), this._syncValidity(), this._syncStates());
61
89
  }
62
- handleClick(r) {
63
- this.onClick && this.onClick(r);
90
+ handleClick(e) {
91
+ this.onClick && this.onClick(e);
64
92
  }
65
- handleKeyDown(r) {
66
- if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"].includes(r.key))
93
+ handleKeyDown(e) {
94
+ if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key))
67
95
  return;
68
- r.preventDefault();
69
- const i = this.getRadiosInGroup();
70
- if (i.length === 0) return;
71
- const d = i.indexOf(this);
72
- if (d === -1) return;
73
- let e;
74
- r.key === "Home" ? e = 0 : r.key === "End" ? e = i.length - 1 : r.key === "ArrowDown" || r.key === "ArrowRight" ? e = (d + 1) % i.length : e = (d - 1 + i.length) % i.length;
75
- const a = i[e];
76
- if (a && !a.disabled) {
77
- const l = a.shadowRoot?.querySelector(".radio-input");
96
+ e.preventDefault();
97
+ const a = this.getRadiosInGroup();
98
+ if (a.length === 0) return;
99
+ const t = a.indexOf(this);
100
+ if (t === -1) return;
101
+ let r;
102
+ e.key === "Home" ? r = 0 : e.key === "End" ? r = a.length - 1 : e.key === "ArrowDown" || e.key === "ArrowRight" ? r = (t + 1) % a.length : r = (t - 1 + a.length) % a.length;
103
+ const i = a[r];
104
+ if (i && !i.disabled) {
105
+ const l = i.shadowRoot?.querySelector(".radio-input");
78
106
  if (l) {
79
- l.focus(), a.checked = !0, a.uncheckOtherRadiosInGroup();
80
- const u = new CustomEvent(
107
+ l.focus(), i.checked = !0, i.uncheckOtherRadiosInGroup();
108
+ const g = new CustomEvent(
81
109
  "change",
82
110
  {
83
111
  detail: {
84
112
  checked: !0,
85
- value: a.value,
86
- name: a.name
113
+ value: i.value,
114
+ name: i.name
87
115
  },
88
116
  bubbles: !0,
89
117
  composed: !0
90
118
  }
91
119
  );
92
- a.dispatchEvent(u), a.onChange && a.onChange(u);
120
+ i.dispatchEvent(g), i.onChange && i.onChange(g);
93
121
  }
94
122
  }
95
123
  }
96
124
  getRadiosInGroup() {
97
125
  if (!this.name) return [];
98
- let r = this.getRootNode();
99
- for (; r && "host" in r; ) {
100
- const e = r.host?.getRootNode();
101
- if (e && e !== r)
102
- r = e;
126
+ let e = this.getRootNode();
127
+ for (; e && "host" in e; ) {
128
+ const r = e.host?.getRootNode();
129
+ if (r && r !== e)
130
+ e = r;
103
131
  else
104
132
  break;
105
133
  }
106
- const d = (r instanceof Document ? r : document).querySelectorAll(`ag-radio[name="${this.name}"]`);
107
- return Array.from(d).filter((e) => e instanceof n && !e.disabled);
134
+ const t = (e instanceof Document ? e : document).querySelectorAll(`ag-radio[name="${this.name}"]`);
135
+ return Array.from(t).filter((r) => r instanceof n && !r.disabled);
108
136
  }
109
- handleChange(r) {
137
+ handleChange(e) {
110
138
  if (this.disabled) {
111
- r.preventDefault();
139
+ e.preventDefault();
112
140
  return;
113
141
  }
114
- const i = r.target, d = this.checked;
115
- this.checked = i.checked, this._syncFormValue(), this._syncValidity(), this._syncStates(), this.checked && !d && this.name && this.uncheckOtherRadiosInGroup();
116
- const e = new CustomEvent(
142
+ const a = e.target, t = this.checked;
143
+ this.checked = a.checked, this._syncFormValue(), this._syncValidity(), this._syncStates(), this.checked && !t && this.name && this.uncheckOtherRadiosInGroup();
144
+ const r = new CustomEvent(
117
145
  "change",
118
146
  {
119
147
  detail: {
@@ -125,19 +153,19 @@ const t = (n = class extends m(p) {
125
153
  composed: !0
126
154
  }
127
155
  );
128
- this.dispatchEvent(e), this.onChange && this.onChange(e);
156
+ this.dispatchEvent(r), this.onChange && this.onChange(r);
129
157
  }
130
158
  uncheckOtherRadiosInGroup() {
131
- let r = this.getRootNode();
132
- for (; r && "host" in r; ) {
133
- const e = r.host?.getRootNode();
134
- if (e && e !== r)
135
- r = e;
159
+ let e = this.getRootNode();
160
+ for (; e && "host" in e; ) {
161
+ const r = e.host?.getRootNode();
162
+ if (r && r !== e)
163
+ e = r;
136
164
  else
137
165
  break;
138
166
  }
139
- (r instanceof Document ? r : document).querySelectorAll(`ag-radio[name="${this.name}"]`).forEach((e) => {
140
- e !== this && e instanceof n && (e.checked = !1);
167
+ (e instanceof Document ? e : document).querySelectorAll(`ag-radio[name="${this.name}"]`).forEach((r) => {
168
+ r !== this && r instanceof n && (r.checked = !1, r._syncValidity(), r._syncStates());
141
169
  });
142
170
  }
143
171
  /**
@@ -199,18 +227,18 @@ const t = (n = class extends m(p) {
199
227
  });
200
228
  }
201
229
  render() {
202
- const r = `
230
+ const e = `
203
231
  radio-wrapper
204
232
  ${this.labelPosition === "start" ? "radio-wrapper--label-start" : ""}
205
- `, i = `
233
+ `, a = `
206
234
  radio-indicator
207
235
  radio-indicator--${this.size}
208
236
  radio-indicator--${this.theme}
209
- `, d = `
237
+ `, t = `
210
238
  radio-label
211
239
  radio-label--${this.size}
212
- `, e = this._getAriaDescribedBy(), a = h`
213
- <label class=${r.trim()} part="ag-radio-wrapper">
240
+ `, r = this._getAriaDescribedBy(), i = h`
241
+ <label class=${e.trim()} part="ag-radio-wrapper">
214
242
  <input
215
243
  type="radio"
216
244
  id="${this._ids.inputId}"
@@ -223,14 +251,14 @@ const t = (n = class extends m(p) {
223
251
  ?required=${this.required}
224
252
  aria-required="${this.required ? "true" : "false"}"
225
253
  aria-invalid="${this.invalid ? "true" : "false"}"
226
- aria-describedby="${e || c}"
254
+ aria-describedby="${r || c}"
227
255
  @click=${this.handleClick}
228
256
  @change=${this.handleChange}
229
257
  @keydown=${this.handleKeyDown}
230
258
  aria-checked=${this.checked ? "true" : "false"}
231
259
  />
232
- <span class=${i.trim()} part="ag-radio-indicator"></span>
233
- <span class=${d.trim()} part="ag-radio-label">
260
+ <span class=${a.trim()} part="ag-radio-indicator"></span>
261
+ <span class=${t.trim()} part="ag-radio-label">
234
262
  ${this.labelText ? this.labelText : h`<slot></slot>`}
235
263
  </span>
236
264
  </label>
@@ -238,14 +266,14 @@ const t = (n = class extends m(p) {
238
266
  return this.label || this.helpText || this.errorMessage ? h`
239
267
  <div class="ag-radio-wrapper-with-external">
240
268
  ${this._renderExternalLabel()}
241
- ${a}
269
+ ${i}
242
270
  ${this._renderHelper()}
243
271
  ${this._renderError()}
244
272
  </div>
245
- ` : a;
273
+ ` : i;
246
274
  }
247
275
  }, n.styles = [
248
- v,
276
+ f,
249
277
  b`
250
278
  :host {
251
279
  display: inline-block;
@@ -432,55 +460,55 @@ const t = (n = class extends m(p) {
432
460
  }
433
461
  `
434
462
  ], n);
435
- s([
436
- o({ type: String, reflect: !0 })
437
- ], t.prototype, "value");
438
- s([
439
- o({ type: Boolean, reflect: !0 })
440
- ], t.prototype, "checked");
441
- s([
442
- o({ type: Boolean, reflect: !0 })
443
- ], t.prototype, "disabled");
444
- s([
445
- o({ type: String })
446
- ], t.prototype, "size");
447
- s([
448
- o({ type: String })
449
- ], t.prototype, "theme");
450
- s([
451
- o({ type: String })
452
- ], t.prototype, "labelText");
453
- s([
454
- o({ type: String })
455
- ], t.prototype, "labelPosition");
456
- s([
457
- o({ type: String })
458
- ], t.prototype, "label");
459
- s([
460
- o({ type: Boolean, attribute: "label-hidden" })
461
- ], t.prototype, "labelHidden");
462
- s([
463
- o({ type: Boolean, attribute: "no-label" })
464
- ], t.prototype, "noLabel");
465
- s([
466
- o({ type: Boolean, reflect: !0 })
467
- ], t.prototype, "required");
468
- s([
469
- o({ type: Boolean, reflect: !0 })
470
- ], t.prototype, "invalid");
471
- s([
472
- o({ type: String, attribute: "error-message" })
473
- ], t.prototype, "errorMessage");
474
- s([
475
- o({ type: String, attribute: "help-text" })
476
- ], t.prototype, "helpText");
477
- s([
478
- o({ attribute: !1 })
479
- ], t.prototype, "onClick");
480
- s([
481
- o({ attribute: !1 })
482
- ], t.prototype, "onChange");
483
- let R = t;
463
+ d([
464
+ s({ type: String, reflect: !0 })
465
+ ], o.prototype, "value");
466
+ d([
467
+ s({ type: Boolean, reflect: !0 })
468
+ ], o.prototype, "checked");
469
+ d([
470
+ s({ type: Boolean, reflect: !0 })
471
+ ], o.prototype, "disabled");
472
+ d([
473
+ s({ type: String })
474
+ ], o.prototype, "size");
475
+ d([
476
+ s({ type: String })
477
+ ], o.prototype, "theme");
478
+ d([
479
+ s({ type: String })
480
+ ], o.prototype, "labelText");
481
+ d([
482
+ s({ type: String })
483
+ ], o.prototype, "labelPosition");
484
+ d([
485
+ s({ type: String })
486
+ ], o.prototype, "label");
487
+ d([
488
+ s({ type: Boolean, attribute: "label-hidden" })
489
+ ], o.prototype, "labelHidden");
490
+ d([
491
+ s({ type: Boolean, attribute: "no-label" })
492
+ ], o.prototype, "noLabel");
493
+ d([
494
+ s({ type: Boolean, reflect: !0 })
495
+ ], o.prototype, "required");
496
+ d([
497
+ s({ type: Boolean, reflect: !0 })
498
+ ], o.prototype, "invalid");
499
+ d([
500
+ s({ type: String, attribute: "error-message" })
501
+ ], o.prototype, "errorMessage");
502
+ d([
503
+ s({ type: String, attribute: "help-text" })
504
+ ], o.prototype, "helpText");
505
+ d([
506
+ s({ attribute: !1 })
507
+ ], o.prototype, "onClick");
508
+ d([
509
+ s({ attribute: !1 })
510
+ ], o.prototype, "onChange");
511
+ let C = o;
484
512
  export {
485
- R as AgRadio
513
+ C as AgRadio
486
514
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agnosticui-core",
3
- "version": "2.0.0-alpha.18",
3
+ "version": "2.0.0-alpha.19",
4
4
  "author": "AgnosticUI",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -5,7 +5,7 @@ import {
5
5
  createFormControlIds,
6
6
  buildAriaDescribedBy,
7
7
  } from '../../../shared/form-control-utils';
8
- import { FaceMixin, syncInnerInputValidity } from '../../../shared/face-mixin';
8
+ import { FaceMixin } from '../../../shared/face-mixin';
9
9
 
10
10
 
11
11
  export type RadioSize = 'small' | 'medium' | 'large';
@@ -356,12 +356,46 @@ export class AgRadio extends FaceMixin(LitElement) implements RadioProps {
356
356
  }
357
357
 
358
358
  /**
359
- * Sync validity to ElementInternals by delegating to the inner
360
- * <input type="radio">. The required constraint is met when any radio
361
- * in the group is checked; the browser handles this natively.
359
+ * Returns true if any ag-radio in this named group is checked.
360
+ * Uses the same DOM-traversal logic as uncheckOtherRadiosInGroup so it
361
+ * works whether the radios are in the document or nested inside a shadow root.
362
+ */
363
+ private _isGroupChecked(): boolean {
364
+ if (this.checked) return true;
365
+ let root: Node = this.getRootNode();
366
+ while (root && 'host' in root) {
367
+ const parent = (root as ShadowRoot).host?.getRootNode();
368
+ if (parent && parent !== root) {
369
+ root = parent;
370
+ } else {
371
+ break;
372
+ }
373
+ }
374
+ const doc = root instanceof Document ? root : document;
375
+ return Array.from(doc.querySelectorAll(`ag-radio[name="${this.name}"]`)).some(
376
+ (el) => (el as AgRadio).checked
377
+ );
378
+ }
379
+
380
+ /**
381
+ * Sync validity to ElementInternals.
382
+ *
383
+ * Shadow DOM isolation prevents the inner <input type="radio"> from seeing
384
+ * sibling ag-radio elements in separate shadow trees, so native delegation
385
+ * would report each unchecked required radio as invalid individually.
386
+ * Instead we query the DOM directly: a required radio group is valid when
387
+ * ANY radio with the same name is checked.
362
388
  */
363
389
  private _syncValidity(): void {
364
- syncInnerInputValidity(this._internals, this.inputRef);
390
+ if (!this.required) {
391
+ this._internals.setValidity({});
392
+ return;
393
+ }
394
+ if (this._isGroupChecked()) {
395
+ this._internals.setValidity({});
396
+ } else {
397
+ this._internals.setValidity({ valueMissing: true }, 'Please select one of these options.');
398
+ }
365
399
  }
366
400
 
367
401
  /**
@@ -571,6 +605,11 @@ export class AgRadio extends FaceMixin(LitElement) implements RadioProps {
571
605
  allRadios.forEach((radio) => {
572
606
  if (radio !== this && radio instanceof AgRadio) {
573
607
  radio.checked = false;
608
+ // If checked didn't actually change (was already false), Lit's updated() won't
609
+ // fire on the sibling, so _syncValidity() wouldn't be called. Force it so
610
+ // unchecked siblings correctly reflect the group's new validity state.
611
+ radio._syncValidity();
612
+ radio._syncStates();
574
613
  }
575
614
  });
576
615
  }