praxis-kit 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,205 +23,47 @@ function isNull(value) {
23
23
  return value === null;
24
24
  }
25
25
 
26
- // ../../lib/adapter-utils/src/apply-display-name.ts
27
- function applyDisplayName(component, name) {
28
- Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
29
- }
30
-
31
- // ../../lib/primitive/src/tag/resolve-tag.ts
32
- function makeResolveTag(defaultTag) {
33
- return function tag(as) {
34
- return as ?? defaultTag;
35
- };
36
- }
37
-
38
- // ../../lib/primitive/src/utils/assert-never.ts
39
- function assertNever(value) {
40
- throw new Error(`Unexpected value: ${String(value)}`);
41
- }
42
-
43
- // ../../lib/primitive/src/utils/cn.ts
44
- import { clsx } from "clsx";
45
- function cn(...inputs) {
46
- return clsx(...inputs);
47
- }
48
-
49
- // ../../lib/primitive/src/utils/iterate.ts
50
- function find(iterable, callback) {
51
- for (const value of iterable) {
52
- const result = callback(value);
53
- if (result != null) {
54
- return result;
55
- }
56
- }
57
- return null;
58
- }
59
- function some(iterable, predicate) {
60
- for (const value of iterable) {
61
- if (predicate(value)) return true;
62
- }
63
- return false;
64
- }
65
- function every(iterable, predicate) {
66
- let index = 0;
67
- for (const value of iterable) {
68
- if (!predicate(value, index++)) {
69
- return false;
70
- }
71
- }
72
- return true;
73
- }
74
- function* filter(iterable, predicate) {
75
- let index = 0;
76
- for (const value of iterable) {
77
- if (predicate(value, index++)) {
78
- yield value;
79
- }
80
- }
81
- }
82
- function* map(iterable, callback) {
83
- let index = 0;
84
- for (const value of iterable) {
85
- yield callback(value, index++);
86
- }
87
- }
88
- function forEach(iterable, callback) {
89
- let index = 0;
90
- for (const value of iterable) {
91
- callback(value, index++);
92
- }
93
- }
94
- function reduce(iterable, initial, callback) {
95
- let accumulator = initial;
96
- let index = 0;
97
- for (const value of iterable) {
98
- accumulator = callback(accumulator, value, index++);
99
- }
100
- return accumulator;
101
- }
102
- function collect(iterable, callback) {
103
- const result = {};
104
- let index = 0;
105
- for (const value of iterable) {
106
- const entry = callback(value, index++);
107
- if (entry === null) {
108
- return null;
109
- }
110
- result[entry[0]] = entry[1];
111
- }
112
- return result;
113
- }
114
- function findLast(value, callback) {
115
- for (let index = value.length - 1; index >= 0; index--) {
116
- const result = callback(value[index], index);
117
- if (result != null) {
118
- return result;
119
- }
120
- }
121
- return null;
122
- }
123
- function* items(collection) {
124
- for (let i = 0; i < collection.length; i++) {
125
- const item = collection.item(i);
126
- if (item !== null) {
127
- yield item;
128
- }
129
- }
130
- }
131
- function nodeList(list) {
132
- return {
133
- *[Symbol.iterator]() {
134
- for (let i = 0; i < list.length; i++) {
135
- const node = list.item(i);
136
- if (node !== null) {
137
- yield node;
138
- }
139
- }
140
- }
141
- };
142
- }
143
- function mapEntries(m) {
144
- return m.entries();
145
- }
146
- function set(s) {
147
- return s.values();
148
- }
149
- function hasOwn(object, key) {
150
- return Object.hasOwn(object, key);
151
- }
152
- function* entries(object) {
153
- for (const key in object) {
154
- if (!hasOwn(object, key)) continue;
155
- yield [key, object[key]];
156
- }
157
- }
158
- function* keys(object) {
159
- for (const [key] of entries(object)) {
160
- yield key;
161
- }
162
- }
163
- function* values(object) {
164
- for (const [, value] of entries(object)) {
165
- yield value;
166
- }
167
- }
168
- function mapValues(object, callback) {
169
- const result = {};
170
- for (const [key, value] of entries(object)) {
171
- result[key] = callback(value, key);
172
- }
173
- return result;
174
- }
175
- function forEachEntry(object, callback) {
176
- for (const [key, value] of entries(object)) {
177
- callback(key, value);
178
- }
179
- }
180
- function forEachKey(object, callback) {
181
- for (const key of keys(object)) {
182
- callback(key);
26
+ // ../../lib/primitive/src/guards/children/is-tag.ts
27
+ function getAsProp(child) {
28
+ if (!isObject(child) || !("props" in child)) return void 0;
29
+ const props = child.props;
30
+ if (!isObject(props)) return void 0;
31
+ const as = props.as;
32
+ return isString(as) && as !== "" ? as : void 0;
33
+ }
34
+ function getTag(child) {
35
+ if (!isObject(child) || !("type" in child)) return void 0;
36
+ const t = child.type;
37
+ if (isString(t)) return t;
38
+ if (typeof t === "function" || isObject(t)) {
39
+ const defaultTag = t[COMPONENT_DEFAULT_TAG];
40
+ if (!isString(defaultTag)) return void 0;
41
+ return getAsProp(child) ?? defaultTag;
183
42
  }
43
+ return void 0;
184
44
  }
185
- function forEachValue(object, callback) {
186
- for (const value of values(object)) {
187
- callback(value);
45
+ function isTag(...args) {
46
+ if (isString(args[0])) {
47
+ const set3 = new Set(args);
48
+ return (child2) => {
49
+ const tag2 = getTag(child2);
50
+ return tag2 !== void 0 && set3.has(tag2);
51
+ };
188
52
  }
53
+ const [child, ...tags] = args;
54
+ const set2 = new Set(tags);
55
+ const tag = getTag(child);
56
+ return tag !== void 0 && set2.has(tag);
189
57
  }
190
- function forEachSet(s, callback) {
191
- for (const value of s) {
192
- callback(value);
193
- }
58
+
59
+ // ../../lib/adapter-utils/src/runtime/apply-display-name.ts
60
+ function applyDisplayName(component, name) {
61
+ Object.assign(component, { displayName: name ?? "PolymorphicComponent" });
194
62
  }
195
- var iterate = Object.freeze({
196
- entries,
197
- filter,
198
- find,
199
- findLast,
200
- forEach,
201
- forEachEntry,
202
- forEachKey,
203
- forEachSet,
204
- forEachValue,
205
- items,
206
- keys,
207
- map,
208
- mapEntries,
209
- mapValues,
210
- nodeList,
211
- reduce,
212
- collect,
213
- set,
214
- some,
215
- every,
216
- values
217
- });
218
63
 
219
- // ../../lib/primitive/src/utils/merge-props.ts
220
- function mergeProps(defaultProps, props) {
221
- return {
222
- ...defaultProps ?? {},
223
- ...props
224
- };
64
+ // ../../lib/adapter-utils/src/runtime/define-component.ts
65
+ function defineContractComponent(options) {
66
+ return (factory) => factory(options);
225
67
  }
226
68
 
227
69
  // ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
@@ -246,7 +88,7 @@ var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
246
88
  ]);
247
89
 
248
90
  // ../../lib/primitive/src/constants/aria/implicit-role-record.ts
249
- var IMPLICIT_ROLE_RECORD = {
91
+ var IMPLICIT_ROLE_RECORD = Object.freeze({
250
92
  // Landmarks
251
93
  article: "article",
252
94
  aside: "complementary",
@@ -282,8 +124,8 @@ var IMPLICIT_ROLE_RECORD = {
282
124
  meter: "meter",
283
125
  output: "status",
284
126
  progress: "progressbar"
285
- };
286
- var INPUT_TYPE_ROLE_MAP = {
127
+ });
128
+ var INPUT_TYPE_ROLE_MAP = Object.freeze({
287
129
  checkbox: "checkbox",
288
130
  radio: "radio",
289
131
  range: "slider",
@@ -297,20 +139,22 @@ var INPUT_TYPE_ROLE_MAP = {
297
139
  submit: "button",
298
140
  reset: "button",
299
141
  image: "button"
300
- };
301
- var STRONG_ROLES = [
142
+ });
143
+ var STRONG_ROLES = Object.freeze([
302
144
  "main",
303
145
  "navigation",
304
146
  "complementary",
305
147
  "contentinfo",
306
148
  "banner"
307
- ];
308
- var STANDALONE_ROLES = ["article"];
149
+ ]);
150
+ var STANDALONE_ROLES = Object.freeze([
151
+ "article"
152
+ ]);
309
153
  var STRONG_ROLES_SET = new Set(STRONG_ROLES);
310
154
  var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
311
155
 
312
156
  // ../../lib/primitive/src/constants/aria/known-aria-roles.ts
313
- var KNOWN_ARIA_ROLES = [
157
+ var KNOWN_ARIA_ROLES = Object.freeze([
314
158
  "alert",
315
159
  "alertdialog",
316
160
  "application",
@@ -392,7 +236,7 @@ var KNOWN_ARIA_ROLES = [
392
236
  "tree",
393
237
  "treegrid",
394
238
  "treeitem"
395
- ];
239
+ ]);
396
240
  var KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
397
241
 
398
242
  // ../../lib/primitive/src/constants/aria/role-restricted-attributes.ts
@@ -550,59 +394,244 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
550
394
  function isGlobalAriaAttribute(attr) {
551
395
  return GLOBAL_ARIA_ATTRIBUTES.has(attr);
552
396
  }
553
- function isAriaAttributeValidForRole(attr, role) {
554
- const allowedRoles = ROLE_RESTRICTED_ATTRIBUTES.get(attr);
555
- if (isUndefined(allowedRoles)) return true;
556
- if (isUndefined(role)) return false;
557
- return allowedRoles.has(role);
397
+ function isAriaAttributeValidForRole(attr, role) {
398
+ const allowedRoles = ROLE_RESTRICTED_ATTRIBUTES.get(attr);
399
+ if (isUndefined(allowedRoles)) return true;
400
+ if (isUndefined(role)) return false;
401
+ return allowedRoles.has(role);
402
+ }
403
+
404
+ // ../../lib/primitive/src/guards/aria/is-aria-role.ts
405
+ function isStrongImplicitRole(tag) {
406
+ if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
407
+ return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
408
+ }
409
+ function isStandaloneTag(tag) {
410
+ if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
411
+ return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
412
+ }
413
+ function getInputImplicitRole(type) {
414
+ if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
415
+ return INPUT_TYPE_ROLE_MAP[type];
416
+ }
417
+ function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
418
+ const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
419
+ if (!isNamed) return void 0;
420
+ if (tag === "section") return "region";
421
+ if (tag === "form") return "form";
422
+ return void 0;
423
+ }
424
+
425
+ // ../../lib/primitive/src/guards/aria/is-known-aria-role.ts
426
+ function isKnownAriaRole(value) {
427
+ return isString(value) && KNOWN_ARIA_ROLES_SET.has(value);
428
+ }
429
+
430
+ // ../../lib/contract/src/aria/aria-role-policy.ts
431
+ function getImplicitRole(tag, props) {
432
+ if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
433
+ if (tag === "input") return getInputImplicitRole(props?.type);
434
+ if (tag === "img") return props?.alt === "" ? "none" : "img";
435
+ if (tag === "section" || tag === "form") {
436
+ return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
437
+ }
438
+ return void 0;
439
+ }
440
+
441
+ // ../../lib/primitive/src/tag/resolve-tag.ts
442
+ function makeResolveTag(defaultTag) {
443
+ return function tag(as) {
444
+ return as ?? defaultTag;
445
+ };
446
+ }
447
+
448
+ // ../../lib/primitive/src/utils/assert-never.ts
449
+ function assertNever(value) {
450
+ throw new Error(`Unexpected value: ${String(value)}`);
451
+ }
452
+
453
+ // ../../lib/primitive/src/utils/cn.ts
454
+ import { clsx } from "clsx";
455
+ function cn(...inputs) {
456
+ return clsx(...inputs);
457
+ }
458
+
459
+ // ../../lib/primitive/src/utils/iterate.ts
460
+ function find(iterable, callback) {
461
+ for (const value of iterable) {
462
+ const result = callback(value);
463
+ if (result != null) {
464
+ return result;
465
+ }
466
+ }
467
+ return null;
468
+ }
469
+ function some(iterable, predicate) {
470
+ for (const value of iterable) {
471
+ if (predicate(value)) return true;
472
+ }
473
+ return false;
474
+ }
475
+ function every(iterable, predicate) {
476
+ let index = 0;
477
+ for (const value of iterable) {
478
+ if (!predicate(value, index++)) {
479
+ return false;
480
+ }
481
+ }
482
+ return true;
483
+ }
484
+ function* filter(iterable, predicate) {
485
+ let index = 0;
486
+ for (const value of iterable) {
487
+ if (predicate(value, index++)) {
488
+ yield value;
489
+ }
490
+ }
491
+ }
492
+ function* map(iterable, callback) {
493
+ let index = 0;
494
+ for (const value of iterable) {
495
+ yield callback(value, index++);
496
+ }
497
+ }
498
+ function forEach(iterable, callback) {
499
+ let index = 0;
500
+ for (const value of iterable) {
501
+ callback(value, index++);
502
+ }
503
+ }
504
+ function reduce(iterable, initial, callback) {
505
+ let accumulator = initial;
506
+ let index = 0;
507
+ for (const value of iterable) {
508
+ accumulator = callback(accumulator, value, index++);
509
+ }
510
+ return accumulator;
511
+ }
512
+ function collect(iterable, callback) {
513
+ const result = {};
514
+ let index = 0;
515
+ for (const value of iterable) {
516
+ const entry = callback(value, index++);
517
+ if (entry === null) {
518
+ return null;
519
+ }
520
+ result[entry[0]] = entry[1];
521
+ }
522
+ return result;
523
+ }
524
+ function findLast(value, callback) {
525
+ for (let index = value.length - 1; index >= 0; index--) {
526
+ const result = callback(value[index], index);
527
+ if (result != null) {
528
+ return result;
529
+ }
530
+ }
531
+ return null;
532
+ }
533
+ function* items(collection) {
534
+ for (let i = 0; i < collection.length; i++) {
535
+ const item = collection.item(i);
536
+ if (item !== null) {
537
+ yield item;
538
+ }
539
+ }
540
+ }
541
+ function nodeList(list) {
542
+ return {
543
+ *[Symbol.iterator]() {
544
+ for (let i = 0; i < list.length; i++) {
545
+ const node = list.item(i);
546
+ if (node !== null) {
547
+ yield node;
548
+ }
549
+ }
550
+ }
551
+ };
558
552
  }
559
-
560
- // ../../lib/primitive/src/guards/aria/is-aria-role.ts
561
- function isStrongImplicitRole(tag) {
562
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
563
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
553
+ function mapEntries(m) {
554
+ return m.entries();
564
555
  }
565
- function isStandaloneTag(tag) {
566
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
567
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
556
+ function set(s) {
557
+ return s.values();
568
558
  }
569
- function getInputImplicitRole(type) {
570
- if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
571
- return INPUT_TYPE_ROLE_MAP[type];
559
+ function hasOwn(object, key) {
560
+ return Object.hasOwn(object, key);
572
561
  }
573
- function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
574
- const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
575
- if (!isNamed) return void 0;
576
- if (tag === "section") return "region";
577
- if (tag === "form") return "form";
578
- return void 0;
562
+ function* entries(object) {
563
+ for (const key in object) {
564
+ if (!hasOwn(object, key)) continue;
565
+ yield [key, object[key]];
566
+ }
579
567
  }
580
-
581
- // ../../lib/primitive/src/guards/aria/is-known-aria-role.ts
582
- function isKnownAriaRole(value) {
583
- return isString(value) && KNOWN_ARIA_ROLES_SET.has(value);
568
+ function* keys(object) {
569
+ for (const [key] of entries(object)) {
570
+ yield key;
571
+ }
584
572
  }
585
-
586
- // ../../lib/adapter-utils/src/apply-filter.ts
587
- function applyFilter(props, filterProps, variantKeys) {
588
- const out = {};
589
- iterate.forEachEntry(props, (k) => {
590
- if (!Object.hasOwn(props, k)) return;
591
- if (filterProps(k, variantKeys)) return;
592
- out[k] = props[k];
593
- });
594
- return out;
573
+ function* values(object) {
574
+ for (const [, value] of entries(object)) {
575
+ yield value;
576
+ }
595
577
  }
596
-
597
- // ../../lib/contract/src/aria/aria-role-policy.ts
598
- function getImplicitRole(tag, props) {
599
- if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
600
- if (tag === "input") return getInputImplicitRole(props?.type);
601
- if (tag === "img") return props?.alt === "" ? "none" : "img";
602
- if (tag === "section" || tag === "form") {
603
- return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
578
+ function mapValues(object, callback) {
579
+ const result = {};
580
+ for (const [key, value] of entries(object)) {
581
+ result[key] = callback(value, key);
604
582
  }
605
- return void 0;
583
+ return result;
584
+ }
585
+ function forEachEntry(object, callback) {
586
+ for (const [key, value] of entries(object)) {
587
+ callback(key, value);
588
+ }
589
+ }
590
+ function forEachKey(object, callback) {
591
+ for (const key of keys(object)) {
592
+ callback(key);
593
+ }
594
+ }
595
+ function forEachValue(object, callback) {
596
+ for (const value of values(object)) {
597
+ callback(value);
598
+ }
599
+ }
600
+ function forEachSet(s, callback) {
601
+ for (const value of s) {
602
+ callback(value);
603
+ }
604
+ }
605
+ var iterate = Object.freeze({
606
+ entries,
607
+ filter,
608
+ find,
609
+ findLast,
610
+ forEach,
611
+ forEachEntry,
612
+ forEachKey,
613
+ forEachSet,
614
+ forEachValue,
615
+ items,
616
+ keys,
617
+ map,
618
+ mapEntries,
619
+ mapValues,
620
+ nodeList,
621
+ reduce,
622
+ collect,
623
+ set,
624
+ some,
625
+ every,
626
+ values
627
+ });
628
+
629
+ // ../../lib/primitive/src/utils/merge-props.ts
630
+ function mergeProps(defaultProps, props) {
631
+ return {
632
+ ...defaultProps ?? {},
633
+ ...props
634
+ };
606
635
  }
607
636
 
608
637
  // ../../lib/contract/src/strict/invariant-base.ts
@@ -627,159 +656,21 @@ var InvariantBase = class {
627
656
  }
628
657
  };
629
658
 
630
- // ../../lib/diagnostics/src/category.ts
631
- var DiagnosticCategory = /* @__PURE__ */ ((DiagnosticCategory2) => {
632
- DiagnosticCategory2[DiagnosticCategory2["Contract"] = 0] = "Contract";
633
- DiagnosticCategory2[DiagnosticCategory2["HTML"] = 1] = "HTML";
634
- DiagnosticCategory2[DiagnosticCategory2["ARIA"] = 2] = "ARIA";
635
- DiagnosticCategory2[DiagnosticCategory2["Composition"] = 3] = "Composition";
636
- DiagnosticCategory2[DiagnosticCategory2["Rendering"] = 4] = "Rendering";
637
- DiagnosticCategory2[DiagnosticCategory2["Accessibility"] = 5] = "Accessibility";
638
- DiagnosticCategory2[DiagnosticCategory2["Performance"] = 6] = "Performance";
639
- DiagnosticCategory2[DiagnosticCategory2["Internal"] = 7] = "Internal";
640
- DiagnosticCategory2[DiagnosticCategory2["Deprecation"] = 8] = "Deprecation";
641
- DiagnosticCategory2[DiagnosticCategory2["Lint"] = 9] = "Lint";
642
- return DiagnosticCategory2;
643
- })(DiagnosticCategory || {});
644
-
645
- // ../../lib/diagnostics/src/error.ts
646
- var PraxisError = class extends Error {
647
- diagnostic;
648
- constructor(diagnostic) {
649
- super(diagnostic.message);
650
- this.name = "PraxisError";
651
- this.diagnostic = diagnostic;
652
- }
653
- };
654
-
655
- // ../../lib/diagnostics/src/severity.ts
656
- var Severity = /* @__PURE__ */ ((Severity2) => {
657
- Severity2[Severity2["Debug"] = 0] = "Debug";
658
- Severity2[Severity2["Info"] = 1] = "Info";
659
- Severity2[Severity2["Warning"] = 2] = "Warning";
660
- Severity2[Severity2["Error"] = 3] = "Error";
661
- Severity2[Severity2["Fatal"] = 4] = "Fatal";
662
- return Severity2;
663
- })(Severity || {});
664
-
665
- // ../../lib/diagnostics/src/policy.ts
666
- var DefaultPolicy = class {
667
- reportThreshold;
668
- throwThreshold;
669
- constructor({
670
- reportThreshold = 1 /* Info */,
671
- throwThreshold = 4 /* Fatal */
672
- } = {}) {
673
- this.reportThreshold = reportThreshold;
674
- this.throwThreshold = throwThreshold;
675
- }
676
- resolve(diagnostic) {
677
- if (diagnostic.severity >= this.throwThreshold) return 2 /* Throw */;
678
- if (diagnostic.severity >= this.reportThreshold) return 1 /* Report */;
679
- return 0 /* Ignore */;
680
- }
681
- };
682
-
683
- // ../../lib/diagnostics/src/diagnostics.ts
684
- var Diagnostics = class {
685
- reporter;
686
- policy;
687
- // Pre-computed at construction time: true if Warning-level diagnostics are not ignored.
688
- active;
689
- constructor(reporter, policy = new DefaultPolicy()) {
690
- this.reporter = reporter;
691
- this.policy = policy;
692
- this.active = policy.resolve({ severity: 2 /* Warning */ }) !== 0 /* Ignore */;
693
- }
694
- report(diagnostic) {
695
- const enforcement = this.policy.resolve(diagnostic);
696
- if (enforcement === 0 /* Ignore */) return diagnostic;
697
- if (enforcement === 2 /* Throw */) throw new PraxisError(diagnostic);
698
- this.reporter.report(diagnostic);
699
- return diagnostic;
700
- }
701
- warn(input) {
702
- return this.report({ ...input, severity: 2 /* Warning */ });
703
- }
704
- error(input) {
705
- return this.report({ ...input, severity: 3 /* Error */ });
706
- }
707
- info(input) {
708
- return this.report({ ...input, severity: 1 /* Info */ });
709
- }
710
- };
711
-
712
- // ../../lib/diagnostics/src/formatter.ts
713
- function formatDiagnostic(diagnostic) {
714
- const level = Severity[diagnostic.severity];
715
- const category = DiagnosticCategory[diagnostic.category];
716
- const prefix = category !== void 0 ? `[${category}] ` : "";
717
- return `${level} ${diagnostic.code}: ${prefix}${diagnostic.message}`;
718
- }
719
-
720
- // ../../lib/diagnostics/src/console-reporter.ts
721
- var ConsoleReporter = class {
722
- report(diagnostic) {
723
- const message = formatDiagnostic(diagnostic);
724
- switch (diagnostic.severity) {
725
- case 0 /* Debug */:
726
- console.debug(message);
727
- break;
728
- case 1 /* Info */:
729
- console.info(message);
730
- break;
731
- case 2 /* Warning */:
732
- console.warn(message);
733
- break;
734
- case 3 /* Error */:
735
- case 4 /* Fatal */:
736
- console.error(message);
737
- break;
738
- }
739
- }
740
- };
741
-
742
- // ../../lib/diagnostics/src/null-reporter.ts
743
- var nullReporter = {
744
- report() {
745
- }
746
- };
747
-
748
- // ../../lib/diagnostics/src/presets.ts
749
- var ignoreAllPolicy = {
750
- resolve(_) {
751
- return 0 /* Ignore */;
752
- }
753
- };
754
- var warnOnlyReporter = {
755
- report(diagnostic) {
756
- console.warn(formatDiagnostic(diagnostic));
757
- }
758
- };
759
- var silentDiagnostics = new Diagnostics(nullReporter, ignoreAllPolicy);
760
- var warnDiagnostics = new Diagnostics(
761
- warnOnlyReporter,
762
- new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 4 /* Fatal */ })
763
- );
764
- var throwDiagnostics = new Diagnostics(
765
- new ConsoleReporter(),
766
- new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 3 /* Error */ })
767
- );
768
-
769
659
  // ../../lib/contract/src/diagnostics/aria.ts
660
+ import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
770
661
  var AriaDiagnostics = {
771
662
  /** Generic bridge for violations produced by external AriaRule functions. */
772
663
  fromViolation(v) {
773
664
  return {
774
- code: "ARIA2002" /* AriaViolation */,
775
- category: 2 /* ARIA */,
665
+ code: DiagnosticCode.AriaViolation,
666
+ category: DiagnosticCategory.ARIA,
776
667
  message: v.message
777
668
  };
778
669
  },
779
670
  attributeInvalid(key, role) {
780
671
  return {
781
- code: "ARIA2003" /* AriaAttributeInvalid */,
782
- category: 2 /* ARIA */,
672
+ code: DiagnosticCode.AriaAttributeInvalid,
673
+ category: DiagnosticCategory.ARIA,
783
674
  message: `"${key}" is not valid on role="${role}". It will be removed.`,
784
675
  rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
785
676
  suggestions: [
@@ -792,8 +683,8 @@ var AriaDiagnostics = {
792
683
  },
793
684
  missingLiveRegion(role, impliedLive) {
794
685
  return {
795
- code: "ARIA2004" /* AriaMissingLiveRegion */,
796
- category: 2 /* ARIA */,
686
+ code: DiagnosticCode.AriaMissingLiveRegion,
687
+ category: DiagnosticCategory.ARIA,
797
688
  message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
798
689
  rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
799
690
  suggestions: [
@@ -807,8 +698,8 @@ var AriaDiagnostics = {
807
698
  },
808
699
  missingAtomic(role) {
809
700
  return {
810
- code: "ARIA2005" /* AriaMissingAtomic */,
811
- category: 2 /* ARIA */,
701
+ code: DiagnosticCode.AriaMissingAtomic,
702
+ category: DiagnosticCategory.ARIA,
812
703
  message: `role="${role}" is a live region. Consider setting aria-atomic="true" if the full region should be announced as a unit, or aria-atomic="false" if only changed nodes should be read.`,
813
704
  rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
814
705
  };
@@ -816,8 +707,8 @@ var AriaDiagnostics = {
816
707
  relevantInvalidTokens(invalid) {
817
708
  const quoted = invalid.map((t) => `"${t}"`).join(", ");
818
709
  return {
819
- code: "ARIA2006" /* AriaRelevantInvalidToken */,
820
- category: 2 /* ARIA */,
710
+ code: DiagnosticCode.AriaRelevantInvalidToken,
711
+ category: DiagnosticCategory.ARIA,
821
712
  message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
822
713
  rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
823
714
  suggestions: [
@@ -830,8 +721,8 @@ var AriaDiagnostics = {
830
721
  },
831
722
  relevantSuperseded() {
832
723
  return {
833
- code: "ARIA2007" /* AriaRelevantSuperseded */,
834
- category: 2 /* ARIA */,
724
+ code: DiagnosticCode.AriaRelevantSuperseded,
725
+ category: DiagnosticCategory.ARIA,
835
726
  message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
836
727
  rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
837
728
  suggestions: [
@@ -844,8 +735,8 @@ var AriaDiagnostics = {
844
735
  },
845
736
  missingAccessibleName(tag) {
846
737
  return {
847
- code: "ARIA2009" /* AriaMissingAccessibleName */,
848
- category: 2 /* ARIA */,
738
+ code: DiagnosticCode.AriaMissingAccessibleName,
739
+ category: DiagnosticCategory.ARIA,
849
740
  message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
850
741
  rationale: "Elements with a landmark or interactive role must have an accessible name so that assistive technology can identify them when presenting the page outline.",
851
742
  suggestions: [
@@ -862,8 +753,8 @@ var AriaDiagnostics = {
862
753
  },
863
754
  attributeOnPresentational(attr, tag) {
864
755
  return {
865
- code: "ARIA2010" /* AriaAttributeOnPresentational */,
866
- category: 2 /* ARIA */,
756
+ code: DiagnosticCode.AriaAttributeOnPresentational,
757
+ category: DiagnosticCategory.ARIA,
867
758
  message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
868
759
  rationale: 'role="none" and role="presentation" (including <img alt="">) remove an element from the accessibility tree. ARIA attributes on such elements are ignored by assistive technology.',
869
760
  suggestions: [
@@ -876,8 +767,8 @@ var AriaDiagnostics = {
876
767
  },
877
768
  ariaHiddenOnFocusable(tag) {
878
769
  return {
879
- code: "ARIA2011" /* AriaHiddenOnFocusable */,
880
- category: 2 /* ARIA */,
770
+ code: DiagnosticCode.AriaHiddenOnFocusable,
771
+ category: DiagnosticCategory.ARIA,
881
772
  message: `aria-hidden="true" must not be used on focusable <${tag}> elements. Screen reader users who navigate by keyboard will encounter the element but receive no information about it.`,
882
773
  rationale: 'aria-hidden removes an element from the accessibility tree while leaving it keyboard-reachable. This creates a "ghost" \u2014 a focusable element assistive technology cannot describe.',
883
774
  suggestions: [
@@ -895,8 +786,8 @@ var AriaDiagnostics = {
895
786
  invalidAttributeValue(attr, value, expected) {
896
787
  const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
897
788
  return {
898
- code: "ARIA2013" /* AriaInvalidAttributeValue */,
899
- category: 2 /* ARIA */,
789
+ code: DiagnosticCode.AriaInvalidAttributeValue,
790
+ category: DiagnosticCategory.ARIA,
900
791
  message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
901
792
  rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
902
793
  suggestions: [
@@ -909,8 +800,8 @@ var AriaDiagnostics = {
909
800
  },
910
801
  redundantAriaLevel(tag, level) {
911
802
  return {
912
- code: "ARIA2014" /* AriaRedundantLevelAttribute */,
913
- category: 2 /* ARIA */,
803
+ code: DiagnosticCode.AriaRedundantLevelAttribute,
804
+ category: DiagnosticCategory.ARIA,
914
805
  message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
915
806
  rationale: 'Restating the implicit aria-level adds noise without semantic value. Use aria-level only to override the native heading level (e.g. aria-level="3" on <h2>).',
916
807
  suggestions: [
@@ -923,8 +814,8 @@ var AriaDiagnostics = {
923
814
  },
924
815
  requiredProperty(attr, role) {
925
816
  return {
926
- code: "ARIA2012" /* AriaRequiredProperty */,
927
- category: 2 /* ARIA */,
817
+ code: DiagnosticCode.AriaRequiredProperty,
818
+ category: DiagnosticCategory.ARIA,
928
819
  message: `"${attr}" is required for role="${role}" but is missing.`,
929
820
  rationale: `WAI-ARIA 1.2 specifies required states and properties for certain roles. Without "${attr}", assistive technology cannot correctly communicate the element's state to users.`,
930
821
  suggestions: [
@@ -937,8 +828,8 @@ var AriaDiagnostics = {
937
828
  },
938
829
  invalidRole(role, tag) {
939
830
  return {
940
- code: "ARIA2008" /* AriaInvalidRole */,
941
- category: 2 /* ARIA */,
831
+ code: DiagnosticCode.AriaInvalidRole,
832
+ category: DiagnosticCategory.ARIA,
942
833
  message: `Invalid role "${role ?? ""}" on <${tag}>.`,
943
834
  rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
944
835
  };
@@ -946,11 +837,12 @@ var AriaDiagnostics = {
946
837
  };
947
838
 
948
839
  // ../../lib/contract/src/diagnostics/contract.ts
840
+ import { DiagnosticCategory as DiagnosticCategory2, DiagnosticCode as DiagnosticCode2 } from "../_shared/diagnostics.js";
949
841
  var ContractDiagnostics = {
950
842
  unexpectedChild(typeName, index, context) {
951
843
  return {
952
- code: "COMP1004" /* UnexpectedChild */,
953
- category: 0 /* Contract */,
844
+ code: DiagnosticCode2.UnexpectedChild,
845
+ category: DiagnosticCategory2.Contract,
954
846
  component: context,
955
847
  message: `${context}: unexpected child "${typeName}" at index ${index}.`
956
848
  };
@@ -958,69 +850,69 @@ var ContractDiagnostics = {
958
850
  ambiguousChild(typeName, index, ruleNames, context) {
959
851
  const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
960
852
  return {
961
- code: "COMP1005" /* AmbiguousChild */,
962
- category: 0 /* Contract */,
853
+ code: DiagnosticCode2.AmbiguousChild,
854
+ category: DiagnosticCategory2.Contract,
963
855
  component: context,
964
856
  message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
965
857
  };
966
858
  },
967
859
  cardinalityMin(ruleName, min, context) {
968
860
  return {
969
- code: "COMP1006" /* CardinalityMin */,
970
- category: 0 /* Contract */,
861
+ code: DiagnosticCode2.CardinalityMin,
862
+ category: DiagnosticCategory2.Contract,
971
863
  component: context,
972
864
  message: `${context}: "${ruleName}" requires at least ${min}.`
973
865
  };
974
866
  },
975
867
  cardinalityMax(ruleName, max, context) {
976
868
  return {
977
- code: "COMP1007" /* CardinalityMax */,
978
- category: 0 /* Contract */,
869
+ code: DiagnosticCode2.CardinalityMax,
870
+ category: DiagnosticCategory2.Contract,
979
871
  component: context,
980
872
  message: `${context}: "${ruleName}" allows at most ${max}.`
981
873
  };
982
874
  },
983
875
  positionViolation(ruleName, position, index, context) {
984
876
  return {
985
- code: "COMP1008" /* PositionViolation */,
986
- category: 0 /* Contract */,
877
+ code: DiagnosticCode2.PositionViolation,
878
+ category: DiagnosticCategory2.Contract,
987
879
  component: context,
988
880
  message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
989
881
  };
990
882
  },
991
883
  unknownVariantDim(component, label2, dim) {
992
884
  return {
993
- code: "COMP1010" /* ContractUnknownVariantDim */,
994
- category: 0 /* Contract */,
885
+ code: DiagnosticCode2.ContractUnknownVariantDim,
886
+ category: DiagnosticCategory2.Contract,
995
887
  message: `${component}: ${label2} references unknown variant "${dim}".`
996
888
  };
997
889
  },
998
890
  unknownVariantValue(component, label2, dim, value, valid) {
999
891
  return {
1000
- code: "COMP1011" /* ContractUnknownVariantValue */,
1001
- category: 0 /* Contract */,
892
+ code: DiagnosticCode2.ContractUnknownVariantValue,
893
+ category: DiagnosticCategory2.Contract,
1002
894
  message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
1003
895
  };
1004
896
  },
1005
897
  unknownRecipeKey(component, key) {
1006
898
  return {
1007
- code: "COMP1012" /* ContractUnknownRecipeKey */,
1008
- category: 0 /* Contract */,
899
+ code: DiagnosticCode2.ContractUnknownRecipeKey,
900
+ category: DiagnosticCategory2.Contract,
1009
901
  message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
1010
902
  };
1011
903
  },
1012
904
  invalidVariantValue(component, key, value) {
1013
905
  return {
1014
- code: "COMP1013" /* ContractInvalidVariantValue */,
1015
- category: 0 /* Contract */,
906
+ code: DiagnosticCode2.ContractInvalidVariantValue,
907
+ category: DiagnosticCategory2.Contract,
1016
908
  message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
1017
909
  };
1018
910
  },
1019
911
  allowedAsViolation(tag, allowedAs, component) {
1020
912
  const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
1021
913
  return {
1022
- code: "COMP1009" /* AllowedAsViolation */,
1023
- category: 0 /* Contract */,
914
+ code: DiagnosticCode2.AllowedAsViolation,
915
+ category: DiagnosticCategory2.Contract,
1024
916
  component,
1025
917
  message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
1026
918
  };
@@ -1028,73 +920,75 @@ var ContractDiagnostics = {
1028
920
  };
1029
921
 
1030
922
  // ../../lib/contract/src/diagnostics/html.ts
923
+ import { DiagnosticCategory as DiagnosticCategory3, DiagnosticCode as DiagnosticCode3 } from "../_shared/diagnostics.js";
1031
924
  var HtmlDiagnostics = {
1032
925
  emptyRole(tag) {
1033
926
  return {
1034
- code: "HTML3002" /* HtmlEmptyRole */,
1035
- category: 1 /* HTML */,
927
+ code: DiagnosticCode3.HtmlEmptyRole,
928
+ category: DiagnosticCategory3.HTML,
1036
929
  message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
1037
930
  };
1038
931
  },
1039
932
  implicitRoleRedundant(tag, implicitRole) {
1040
933
  return {
1041
- code: "HTML3003" /* HtmlImplicitRoleRedundant */,
1042
- category: 1 /* HTML */,
934
+ code: DiagnosticCode3.HtmlImplicitRoleRedundant,
935
+ category: DiagnosticCategory3.HTML,
1043
936
  message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
1044
937
  };
1045
938
  },
1046
939
  implicitRoleOverride(tag, implicitRole, role) {
1047
940
  return {
1048
- code: "HTML3004" /* HtmlImplicitRoleOverride */,
1049
- category: 1 /* HTML */,
941
+ code: DiagnosticCode3.HtmlImplicitRoleOverride,
942
+ category: DiagnosticCategory3.HTML,
1050
943
  message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
1051
944
  };
1052
945
  },
1053
946
  standaloneRegionOverride(tag, implicitRole) {
1054
947
  return {
1055
- code: "HTML3005" /* HtmlStandaloneRegionOverride */,
1056
- category: 1 /* HTML */,
948
+ code: DiagnosticCode3.HtmlStandaloneRegionOverride,
949
+ category: DiagnosticCategory3.HTML,
1057
950
  message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
1058
951
  };
1059
952
  },
1060
953
  landmarkRoleOverride(tag, implicitRole, role) {
1061
954
  return {
1062
- code: "HTML3006" /* HtmlLandmarkRoleOverride */,
1063
- category: 1 /* HTML */,
955
+ code: DiagnosticCode3.HtmlLandmarkRoleOverride,
956
+ category: DiagnosticCategory3.HTML,
1064
957
  message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
1065
958
  };
1066
959
  },
1067
960
  invalidChild(child, parent, allowed) {
1068
961
  return {
1069
- code: "HTML3007" /* HtmlInvalidChild */,
1070
- category: 1 /* HTML */,
962
+ code: DiagnosticCode3.HtmlInvalidChild,
963
+ category: DiagnosticCategory3.HTML,
1071
964
  message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
1072
965
  };
1073
966
  }
1074
967
  };
1075
968
 
1076
969
  // ../../lib/contract/src/diagnostics/slot.ts
970
+ import { DiagnosticCategory as DiagnosticCategory4, DiagnosticCode as DiagnosticCode4 } from "../_shared/diagnostics.js";
1077
971
  var SlotDiagnostics = {
1078
972
  exclusive(name) {
1079
973
  return {
1080
- code: "SLOT1001" /* SlotExclusive */,
1081
- category: 0 /* Contract */,
974
+ code: DiagnosticCode4.SlotExclusive,
975
+ category: DiagnosticCategory4.Contract,
1082
976
  component: name,
1083
977
  message: `${name}: "as" and "asChild" are mutually exclusive`
1084
978
  };
1085
979
  },
1086
980
  singleChildRequired(name, elementTerm) {
1087
981
  return {
1088
- code: "SLOT1002" /* SlotSingleChild */,
1089
- category: 0 /* Contract */,
982
+ code: DiagnosticCode4.SlotSingleChild,
983
+ category: DiagnosticCategory4.Contract,
1090
984
  component: name,
1091
985
  message: `${name}: asChild requires a ${elementTerm} child`
1092
986
  };
1093
987
  },
1094
988
  singleChildExceeded(name, elementTerm, count) {
1095
989
  return {
1096
- code: "SLOT1002" /* SlotSingleChild */,
1097
- category: 0 /* Contract */,
990
+ code: DiagnosticCode4.SlotSingleChild,
991
+ category: DiagnosticCategory4.Contract,
1098
992
  component: name,
1099
993
  message: `${name}: asChild requires exactly one ${elementTerm} child, got ${count}`
1100
994
  };
@@ -1102,16 +996,16 @@ var SlotDiagnostics = {
1102
996
  discardedChildren(name, elementTerm, count) {
1103
997
  const suffix = count === 1 ? "" : "ren";
1104
998
  return {
1105
- code: "SLOT1003" /* SlotDiscardedChildren */,
1106
- category: 0 /* Contract */,
999
+ code: DiagnosticCode4.SlotDiscardedChildren,
1000
+ category: DiagnosticCategory4.Contract,
1107
1001
  component: name,
1108
1002
  message: `${name}: asChild discarded ${count} non-element child${suffix} \u2014 only ${elementTerm}s are valid asChild children.`
1109
1003
  };
1110
1004
  },
1111
1005
  renderFnRequired(name, received) {
1112
1006
  return {
1113
- code: "SLOT1004" /* SlotRenderFn */,
1114
- category: 0 /* Contract */,
1007
+ code: DiagnosticCode4.SlotRenderFn,
1008
+ category: DiagnosticCategory4.Contract,
1115
1009
  component: name,
1116
1010
  message: `${name}: asChild requires a render function as children, got ${received}`
1117
1011
  };
@@ -1795,7 +1689,7 @@ function getTypeName(value) {
1795
1689
  return primitive;
1796
1690
  }
1797
1691
  const name = value.constructor?.name;
1798
- return typeof name === "string" && name !== "Object" ? name : "object";
1692
+ return isString(name) && name !== "Object" ? name : "object";
1799
1693
  }
1800
1694
 
1801
1695
  // ../../lib/contract/src/children/normalize-child-rule.ts
@@ -2046,6 +1940,9 @@ var readonlyProps = ({
2046
1940
  };
2047
1941
  };
2048
1942
 
1943
+ // ../core/src/html/evaluators.ts
1944
+ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
1945
+
2049
1946
  // ../core/src/html/aria-rules.ts
2050
1947
  var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
2051
1948
  var removeLandmarkRoleOverride = {
@@ -2088,6 +1985,167 @@ function landmarkNameAdvisory(ctx) {
2088
1985
  }
2089
1986
  var HTML_ARIA_RULES = [landmarkRoleRule, landmarkNameAdvisory];
2090
1987
 
1988
+ // ../core/src/html/contracts.ts
1989
+ import { warnDiagnostics } from "../_shared/diagnostics.js";
1990
+ function isOpenContent(...blockedTags) {
1991
+ const set2 = new Set(blockedTags);
1992
+ return (child) => isObject(child) && "type" in child && (!isString(child.type) || !set2.has(child.type));
1993
+ }
1994
+ var METADATA_TAGS = ["script", "template"];
1995
+ var metadataMatch = isTag(...METADATA_TAGS);
1996
+ function metadata(name = "metadata") {
1997
+ return { name, match: metadataMatch };
1998
+ }
1999
+ function firstOptional(name, tag) {
2000
+ return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
2001
+ }
2002
+ function contract(children) {
2003
+ return { diagnostics: warnDiagnostics, children };
2004
+ }
2005
+ function ariaContract(aria) {
2006
+ return { diagnostics: warnDiagnostics, aria };
2007
+ }
2008
+ function firstChildContract(name, tag) {
2009
+ return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
2010
+ }
2011
+ var VOID_TAGS = [
2012
+ "area",
2013
+ "base",
2014
+ "br",
2015
+ "col",
2016
+ "embed",
2017
+ "hr",
2018
+ "img",
2019
+ "input",
2020
+ "link",
2021
+ "meta",
2022
+ "param",
2023
+ "source",
2024
+ "track",
2025
+ "wbr"
2026
+ ];
2027
+ var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
2028
+ var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
2029
+ var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
2030
+ var tableContract = contract([
2031
+ firstOptional("caption", "caption"),
2032
+ { name: "colgroup", match: isTag("colgroup") },
2033
+ { name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
2034
+ { name: "tbody", match: isTag("tbody") },
2035
+ { name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
2036
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2037
+ ]);
2038
+ var tableBodyContract = contract([
2039
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
2040
+ ]);
2041
+ var tableRowContract = contract([
2042
+ { name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
2043
+ ]);
2044
+ var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
2045
+ var dlContract = contract([
2046
+ { name: "term", match: isTag("dt") },
2047
+ { name: "description", match: isTag("dd") },
2048
+ { name: "group", match: isTag("div") },
2049
+ metadata()
2050
+ ]);
2051
+ var selectContract = contract([
2052
+ { name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
2053
+ ]);
2054
+ var optgroupContract = contract([
2055
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
2056
+ ]);
2057
+ var datalistContract = contract([
2058
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
2059
+ ]);
2060
+ var pictureContract = contract([
2061
+ { name: "source", match: isTag("source", ...METADATA_TAGS) },
2062
+ { name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
2063
+ ]);
2064
+ var figureContract = contract([
2065
+ { name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
2066
+ { name: "content", match: isOpenContent("figcaption") }
2067
+ ]);
2068
+ var detailsContract = firstChildContract("summary", "summary");
2069
+ var fieldsetContract = firstChildContract("legend", "legend");
2070
+ var mediaContract = contract([
2071
+ { name: "source", match: isTag("source") },
2072
+ { name: "track", match: isTag("track") },
2073
+ metadata(),
2074
+ { name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
2075
+ ]);
2076
+ var headContract = contract([
2077
+ {
2078
+ name: "metadata",
2079
+ match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
2080
+ }
2081
+ ]);
2082
+ var htmlContract = contract([
2083
+ { name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
2084
+ { name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
2085
+ ]);
2086
+ var voidContract = contract([]);
2087
+ var textOnlyContract = contract([
2088
+ {
2089
+ name: "text",
2090
+ match: (child) => isString(child) || isNumber(child)
2091
+ }
2092
+ ]);
2093
+ var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
2094
+ var dialogContract = ariaContract([requireAccessibleName]);
2095
+ var menuContract = ariaContract([requireAccessibleName]);
2096
+ var menubarContract = ariaContract([requireAccessibleName]);
2097
+ var treeContract = ariaContract([requireAccessibleName]);
2098
+ var gridContract = ariaContract([requireAccessibleName]);
2099
+ var listboxContract = ariaContract([requireAccessibleName]);
2100
+ var tablistContract = ariaContract([requireAccessibleName]);
2101
+ var radiogroupContract = ariaContract([requireAccessibleName]);
2102
+ var CONTRACT_GROUPS = [
2103
+ [VOID_TAGS, voidContract],
2104
+ [TEXT_ONLY_TAGS, textOnlyContract],
2105
+ [LANDMARK_TAGS, landmarkContract],
2106
+ [["ul", "ol", "menu"], listContract],
2107
+ [["audio", "video"], mediaContract],
2108
+ [["thead", "tbody", "tfoot"], tableBodyContract]
2109
+ ];
2110
+ function contractMap(groups) {
2111
+ return Object.fromEntries(
2112
+ groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
2113
+ );
2114
+ }
2115
+ var htmlContracts = {
2116
+ ...contractMap(CONTRACT_GROUPS),
2117
+ table: tableContract,
2118
+ tr: tableRowContract,
2119
+ colgroup: colgroupContract,
2120
+ dl: dlContract,
2121
+ select: selectContract,
2122
+ optgroup: optgroupContract,
2123
+ datalist: datalistContract,
2124
+ picture: pictureContract,
2125
+ figure: figureContract,
2126
+ details: detailsContract,
2127
+ fieldset: fieldsetContract,
2128
+ dialog: dialogContract,
2129
+ head: headContract,
2130
+ html: htmlContract
2131
+ };
2132
+
2133
+ // ../core/src/html/evaluators.ts
2134
+ var htmlDiagnostics = warnDiagnostics2;
2135
+ function buildEvaluatorMap() {
2136
+ const map2 = /* @__PURE__ */ new Map();
2137
+ iterate.forEachEntry(htmlContracts, (tag, { children }) => {
2138
+ if (children?.length) {
2139
+ map2.set(tag, new ChildrenEvaluator(children, htmlDiagnostics, `<${tag}>`));
2140
+ }
2141
+ });
2142
+ return map2;
2143
+ }
2144
+ var HTML_EVALUATORS = buildEvaluatorMap();
2145
+ function getHtmlChildrenEvaluator(tag) {
2146
+ return typeof tag === "string" ? HTML_EVALUATORS.get(tag) : void 0;
2147
+ }
2148
+
2091
2149
  // ../core/src/html/prop-normalizers.ts
2092
2150
  var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
2093
2151
  ["button", [disabledProps]],
@@ -2275,7 +2333,21 @@ function createClassPipeline(resolved) {
2275
2333
  };
2276
2334
  }
2277
2335
 
2336
+ // ../../lib/pipeline-kit/src/factory/define-pipeline.ts
2337
+ function definePipeline(factory) {
2338
+ const cache = /* @__PURE__ */ new WeakMap();
2339
+ return (resolved) => {
2340
+ let pipeline = cache.get(resolved);
2341
+ if (!pipeline) {
2342
+ pipeline = factory(resolved);
2343
+ cache.set(resolved, pipeline);
2344
+ }
2345
+ return pipeline;
2346
+ };
2347
+ }
2348
+
2278
2349
  // ../core/src/options/resolve-factory-options.ts
2350
+ import { silentDiagnostics } from "../_shared/diagnostics.js";
2279
2351
  var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
2280
2352
  function composeNormalizers(normalizers, fn) {
2281
2353
  if (!normalizers?.length) return fn;
@@ -2367,21 +2439,25 @@ function validateRenderProps(diagnostics, options, props, recipeKey) {
2367
2439
  }
2368
2440
  }
2369
2441
 
2442
+ // ../core/src/factory/plugin-invariants.ts
2443
+ import { throwDiagnostics } from "../_shared/diagnostics.js";
2444
+
2370
2445
  // ../core/src/factory/plugin-diagnostics.ts
2446
+ import { DiagnosticCategory as DiagnosticCategory5, DiagnosticCode as DiagnosticCode5 } from "../_shared/diagnostics.js";
2371
2447
  var PluginDiagnostics = {
2372
2448
  invalidShape(received) {
2373
2449
  const got = received === null ? "null" : typeof received;
2374
2450
  return {
2375
- code: "PLUGIN7001" /* PluginInvalidShape */,
2376
- category: 7 /* Internal */,
2451
+ code: DiagnosticCode5.PluginInvalidShape,
2452
+ category: DiagnosticCategory5.Internal,
2377
2453
  message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
2378
2454
  };
2379
2455
  },
2380
2456
  pipelineReturnType(received) {
2381
2457
  const got = received === null ? "null" : Array.isArray(received) ? "array" : typeof received;
2382
2458
  return {
2383
- code: "PLUGIN7002" /* PluginPipelineReturnType */,
2384
- category: 7 /* Internal */,
2459
+ code: DiagnosticCode5.PluginPipelineReturnType,
2460
+ category: DiagnosticCategory5.Internal,
2385
2461
  message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
2386
2462
  };
2387
2463
  }
@@ -2405,89 +2481,82 @@ function guardPipeline(pipeline) {
2405
2481
  };
2406
2482
  }
2407
2483
 
2408
- // ../core/src/factory/create-polymorphic.ts
2409
- var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
2410
- function resolveClassPipeline(options, resolved, diagnostics, capabilities) {
2411
- const factory = options.styling?.plugin;
2412
- if (!factory) {
2413
- const createClassPipeline2 = capabilities?.createClassPipeline;
2414
- const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
2415
- return { pluginResult: void 0, classPipeline: classPipeline2 };
2416
- }
2484
+ // ../core/src/factory/create-polymorphic2.ts
2485
+ var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
2486
+ var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
2487
+ var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
2488
+ var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
2489
+ var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
2490
+ function resolveAriaRules(resolved) {
2491
+ return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
2492
+ }
2493
+ var createAriaPipeline = (resolved) => {
2494
+ const rules = resolveAriaRules(resolved);
2495
+ const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
2496
+ return (tag, props) => engine.validate(tag, props);
2497
+ };
2498
+ var memoizedTagPipeline = definePipeline(createTagPipeline);
2499
+ var memoizedPropsPipeline = definePipeline(createPropsPipeline);
2500
+ var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
2501
+ var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(createHtmlChildrenEvaluatorPipeline);
2502
+ var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
2503
+ var memoizedAriaPipeline = definePipeline(createAriaPipeline);
2504
+ function resolveAriaPassthrough(_tag, props) {
2505
+ return { props };
2506
+ }
2507
+ function resolveClassPlugin(factory, resolved, diagnostics) {
2508
+ if (!factory) return { pluginResult: void 0, classPipeline: memoizedClassPipeline(resolved) };
2417
2509
  const pluginResult = factory(resolved, diagnostics);
2418
2510
  assertPluginShape(pluginResult);
2419
- const classPipeline = guardPipeline(pluginResult.pipeline);
2420
- return { pluginResult, classPipeline };
2511
+ return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
2421
2512
  }
2422
- function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
2423
- return {
2424
- resolveTag: makeResolveTag(resolved.defaultTag),
2425
- resolveProps(props) {
2426
- return mergeProps(resolved.defaultProps, props);
2427
- },
2513
+ function createPolymorphic2(options = {}) {
2514
+ const baseResolved = resolveFactoryOptions(options);
2515
+ const anyBaseResolved = baseResolved;
2516
+ const resolved = Object.freeze({
2517
+ ...baseResolved,
2518
+ htmlPropNormalizersFn: memoizedHtmlPropNormalizersPipeline(anyBaseResolved),
2519
+ htmlChildrenEvaluatorFn: memoizedHtmlChildrenEvaluatorPipeline(anyBaseResolved)
2520
+ });
2521
+ const anyResolved = resolved;
2522
+ if (process.env.NODE_ENV !== "production") {
2523
+ validateFactoryOptions(resolved, resolved.diagnostics);
2524
+ }
2525
+ const { pluginResult, classPipeline } = resolveClassPlugin(
2526
+ options.styling?.plugin,
2527
+ anyResolved,
2528
+ resolved.diagnostics
2529
+ );
2530
+ const resolveTag3 = memoizedTagPipeline(anyResolved);
2531
+ const resolveProps = memoizedPropsPipeline(anyResolved);
2532
+ const resolveAriaFn = options.enforcement !== void 0 ? memoizedAriaPipeline(anyResolved) : resolveAriaPassthrough;
2533
+ const methods = {
2534
+ resolveTag: resolveTag3,
2535
+ resolveProps,
2428
2536
  resolveClasses(tag, props, className, recipe) {
2429
2537
  if (process.env.NODE_ENV !== "production") {
2430
- validateRenderProps(renderDiagnostics, resolved, props, recipe);
2538
+ validateRenderProps(resolved.diagnostics, resolved, props, recipe);
2431
2539
  }
2432
2540
  return classPipeline(tag, props, className, recipe);
2433
2541
  },
2434
2542
  resolveAria(tag, props) {
2435
- if (!engine) return { props };
2436
- const result = engine.validate(tag, props);
2437
- return { props: result.props };
2543
+ return resolveAriaFn(tag, props);
2438
2544
  }
2439
2545
  };
2440
- }
2441
- function createRuntimeObject(methods, resolved, pluginResult) {
2442
- return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2443
- }
2444
- function createPolymorphic(options = {}, capabilities) {
2445
- const baseResolved = resolveFactoryOptions(options);
2446
- const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
2447
- ...baseResolved,
2448
- htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
2449
- }) : baseResolved;
2450
- if (process.env.NODE_ENV !== "production") {
2451
- validateFactoryOptions(resolved, resolved.diagnostics);
2452
- }
2453
- const { pluginResult, classPipeline } = resolveClassPipeline(
2454
- options,
2455
- resolved,
2456
- resolved.diagnostics,
2457
- capabilities
2458
- );
2459
- const allAriaRules = [
2460
- .../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
2461
- ];
2462
- const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
2463
- resolved.diagnostics,
2464
- allAriaRules.length ? { rules: allAriaRules } : void 0
2465
- ) : null;
2466
- const methods = createRuntimeMethods(resolved, classPipeline, engine, resolved.diagnostics);
2467
- return createRuntimeObject(
2468
- methods,
2469
- resolved,
2470
- pluginResult
2471
- );
2472
- }
2473
-
2474
- // ../core/src/factory/create-polymorphic-full.ts
2475
- var FULL_CAPABILITIES = {
2476
- createClassPipeline,
2477
- AriaEngine: AriaPolicyEngine,
2478
- htmlAriaRules: HTML_ARIA_RULES,
2479
- htmlPropNormalizersFn: getHtmlPropNormalizers
2480
- };
2481
- function createPolymorphic2(options = {}) {
2482
- return createPolymorphic(options, FULL_CAPABILITIES);
2546
+ const runtimeObject = pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2547
+ return runtimeObject;
2483
2548
  }
2484
2549
 
2485
- // ../../lib/adapter-utils/src/define-component.ts
2486
- function defineContractComponent(options) {
2487
- return (factory) => factory(options);
2550
+ // ../core/src/resolver/resolver.ts
2551
+ import { silentDiagnostics as silentDiagnostics2 } from "../_shared/diagnostics.js";
2552
+ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
2553
+ if (allowedAs.includes(tag)) return;
2554
+ if (!diagnostics) return;
2555
+ const component = displayName ?? String(tag);
2556
+ diagnostics.error(ContractDiagnostics.allowedAsViolation(String(tag), allowedAs, component));
2488
2557
  }
2489
2558
 
2490
- // ../../lib/adapter-utils/src/build-core-runtime.ts
2559
+ // ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
2491
2560
  var EMPTY_SET = /* @__PURE__ */ new Set();
2492
2561
  function buildCoreRuntime(normalized) {
2493
2562
  const runtime = createPolymorphic2(normalized);
@@ -2495,12 +2564,32 @@ function buildCoreRuntime(normalized) {
2495
2564
  return { runtime, ownedKeys };
2496
2565
  }
2497
2566
 
2498
- // ../../lib/adapter-utils/src/build-engines.ts
2567
+ // ../../lib/adapter-utils/src/runtime/build-engines.ts
2499
2568
  function buildEngines(diagnostics, childRules, context) {
2500
2569
  return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
2501
2570
  }
2502
2571
 
2503
- // ../../lib/adapter-utils/src/compose-filter.ts
2572
+ // ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
2573
+ import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
2574
+ function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
2575
+ return {
2576
+ name: options.name ?? defaultName,
2577
+ diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
2578
+ };
2579
+ }
2580
+
2581
+ // ../../lib/adapter-utils/src/props/apply-filter.ts
2582
+ function applyFilter(props, filterProps, variantKeys) {
2583
+ const out = {};
2584
+ iterate.forEachEntry(props, (k) => {
2585
+ if (!Object.hasOwn(props, k)) return;
2586
+ if (filterProps(k, variantKeys)) return;
2587
+ out[k] = props[k];
2588
+ });
2589
+ return out;
2590
+ }
2591
+
2592
+ // ../../lib/adapter-utils/src/props/compose-filter.ts
2504
2593
  function composeFilter(ownedKeys, filterProps) {
2505
2594
  const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
2506
2595
  if (!filterProps) {
@@ -2509,14 +2598,6 @@ function composeFilter(ownedKeys, filterProps) {
2509
2598
  return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
2510
2599
  }
2511
2600
 
2512
- // ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
2513
- function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics) {
2514
- return {
2515
- name: options.name ?? defaultName,
2516
- diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
2517
- };
2518
- }
2519
-
2520
2601
  // ../../adapters/solid/src/slot/slot-validator.ts
2521
2602
  var SlotValidator = class extends InvariantBase {
2522
2603
  #name;
@@ -2593,7 +2674,7 @@ function resolveTag2(runtime, as) {
2593
2674
  return runtime.resolveTag(as);
2594
2675
  }
2595
2676
  function resolveDomProps(tag, elementProps, runtime) {
2596
- return typeof tag === "string" ? runtime.resolveAria(tag, elementProps).props : elementProps;
2677
+ return isString(tag) ? runtime.resolveAria(tag, elementProps).props : elementProps;
2597
2678
  }
2598
2679
  function tryRenderAsChild(known, filteredProps, resolvedClass, slotValidator) {
2599
2680
  if (!known.asChild) return null;
@@ -2634,9 +2715,20 @@ function render({
2634
2715
  const filteredProps = createMemo(
2635
2716
  () => applyFilter(normalizedProps(), filterProps, runtime.options.variantKeys)
2636
2717
  );
2718
+ const { allowedAs } = runtime.options;
2719
+ if (allowedAs !== void 0) {
2720
+ createEffect(
2721
+ () => enforceAllowedAs(tag(), allowedAs, runtime.options.diagnostics, runtime.options.displayName)
2722
+ );
2723
+ }
2637
2724
  if (process.env.NODE_ENV !== "production" && childrenEvaluator) {
2638
2725
  createEffect(() => childrenEvaluator.evaluate(toChildArray(known.children)));
2639
2726
  }
2727
+ if (process.env.NODE_ENV !== "production") {
2728
+ createEffect(
2729
+ () => runtime.options.htmlChildrenEvaluatorFn?.(tag())?.evaluate(toChildArray(known.children))
2730
+ );
2731
+ }
2640
2732
  const slotResult = tryRenderAsChild(known, filteredProps, resolvedClass, slotValidator);
2641
2733
  if (slotResult !== null) return slotResult;
2642
2734
  const domProps = createMemo(() => {