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.
package/dist/lit/index.js CHANGED
@@ -1,11 +1,16 @@
1
- // ../../adapters/lit/src/create-contract-component.ts
2
- import { LitElement, html } from "lit";
1
+ // ../../lib/adapter-utils/src/runtime/define-component.ts
2
+ function defineContractComponent(options) {
3
+ return (factory) => factory(options);
4
+ }
3
5
 
4
- // ../../lib/primitive/src/tag/resolve-tag.ts
5
- function makeResolveTag(defaultTag) {
6
- return function tag(as) {
7
- return as ?? defaultTag;
8
- };
6
+ // ../../lib/primitive/src/guards/foundational/is-defined.ts
7
+ function isUndefined(value) {
8
+ return value === void 0;
9
+ }
10
+
11
+ // ../../lib/primitive/src/guards/foundational/is-null.ts
12
+ function isNull(value) {
13
+ return value === null;
9
14
  }
10
15
 
11
16
  // ../../lib/primitive/src/utils/is-object.ts
@@ -20,195 +25,6 @@ function isNumber(value) {
20
25
  return typeof value === "number";
21
26
  }
22
27
 
23
- // ../../lib/primitive/src/utils/assert-never.ts
24
- function assertNever(value) {
25
- throw new Error(`Unexpected value: ${String(value)}`);
26
- }
27
-
28
- // ../../lib/primitive/src/utils/cn.ts
29
- import { clsx } from "clsx";
30
- function cn(...inputs) {
31
- return clsx(...inputs);
32
- }
33
-
34
- // ../../lib/primitive/src/utils/iterate.ts
35
- function find(iterable, callback) {
36
- for (const value of iterable) {
37
- const result = callback(value);
38
- if (result != null) {
39
- return result;
40
- }
41
- }
42
- return null;
43
- }
44
- function some(iterable, predicate) {
45
- for (const value of iterable) {
46
- if (predicate(value)) return true;
47
- }
48
- return false;
49
- }
50
- function every(iterable, predicate) {
51
- let index = 0;
52
- for (const value of iterable) {
53
- if (!predicate(value, index++)) {
54
- return false;
55
- }
56
- }
57
- return true;
58
- }
59
- function* filter(iterable, predicate) {
60
- let index = 0;
61
- for (const value of iterable) {
62
- if (predicate(value, index++)) {
63
- yield value;
64
- }
65
- }
66
- }
67
- function* map(iterable, callback) {
68
- let index = 0;
69
- for (const value of iterable) {
70
- yield callback(value, index++);
71
- }
72
- }
73
- function forEach(iterable, callback) {
74
- let index = 0;
75
- for (const value of iterable) {
76
- callback(value, index++);
77
- }
78
- }
79
- function reduce(iterable, initial, callback) {
80
- let accumulator = initial;
81
- let index = 0;
82
- for (const value of iterable) {
83
- accumulator = callback(accumulator, value, index++);
84
- }
85
- return accumulator;
86
- }
87
- function collect(iterable, callback) {
88
- const result = {};
89
- let index = 0;
90
- for (const value of iterable) {
91
- const entry = callback(value, index++);
92
- if (entry === null) {
93
- return null;
94
- }
95
- result[entry[0]] = entry[1];
96
- }
97
- return result;
98
- }
99
- function findLast(value, callback) {
100
- for (let index = value.length - 1; index >= 0; index--) {
101
- const result = callback(value[index], index);
102
- if (result != null) {
103
- return result;
104
- }
105
- }
106
- return null;
107
- }
108
- function* items(collection) {
109
- for (let i = 0; i < collection.length; i++) {
110
- const item = collection.item(i);
111
- if (item !== null) {
112
- yield item;
113
- }
114
- }
115
- }
116
- function nodeList(list) {
117
- return {
118
- *[Symbol.iterator]() {
119
- for (let i = 0; i < list.length; i++) {
120
- const node = list.item(i);
121
- if (node !== null) {
122
- yield node;
123
- }
124
- }
125
- }
126
- };
127
- }
128
- function mapEntries(m) {
129
- return m.entries();
130
- }
131
- function set(s) {
132
- return s.values();
133
- }
134
- function hasOwn(object, key) {
135
- return Object.hasOwn(object, key);
136
- }
137
- function* entries(object) {
138
- for (const key in object) {
139
- if (!hasOwn(object, key)) continue;
140
- yield [key, object[key]];
141
- }
142
- }
143
- function* keys(object) {
144
- for (const [key] of entries(object)) {
145
- yield key;
146
- }
147
- }
148
- function* values(object) {
149
- for (const [, value] of entries(object)) {
150
- yield value;
151
- }
152
- }
153
- function mapValues(object, callback) {
154
- const result = {};
155
- for (const [key, value] of entries(object)) {
156
- result[key] = callback(value, key);
157
- }
158
- return result;
159
- }
160
- function forEachEntry(object, callback) {
161
- for (const [key, value] of entries(object)) {
162
- callback(key, value);
163
- }
164
- }
165
- function forEachKey(object, callback) {
166
- for (const key of keys(object)) {
167
- callback(key);
168
- }
169
- }
170
- function forEachValue(object, callback) {
171
- for (const value of values(object)) {
172
- callback(value);
173
- }
174
- }
175
- function forEachSet(s, callback) {
176
- for (const value of s) {
177
- callback(value);
178
- }
179
- }
180
- var iterate = Object.freeze({
181
- entries,
182
- filter,
183
- find,
184
- findLast,
185
- forEach,
186
- forEachEntry,
187
- forEachKey,
188
- forEachSet,
189
- forEachValue,
190
- items,
191
- keys,
192
- map,
193
- mapEntries,
194
- mapValues,
195
- nodeList,
196
- reduce,
197
- collect,
198
- set,
199
- some,
200
- every,
201
- values
202
- });
203
-
204
- // ../../lib/primitive/src/utils/merge-props.ts
205
- function mergeProps(defaultProps, props) {
206
- return {
207
- ...defaultProps ?? {},
208
- ...props
209
- };
210
- }
211
-
212
28
  // ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
213
29
  var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
214
30
  "aria-atomic",
@@ -231,7 +47,7 @@ var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
231
47
  ]);
232
48
 
233
49
  // ../../lib/primitive/src/constants/aria/implicit-role-record.ts
234
- var IMPLICIT_ROLE_RECORD = {
50
+ var IMPLICIT_ROLE_RECORD = Object.freeze({
235
51
  // Landmarks
236
52
  article: "article",
237
53
  aside: "complementary",
@@ -267,8 +83,8 @@ var IMPLICIT_ROLE_RECORD = {
267
83
  meter: "meter",
268
84
  output: "status",
269
85
  progress: "progressbar"
270
- };
271
- var INPUT_TYPE_ROLE_MAP = {
86
+ });
87
+ var INPUT_TYPE_ROLE_MAP = Object.freeze({
272
88
  checkbox: "checkbox",
273
89
  radio: "radio",
274
90
  range: "slider",
@@ -282,15 +98,17 @@ var INPUT_TYPE_ROLE_MAP = {
282
98
  submit: "button",
283
99
  reset: "button",
284
100
  image: "button"
285
- };
286
- var STRONG_ROLES = [
101
+ });
102
+ var STRONG_ROLES = Object.freeze([
287
103
  "main",
288
104
  "navigation",
289
105
  "complementary",
290
106
  "contentinfo",
291
107
  "banner"
292
- ];
293
- var STANDALONE_ROLES = ["article"];
108
+ ]);
109
+ var STANDALONE_ROLES = Object.freeze([
110
+ "article"
111
+ ]);
294
112
  var STRONG_ROLES_SET = new Set(STRONG_ROLES);
295
113
  var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
296
114
 
@@ -445,16 +263,6 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
445
263
  ]
446
264
  ]);
447
265
 
448
- // ../../lib/primitive/src/guards/foundational/is-defined.ts
449
- function isUndefined(value) {
450
- return value === void 0;
451
- }
452
-
453
- // ../../lib/primitive/src/guards/foundational/is-null.ts
454
- function isNull(value) {
455
- return value === null;
456
- }
457
-
458
266
  // ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
459
267
  function isGlobalAriaAttribute(attr) {
460
268
  return GLOBAL_ARIA_ATTRIBUTES.has(attr);
@@ -476,38 +284,259 @@ function isStandaloneTag(tag) {
476
284
  return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
477
285
  }
478
286
  function getInputImplicitRole(type) {
479
- if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
287
+ if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
480
288
  return INPUT_TYPE_ROLE_MAP[type];
481
289
  }
482
290
  function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
483
- const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
291
+ const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
484
292
  if (!isNamed) return void 0;
485
293
  if (tag === "section") return "region";
486
294
  if (tag === "form") return "form";
487
295
  return void 0;
488
296
  }
489
297
 
490
- // ../../lib/adapter-utils/src/apply-filter.ts
491
- function applyFilter(props, filterProps, variantKeys) {
492
- const out = {};
493
- iterate.forEachEntry(props, (k) => {
494
- if (!Object.hasOwn(props, k)) return;
495
- if (filterProps(k, variantKeys)) return;
496
- out[k] = props[k];
497
- });
498
- return out;
298
+ // ../../lib/contract/src/aria/aria-role-policy.ts
299
+ function getImplicitRole(tag, props) {
300
+ if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
301
+ if (tag === "input") return getInputImplicitRole(props?.type);
302
+ if (tag === "img") return props?.alt === "" ? "none" : "img";
303
+ if (tag === "section" || tag === "form") {
304
+ return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
305
+ }
306
+ return void 0;
307
+ }
308
+
309
+ // ../../lib/primitive/src/tag/resolve-tag.ts
310
+ function makeResolveTag(defaultTag) {
311
+ return function tag(as) {
312
+ return as ?? defaultTag;
313
+ };
314
+ }
315
+
316
+ // ../../lib/primitive/src/utils/assert-never.ts
317
+ function assertNever(value) {
318
+ throw new Error(`Unexpected value: ${String(value)}`);
319
+ }
320
+
321
+ // ../../lib/primitive/src/utils/cn.ts
322
+ import { clsx } from "clsx";
323
+ function cn(...inputs) {
324
+ return clsx(...inputs);
325
+ }
326
+
327
+ // ../../lib/primitive/src/utils/iterate.ts
328
+ function find(iterable, callback) {
329
+ for (const value of iterable) {
330
+ const result = callback(value);
331
+ if (result != null) {
332
+ return result;
333
+ }
334
+ }
335
+ return null;
336
+ }
337
+ function some(iterable, predicate) {
338
+ for (const value of iterable) {
339
+ if (predicate(value)) return true;
340
+ }
341
+ return false;
342
+ }
343
+ function every(iterable, predicate) {
344
+ let index = 0;
345
+ for (const value of iterable) {
346
+ if (!predicate(value, index++)) {
347
+ return false;
348
+ }
349
+ }
350
+ return true;
351
+ }
352
+ function* filter(iterable, predicate) {
353
+ let index = 0;
354
+ for (const value of iterable) {
355
+ if (predicate(value, index++)) {
356
+ yield value;
357
+ }
358
+ }
359
+ }
360
+ function* map(iterable, callback) {
361
+ let index = 0;
362
+ for (const value of iterable) {
363
+ yield callback(value, index++);
364
+ }
365
+ }
366
+ function forEach(iterable, callback) {
367
+ let index = 0;
368
+ for (const value of iterable) {
369
+ callback(value, index++);
370
+ }
371
+ }
372
+ function reduce(iterable, initial, callback) {
373
+ let accumulator = initial;
374
+ let index = 0;
375
+ for (const value of iterable) {
376
+ accumulator = callback(accumulator, value, index++);
377
+ }
378
+ return accumulator;
379
+ }
380
+ function collect(iterable, callback) {
381
+ const result = {};
382
+ let index = 0;
383
+ for (const value of iterable) {
384
+ const entry = callback(value, index++);
385
+ if (entry === null) {
386
+ return null;
387
+ }
388
+ result[entry[0]] = entry[1];
389
+ }
390
+ return result;
391
+ }
392
+ function findLast(value, callback) {
393
+ for (let index = value.length - 1; index >= 0; index--) {
394
+ const result = callback(value[index], index);
395
+ if (result != null) {
396
+ return result;
397
+ }
398
+ }
399
+ return null;
400
+ }
401
+ function* items(collection) {
402
+ for (let i = 0; i < collection.length; i++) {
403
+ const item = collection.item(i);
404
+ if (item !== null) {
405
+ yield item;
406
+ }
407
+ }
408
+ }
409
+ function nodeList(list) {
410
+ return {
411
+ *[Symbol.iterator]() {
412
+ for (let i = 0; i < list.length; i++) {
413
+ const node = list.item(i);
414
+ if (node !== null) {
415
+ yield node;
416
+ }
417
+ }
418
+ }
419
+ };
420
+ }
421
+ function mapEntries(m) {
422
+ return m.entries();
423
+ }
424
+ function set(s) {
425
+ return s.values();
426
+ }
427
+ function hasOwn(object, key) {
428
+ return Object.hasOwn(object, key);
429
+ }
430
+ function* entries(object) {
431
+ for (const key in object) {
432
+ if (!hasOwn(object, key)) continue;
433
+ yield [key, object[key]];
434
+ }
435
+ }
436
+ function* keys(object) {
437
+ for (const [key] of entries(object)) {
438
+ yield key;
439
+ }
440
+ }
441
+ function* values(object) {
442
+ for (const [, value] of entries(object)) {
443
+ yield value;
444
+ }
445
+ }
446
+ function mapValues(object, callback) {
447
+ const result = {};
448
+ for (const [key, value] of entries(object)) {
449
+ result[key] = callback(value, key);
450
+ }
451
+ return result;
452
+ }
453
+ function forEachEntry(object, callback) {
454
+ for (const [key, value] of entries(object)) {
455
+ callback(key, value);
456
+ }
457
+ }
458
+ function forEachKey(object, callback) {
459
+ for (const key of keys(object)) {
460
+ callback(key);
461
+ }
462
+ }
463
+ function forEachValue(object, callback) {
464
+ for (const value of values(object)) {
465
+ callback(value);
466
+ }
467
+ }
468
+ function forEachSet(s, callback) {
469
+ for (const value of s) {
470
+ callback(value);
471
+ }
472
+ }
473
+ var iterate = Object.freeze({
474
+ entries,
475
+ filter,
476
+ find,
477
+ findLast,
478
+ forEach,
479
+ forEachEntry,
480
+ forEachKey,
481
+ forEachSet,
482
+ forEachValue,
483
+ items,
484
+ keys,
485
+ map,
486
+ mapEntries,
487
+ mapValues,
488
+ nodeList,
489
+ reduce,
490
+ collect,
491
+ set,
492
+ some,
493
+ every,
494
+ values
495
+ });
496
+
497
+ // ../../lib/primitive/src/utils/merge-props.ts
498
+ function mergeProps(defaultProps, props) {
499
+ return {
500
+ ...defaultProps ?? {},
501
+ ...props
502
+ };
499
503
  }
500
504
 
501
- // ../../lib/contract/src/aria/aria-role-policy.ts
502
- function getImplicitRole(tag, props) {
503
- if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
504
- if (tag === "input") return getInputImplicitRole(props?.type);
505
- if (tag === "img") return props?.alt === "" ? "none" : "img";
506
- if (tag === "section" || tag === "form") {
507
- return getConditionalImplicitRole(tag, props?.["aria-label"], props?.["aria-labelledby"]);
505
+ // ../../lib/primitive/src/guards/children/component-id.ts
506
+ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default-tag");
507
+
508
+ // ../../lib/primitive/src/guards/children/is-tag.ts
509
+ function getAsProp(child) {
510
+ if (!isObject(child) || !("props" in child)) return void 0;
511
+ const props = child.props;
512
+ if (!isObject(props)) return void 0;
513
+ const as = props.as;
514
+ return isString(as) && as !== "" ? as : void 0;
515
+ }
516
+ function getTag(child) {
517
+ if (!isObject(child) || !("type" in child)) return void 0;
518
+ const t = child.type;
519
+ if (isString(t)) return t;
520
+ if (typeof t === "function" || isObject(t)) {
521
+ const defaultTag = t[COMPONENT_DEFAULT_TAG];
522
+ if (!isString(defaultTag)) return void 0;
523
+ return getAsProp(child) ?? defaultTag;
508
524
  }
509
525
  return void 0;
510
526
  }
527
+ function isTag(...args) {
528
+ if (isString(args[0])) {
529
+ const set3 = new Set(args);
530
+ return (child2) => {
531
+ const tag2 = getTag(child2);
532
+ return tag2 !== void 0 && set3.has(tag2);
533
+ };
534
+ }
535
+ const [child, ...tags] = args;
536
+ const set2 = new Set(tags);
537
+ const tag = getTag(child);
538
+ return tag !== void 0 && set2.has(tag);
539
+ }
511
540
 
512
541
  // ../../lib/contract/src/strict/invariant-base.ts
513
542
  var InvariantBase = class {
@@ -531,159 +560,21 @@ var InvariantBase = class {
531
560
  }
532
561
  };
533
562
 
534
- // ../../lib/diagnostics/src/category.ts
535
- var DiagnosticCategory = /* @__PURE__ */ ((DiagnosticCategory2) => {
536
- DiagnosticCategory2[DiagnosticCategory2["Contract"] = 0] = "Contract";
537
- DiagnosticCategory2[DiagnosticCategory2["HTML"] = 1] = "HTML";
538
- DiagnosticCategory2[DiagnosticCategory2["ARIA"] = 2] = "ARIA";
539
- DiagnosticCategory2[DiagnosticCategory2["Composition"] = 3] = "Composition";
540
- DiagnosticCategory2[DiagnosticCategory2["Rendering"] = 4] = "Rendering";
541
- DiagnosticCategory2[DiagnosticCategory2["Accessibility"] = 5] = "Accessibility";
542
- DiagnosticCategory2[DiagnosticCategory2["Performance"] = 6] = "Performance";
543
- DiagnosticCategory2[DiagnosticCategory2["Internal"] = 7] = "Internal";
544
- DiagnosticCategory2[DiagnosticCategory2["Deprecation"] = 8] = "Deprecation";
545
- DiagnosticCategory2[DiagnosticCategory2["Lint"] = 9] = "Lint";
546
- return DiagnosticCategory2;
547
- })(DiagnosticCategory || {});
548
-
549
- // ../../lib/diagnostics/src/error.ts
550
- var PraxisError = class extends Error {
551
- diagnostic;
552
- constructor(diagnostic) {
553
- super(diagnostic.message);
554
- this.name = "PraxisError";
555
- this.diagnostic = diagnostic;
556
- }
557
- };
558
-
559
- // ../../lib/diagnostics/src/severity.ts
560
- var Severity = /* @__PURE__ */ ((Severity2) => {
561
- Severity2[Severity2["Debug"] = 0] = "Debug";
562
- Severity2[Severity2["Info"] = 1] = "Info";
563
- Severity2[Severity2["Warning"] = 2] = "Warning";
564
- Severity2[Severity2["Error"] = 3] = "Error";
565
- Severity2[Severity2["Fatal"] = 4] = "Fatal";
566
- return Severity2;
567
- })(Severity || {});
568
-
569
- // ../../lib/diagnostics/src/policy.ts
570
- var DefaultPolicy = class {
571
- reportThreshold;
572
- throwThreshold;
573
- constructor({
574
- reportThreshold = 1 /* Info */,
575
- throwThreshold = 4 /* Fatal */
576
- } = {}) {
577
- this.reportThreshold = reportThreshold;
578
- this.throwThreshold = throwThreshold;
579
- }
580
- resolve(diagnostic) {
581
- if (diagnostic.severity >= this.throwThreshold) return 2 /* Throw */;
582
- if (diagnostic.severity >= this.reportThreshold) return 1 /* Report */;
583
- return 0 /* Ignore */;
584
- }
585
- };
586
-
587
- // ../../lib/diagnostics/src/diagnostics.ts
588
- var Diagnostics = class {
589
- reporter;
590
- policy;
591
- // Pre-computed at construction time: true if Warning-level diagnostics are not ignored.
592
- active;
593
- constructor(reporter, policy = new DefaultPolicy()) {
594
- this.reporter = reporter;
595
- this.policy = policy;
596
- this.active = policy.resolve({ severity: 2 /* Warning */ }) !== 0 /* Ignore */;
597
- }
598
- report(diagnostic) {
599
- const enforcement = this.policy.resolve(diagnostic);
600
- if (enforcement === 0 /* Ignore */) return diagnostic;
601
- if (enforcement === 2 /* Throw */) throw new PraxisError(diagnostic);
602
- this.reporter.report(diagnostic);
603
- return diagnostic;
604
- }
605
- warn(input) {
606
- return this.report({ ...input, severity: 2 /* Warning */ });
607
- }
608
- error(input) {
609
- return this.report({ ...input, severity: 3 /* Error */ });
610
- }
611
- info(input) {
612
- return this.report({ ...input, severity: 1 /* Info */ });
613
- }
614
- };
615
-
616
- // ../../lib/diagnostics/src/formatter.ts
617
- function formatDiagnostic(diagnostic) {
618
- const level = Severity[diagnostic.severity];
619
- const category = DiagnosticCategory[diagnostic.category];
620
- const prefix = category !== void 0 ? `[${category}] ` : "";
621
- return `${level} ${diagnostic.code}: ${prefix}${diagnostic.message}`;
622
- }
623
-
624
- // ../../lib/diagnostics/src/console-reporter.ts
625
- var ConsoleReporter = class {
626
- report(diagnostic) {
627
- const message = formatDiagnostic(diagnostic);
628
- switch (diagnostic.severity) {
629
- case 0 /* Debug */:
630
- console.debug(message);
631
- break;
632
- case 1 /* Info */:
633
- console.info(message);
634
- break;
635
- case 2 /* Warning */:
636
- console.warn(message);
637
- break;
638
- case 3 /* Error */:
639
- case 4 /* Fatal */:
640
- console.error(message);
641
- break;
642
- }
643
- }
644
- };
645
-
646
- // ../../lib/diagnostics/src/null-reporter.ts
647
- var nullReporter = {
648
- report() {
649
- }
650
- };
651
-
652
- // ../../lib/diagnostics/src/presets.ts
653
- var ignoreAllPolicy = {
654
- resolve(_) {
655
- return 0 /* Ignore */;
656
- }
657
- };
658
- var warnOnlyReporter = {
659
- report(diagnostic) {
660
- console.warn(formatDiagnostic(diagnostic));
661
- }
662
- };
663
- var silentDiagnostics = new Diagnostics(nullReporter, ignoreAllPolicy);
664
- var warnDiagnostics = new Diagnostics(
665
- warnOnlyReporter,
666
- new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 4 /* Fatal */ })
667
- );
668
- var throwDiagnostics = new Diagnostics(
669
- new ConsoleReporter(),
670
- new DefaultPolicy({ reportThreshold: 2 /* Warning */, throwThreshold: 3 /* Error */ })
671
- );
672
-
673
563
  // ../../lib/contract/src/diagnostics/aria.ts
564
+ import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
674
565
  var AriaDiagnostics = {
675
566
  /** Generic bridge for violations produced by external AriaRule functions. */
676
567
  fromViolation(v) {
677
568
  return {
678
- code: "ARIA2002" /* AriaViolation */,
679
- category: 2 /* ARIA */,
569
+ code: DiagnosticCode.AriaViolation,
570
+ category: DiagnosticCategory.ARIA,
680
571
  message: v.message
681
572
  };
682
573
  },
683
574
  attributeInvalid(key, role) {
684
575
  return {
685
- code: "ARIA2003" /* AriaAttributeInvalid */,
686
- category: 2 /* ARIA */,
576
+ code: DiagnosticCode.AriaAttributeInvalid,
577
+ category: DiagnosticCategory.ARIA,
687
578
  message: `"${key}" is not valid on role="${role}". It will be removed.`,
688
579
  rationale: "Invalid ARIA attributes are ignored by assistive technology and may trigger accessibility-tree warnings in browser devtools.",
689
580
  suggestions: [
@@ -696,8 +587,8 @@ var AriaDiagnostics = {
696
587
  },
697
588
  missingLiveRegion(role, impliedLive) {
698
589
  return {
699
- code: "ARIA2004" /* AriaMissingLiveRegion */,
700
- category: 2 /* ARIA */,
590
+ code: DiagnosticCode.AriaMissingLiveRegion,
591
+ category: DiagnosticCategory.ARIA,
701
592
  message: `role="${role}" implies aria-live="${impliedLive}" but it is missing. It has been injected.`,
702
593
  rationale: "Live-region roles announce dynamic content changes to screen readers. Without aria-live the politeness level is unspecified and announcements may be silent.",
703
594
  suggestions: [
@@ -711,8 +602,8 @@ var AriaDiagnostics = {
711
602
  },
712
603
  missingAtomic(role) {
713
604
  return {
714
- code: "ARIA2005" /* AriaMissingAtomic */,
715
- category: 2 /* ARIA */,
605
+ code: DiagnosticCode.AriaMissingAtomic,
606
+ category: DiagnosticCategory.ARIA,
716
607
  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.`,
717
608
  rationale: "aria-atomic controls whether assistive technology announces the entire live region or only the changed nodes. Omitting it leaves the behaviour browser-defined."
718
609
  };
@@ -720,8 +611,8 @@ var AriaDiagnostics = {
720
611
  relevantInvalidTokens(invalid) {
721
612
  const quoted = invalid.map((t) => `"${t}"`).join(", ");
722
613
  return {
723
- code: "ARIA2006" /* AriaRelevantInvalidToken */,
724
- category: 2 /* ARIA */,
614
+ code: DiagnosticCode.AriaRelevantInvalidToken,
615
+ category: DiagnosticCategory.ARIA,
725
616
  message: `aria-relevant contains invalid token(s): ${quoted}. Valid tokens are: additions, removals, text, all.`,
726
617
  rationale: "aria-relevant accepts a space-separated list of change types. Unrecognised tokens are silently ignored by assistive technology, making the attribute ineffective.",
727
618
  suggestions: [
@@ -734,8 +625,8 @@ var AriaDiagnostics = {
734
625
  },
735
626
  relevantSuperseded() {
736
627
  return {
737
- code: "ARIA2007" /* AriaRelevantSuperseded */,
738
- category: 2 /* ARIA */,
628
+ code: DiagnosticCode.AriaRelevantSuperseded,
629
+ category: DiagnosticCategory.ARIA,
739
630
  message: 'aria-relevant includes "all" alongside other tokens. "all" supersedes additions, removals, and text \u2014 use aria-relevant="all" alone.',
740
631
  rationale: '"all" is equivalent to "additions removals text". Combining it with other tokens is redundant and may confuse readers of the markup.',
741
632
  suggestions: [
@@ -748,8 +639,8 @@ var AriaDiagnostics = {
748
639
  },
749
640
  missingAccessibleName(tag) {
750
641
  return {
751
- code: "ARIA2009" /* AriaMissingAccessibleName */,
752
- category: 2 /* ARIA */,
642
+ code: DiagnosticCode.AriaMissingAccessibleName,
643
+ category: DiagnosticCategory.ARIA,
753
644
  message: `<${tag}> has no accessible name. Add aria-label or aria-labelledby.`,
754
645
  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.",
755
646
  suggestions: [
@@ -766,8 +657,8 @@ var AriaDiagnostics = {
766
657
  },
767
658
  attributeOnPresentational(attr, tag) {
768
659
  return {
769
- code: "ARIA2010" /* AriaAttributeOnPresentational */,
770
- category: 2 /* ARIA */,
660
+ code: DiagnosticCode.AriaAttributeOnPresentational,
661
+ category: DiagnosticCategory.ARIA,
771
662
  message: `"${attr}" is not allowed on a presentational <${tag}>. Presentational elements are invisible to assistive technology.`,
772
663
  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.',
773
664
  suggestions: [
@@ -780,8 +671,8 @@ var AriaDiagnostics = {
780
671
  },
781
672
  ariaHiddenOnFocusable(tag) {
782
673
  return {
783
- code: "ARIA2011" /* AriaHiddenOnFocusable */,
784
- category: 2 /* ARIA */,
674
+ code: DiagnosticCode.AriaHiddenOnFocusable,
675
+ category: DiagnosticCategory.ARIA,
785
676
  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.`,
786
677
  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.',
787
678
  suggestions: [
@@ -799,8 +690,8 @@ var AriaDiagnostics = {
799
690
  invalidAttributeValue(attr, value, expected) {
800
691
  const got = value === null ? "null" : value === void 0 ? "undefined" : typeof value === "string" ? `"${value}"` : String(value);
801
692
  return {
802
- code: "ARIA2013" /* AriaInvalidAttributeValue */,
803
- category: 2 /* ARIA */,
693
+ code: DiagnosticCode.AriaInvalidAttributeValue,
694
+ category: DiagnosticCategory.ARIA,
804
695
  message: `"${attr}" has an invalid value (${got}). Expected: ${expected}.`,
805
696
  rationale: "ARIA attributes with invalid values are silently ignored by assistive technology, making the markup semantically inert.",
806
697
  suggestions: [
@@ -813,8 +704,8 @@ var AriaDiagnostics = {
813
704
  },
814
705
  redundantAriaLevel(tag, level) {
815
706
  return {
816
- code: "ARIA2014" /* AriaRedundantLevelAttribute */,
817
- category: 2 /* ARIA */,
707
+ code: DiagnosticCode.AriaRedundantLevelAttribute,
708
+ category: DiagnosticCategory.ARIA,
818
709
  message: `aria-level="${level}" is redundant on <${tag}>: the element already has an implicit heading level of ${level}. Remove the attribute.`,
819
710
  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>).',
820
711
  suggestions: [
@@ -827,8 +718,8 @@ var AriaDiagnostics = {
827
718
  },
828
719
  requiredProperty(attr, role) {
829
720
  return {
830
- code: "ARIA2012" /* AriaRequiredProperty */,
831
- category: 2 /* ARIA */,
721
+ code: DiagnosticCode.AriaRequiredProperty,
722
+ category: DiagnosticCategory.ARIA,
832
723
  message: `"${attr}" is required for role="${role}" but is missing.`,
833
724
  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.`,
834
725
  suggestions: [
@@ -841,8 +732,8 @@ var AriaDiagnostics = {
841
732
  },
842
733
  invalidRole(role, tag) {
843
734
  return {
844
- code: "ARIA2008" /* AriaInvalidRole */,
845
- category: 2 /* ARIA */,
735
+ code: DiagnosticCode.AriaInvalidRole,
736
+ category: DiagnosticCategory.ARIA,
846
737
  message: `Invalid role "${role ?? ""}" on <${tag}>.`,
847
738
  rationale: "An unrecognised or misapplied ARIA role is ignored by assistive technology and may degrade the accessibility of the element."
848
739
  };
@@ -850,11 +741,12 @@ var AriaDiagnostics = {
850
741
  };
851
742
 
852
743
  // ../../lib/contract/src/diagnostics/contract.ts
744
+ import { DiagnosticCategory as DiagnosticCategory2, DiagnosticCode as DiagnosticCode2 } from "../_shared/diagnostics.js";
853
745
  var ContractDiagnostics = {
854
746
  unexpectedChild(typeName, index, context) {
855
747
  return {
856
- code: "COMP1004" /* UnexpectedChild */,
857
- category: 0 /* Contract */,
748
+ code: DiagnosticCode2.UnexpectedChild,
749
+ category: DiagnosticCategory2.Contract,
858
750
  component: context,
859
751
  message: `${context}: unexpected child "${typeName}" at index ${index}.`
860
752
  };
@@ -862,69 +754,69 @@ var ContractDiagnostics = {
862
754
  ambiguousChild(typeName, index, ruleNames, context) {
863
755
  const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
864
756
  return {
865
- code: "COMP1005" /* AmbiguousChild */,
866
- category: 0 /* Contract */,
757
+ code: DiagnosticCode2.AmbiguousChild,
758
+ category: DiagnosticCategory2.Contract,
867
759
  component: context,
868
760
  message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
869
761
  };
870
762
  },
871
763
  cardinalityMin(ruleName, min, context) {
872
764
  return {
873
- code: "COMP1006" /* CardinalityMin */,
874
- category: 0 /* Contract */,
765
+ code: DiagnosticCode2.CardinalityMin,
766
+ category: DiagnosticCategory2.Contract,
875
767
  component: context,
876
768
  message: `${context}: "${ruleName}" requires at least ${min}.`
877
769
  };
878
770
  },
879
771
  cardinalityMax(ruleName, max, context) {
880
772
  return {
881
- code: "COMP1007" /* CardinalityMax */,
882
- category: 0 /* Contract */,
773
+ code: DiagnosticCode2.CardinalityMax,
774
+ category: DiagnosticCategory2.Contract,
883
775
  component: context,
884
776
  message: `${context}: "${ruleName}" allows at most ${max}.`
885
777
  };
886
778
  },
887
779
  positionViolation(ruleName, position, index, context) {
888
780
  return {
889
- code: "COMP1008" /* PositionViolation */,
890
- category: 0 /* Contract */,
781
+ code: DiagnosticCode2.PositionViolation,
782
+ category: DiagnosticCategory2.Contract,
891
783
  component: context,
892
784
  message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
893
785
  };
894
786
  },
895
787
  unknownVariantDim(component, label2, dim) {
896
788
  return {
897
- code: "COMP1010" /* ContractUnknownVariantDim */,
898
- category: 0 /* Contract */,
789
+ code: DiagnosticCode2.ContractUnknownVariantDim,
790
+ category: DiagnosticCategory2.Contract,
899
791
  message: `${component}: ${label2} references unknown variant "${dim}".`
900
792
  };
901
793
  },
902
794
  unknownVariantValue(component, label2, dim, value, valid) {
903
795
  return {
904
- code: "COMP1011" /* ContractUnknownVariantValue */,
905
- category: 0 /* Contract */,
796
+ code: DiagnosticCode2.ContractUnknownVariantValue,
797
+ category: DiagnosticCategory2.Contract,
906
798
  message: `${component}: ${label2} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
907
799
  };
908
800
  },
909
801
  unknownRecipeKey(component, key) {
910
802
  return {
911
- code: "COMP1012" /* ContractUnknownRecipeKey */,
912
- category: 0 /* Contract */,
803
+ code: DiagnosticCode2.ContractUnknownRecipeKey,
804
+ category: DiagnosticCategory2.Contract,
913
805
  message: `${component} Unknown recipeKey "${key}" \u2014 no preset with that name exists.`
914
806
  };
915
807
  },
916
808
  invalidVariantValue(component, key, value) {
917
809
  return {
918
- code: "COMP1013" /* ContractInvalidVariantValue */,
919
- category: 0 /* Contract */,
810
+ code: DiagnosticCode2.ContractInvalidVariantValue,
811
+ category: DiagnosticCategory2.Contract,
920
812
  message: `${component} Variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
921
813
  };
922
814
  },
923
815
  allowedAsViolation(tag, allowedAs, component) {
924
816
  const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
925
817
  return {
926
- code: "COMP1009" /* AllowedAsViolation */,
927
- category: 0 /* Contract */,
818
+ code: DiagnosticCode2.AllowedAsViolation,
819
+ category: DiagnosticCategory2.Contract,
928
820
  component,
929
821
  message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
930
822
  };
@@ -932,46 +824,47 @@ var ContractDiagnostics = {
932
824
  };
933
825
 
934
826
  // ../../lib/contract/src/diagnostics/html.ts
827
+ import { DiagnosticCategory as DiagnosticCategory3, DiagnosticCode as DiagnosticCode3 } from "../_shared/diagnostics.js";
935
828
  var HtmlDiagnostics = {
936
829
  emptyRole(tag) {
937
830
  return {
938
- code: "HTML3002" /* HtmlEmptyRole */,
939
- category: 1 /* HTML */,
831
+ code: DiagnosticCode3.HtmlEmptyRole,
832
+ category: DiagnosticCategory3.HTML,
940
833
  message: `<${tag}> has an explicit empty role="". Omit the attribute instead.`
941
834
  };
942
835
  },
943
836
  implicitRoleRedundant(tag, implicitRole) {
944
837
  return {
945
- code: "HTML3003" /* HtmlImplicitRoleRedundant */,
946
- category: 1 /* HTML */,
838
+ code: DiagnosticCode3.HtmlImplicitRoleRedundant,
839
+ category: DiagnosticCategory3.HTML,
947
840
  message: `<${tag}> already has implicit role="${implicitRole}". Avoid redundant role assignment.`
948
841
  };
949
842
  },
950
843
  implicitRoleOverride(tag, implicitRole, role) {
951
844
  return {
952
- code: "HTML3004" /* HtmlImplicitRoleOverride */,
953
- category: 1 /* HTML */,
845
+ code: DiagnosticCode3.HtmlImplicitRoleOverride,
846
+ category: DiagnosticCategory3.HTML,
954
847
  message: `<${tag}> should not override its implicit role="${implicitRole}" with role="${role}".`
955
848
  };
956
849
  },
957
850
  standaloneRegionOverride(tag, implicitRole) {
958
851
  return {
959
- code: "HTML3005" /* HtmlStandaloneRegionOverride */,
960
- category: 1 /* HTML */,
852
+ code: DiagnosticCode3.HtmlStandaloneRegionOverride,
853
+ category: DiagnosticCategory3.HTML,
961
854
  message: `<${tag}> is a self-contained element with implicit role="${implicitRole}". Assigning role="region" has been removed.`
962
855
  };
963
856
  },
964
857
  landmarkRoleOverride(tag, implicitRole, role) {
965
858
  return {
966
- code: "HTML3006" /* HtmlLandmarkRoleOverride */,
967
- category: 1 /* HTML */,
859
+ code: DiagnosticCode3.HtmlLandmarkRoleOverride,
860
+ category: DiagnosticCategory3.HTML,
968
861
  message: `<${tag}> has a fixed landmark role="${implicitRole}". role="${role}" overrides it and confuses assistive technology. The override has been removed.`
969
862
  };
970
863
  },
971
864
  invalidChild(child, parent, allowed) {
972
865
  return {
973
- code: "HTML3007" /* HtmlInvalidChild */,
974
- category: 1 /* HTML */,
866
+ code: DiagnosticCode3.HtmlInvalidChild,
867
+ category: DiagnosticCategory3.HTML,
975
868
  message: `<${child}> is not a valid direct child of <${parent}>. Allowed: ${allowed}.`
976
869
  };
977
870
  }
@@ -1654,7 +1547,7 @@ function getTypeName(value) {
1654
1547
  return primitive;
1655
1548
  }
1656
1549
  const name = value.constructor?.name;
1657
- return typeof name === "string" && name !== "Object" ? name : "object";
1550
+ return isString(name) && name !== "Object" ? name : "object";
1658
1551
  }
1659
1552
 
1660
1553
  // ../../lib/contract/src/children/normalize-child-rule.ts
@@ -1905,6 +1798,9 @@ var readonlyProps = ({
1905
1798
  };
1906
1799
  };
1907
1800
 
1801
+ // ../core/src/html/evaluators.ts
1802
+ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
1803
+
1908
1804
  // ../core/src/html/aria-rules.ts
1909
1805
  var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
1910
1806
  var removeLandmarkRoleOverride = {
@@ -1947,6 +1843,167 @@ function landmarkNameAdvisory(ctx) {
1947
1843
  }
1948
1844
  var HTML_ARIA_RULES = [landmarkRoleRule, landmarkNameAdvisory];
1949
1845
 
1846
+ // ../core/src/html/contracts.ts
1847
+ import { warnDiagnostics } from "../_shared/diagnostics.js";
1848
+ function isOpenContent(...blockedTags) {
1849
+ const set2 = new Set(blockedTags);
1850
+ return (child) => isObject(child) && "type" in child && (!isString(child.type) || !set2.has(child.type));
1851
+ }
1852
+ var METADATA_TAGS = ["script", "template"];
1853
+ var metadataMatch = isTag(...METADATA_TAGS);
1854
+ function metadata(name = "metadata") {
1855
+ return { name, match: metadataMatch };
1856
+ }
1857
+ function firstOptional(name, tag) {
1858
+ return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
1859
+ }
1860
+ function contract(children) {
1861
+ return { diagnostics: warnDiagnostics, children };
1862
+ }
1863
+ function ariaContract(aria) {
1864
+ return { diagnostics: warnDiagnostics, aria };
1865
+ }
1866
+ function firstChildContract(name, tag) {
1867
+ return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
1868
+ }
1869
+ var VOID_TAGS = [
1870
+ "area",
1871
+ "base",
1872
+ "br",
1873
+ "col",
1874
+ "embed",
1875
+ "hr",
1876
+ "img",
1877
+ "input",
1878
+ "link",
1879
+ "meta",
1880
+ "param",
1881
+ "source",
1882
+ "track",
1883
+ "wbr"
1884
+ ];
1885
+ var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
1886
+ var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
1887
+ var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
1888
+ var tableContract = contract([
1889
+ firstOptional("caption", "caption"),
1890
+ { name: "colgroup", match: isTag("colgroup") },
1891
+ { name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
1892
+ { name: "tbody", match: isTag("tbody") },
1893
+ { name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
1894
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
1895
+ ]);
1896
+ var tableBodyContract = contract([
1897
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
1898
+ ]);
1899
+ var tableRowContract = contract([
1900
+ { name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
1901
+ ]);
1902
+ var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
1903
+ var dlContract = contract([
1904
+ { name: "term", match: isTag("dt") },
1905
+ { name: "description", match: isTag("dd") },
1906
+ { name: "group", match: isTag("div") },
1907
+ metadata()
1908
+ ]);
1909
+ var selectContract = contract([
1910
+ { name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
1911
+ ]);
1912
+ var optgroupContract = contract([
1913
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
1914
+ ]);
1915
+ var datalistContract = contract([
1916
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
1917
+ ]);
1918
+ var pictureContract = contract([
1919
+ { name: "source", match: isTag("source", ...METADATA_TAGS) },
1920
+ { name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
1921
+ ]);
1922
+ var figureContract = contract([
1923
+ { name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
1924
+ { name: "content", match: isOpenContent("figcaption") }
1925
+ ]);
1926
+ var detailsContract = firstChildContract("summary", "summary");
1927
+ var fieldsetContract = firstChildContract("legend", "legend");
1928
+ var mediaContract = contract([
1929
+ { name: "source", match: isTag("source") },
1930
+ { name: "track", match: isTag("track") },
1931
+ metadata(),
1932
+ { name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
1933
+ ]);
1934
+ var headContract = contract([
1935
+ {
1936
+ name: "metadata",
1937
+ match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
1938
+ }
1939
+ ]);
1940
+ var htmlContract = contract([
1941
+ { name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
1942
+ { name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
1943
+ ]);
1944
+ var voidContract = contract([]);
1945
+ var textOnlyContract = contract([
1946
+ {
1947
+ name: "text",
1948
+ match: (child) => isString(child) || isNumber(child)
1949
+ }
1950
+ ]);
1951
+ var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
1952
+ var dialogContract = ariaContract([requireAccessibleName]);
1953
+ var menuContract = ariaContract([requireAccessibleName]);
1954
+ var menubarContract = ariaContract([requireAccessibleName]);
1955
+ var treeContract = ariaContract([requireAccessibleName]);
1956
+ var gridContract = ariaContract([requireAccessibleName]);
1957
+ var listboxContract = ariaContract([requireAccessibleName]);
1958
+ var tablistContract = ariaContract([requireAccessibleName]);
1959
+ var radiogroupContract = ariaContract([requireAccessibleName]);
1960
+ var CONTRACT_GROUPS = [
1961
+ [VOID_TAGS, voidContract],
1962
+ [TEXT_ONLY_TAGS, textOnlyContract],
1963
+ [LANDMARK_TAGS, landmarkContract],
1964
+ [["ul", "ol", "menu"], listContract],
1965
+ [["audio", "video"], mediaContract],
1966
+ [["thead", "tbody", "tfoot"], tableBodyContract]
1967
+ ];
1968
+ function contractMap(groups) {
1969
+ return Object.fromEntries(
1970
+ groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
1971
+ );
1972
+ }
1973
+ var htmlContracts = {
1974
+ ...contractMap(CONTRACT_GROUPS),
1975
+ table: tableContract,
1976
+ tr: tableRowContract,
1977
+ colgroup: colgroupContract,
1978
+ dl: dlContract,
1979
+ select: selectContract,
1980
+ optgroup: optgroupContract,
1981
+ datalist: datalistContract,
1982
+ picture: pictureContract,
1983
+ figure: figureContract,
1984
+ details: detailsContract,
1985
+ fieldset: fieldsetContract,
1986
+ dialog: dialogContract,
1987
+ head: headContract,
1988
+ html: htmlContract
1989
+ };
1990
+
1991
+ // ../core/src/html/evaluators.ts
1992
+ var htmlDiagnostics = warnDiagnostics2;
1993
+ function buildEvaluatorMap() {
1994
+ const map2 = /* @__PURE__ */ new Map();
1995
+ iterate.forEachEntry(htmlContracts, (tag, { children }) => {
1996
+ if (children?.length) {
1997
+ map2.set(tag, new ChildrenEvaluator(children, htmlDiagnostics, `<${tag}>`));
1998
+ }
1999
+ });
2000
+ return map2;
2001
+ }
2002
+ var HTML_EVALUATORS = buildEvaluatorMap();
2003
+ function getHtmlChildrenEvaluator(tag) {
2004
+ return typeof tag === "string" ? HTML_EVALUATORS.get(tag) : void 0;
2005
+ }
2006
+
1950
2007
  // ../core/src/html/prop-normalizers.ts
1951
2008
  var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
1952
2009
  ["button", [disabledProps]],
@@ -2134,7 +2191,21 @@ function createClassPipeline(resolved) {
2134
2191
  };
2135
2192
  }
2136
2193
 
2194
+ // ../../lib/pipeline-kit/src/factory/define-pipeline.ts
2195
+ function definePipeline(factory) {
2196
+ const cache = /* @__PURE__ */ new WeakMap();
2197
+ return (resolved) => {
2198
+ let pipeline = cache.get(resolved);
2199
+ if (!pipeline) {
2200
+ pipeline = factory(resolved);
2201
+ cache.set(resolved, pipeline);
2202
+ }
2203
+ return pipeline;
2204
+ };
2205
+ }
2206
+
2137
2207
  // ../core/src/options/resolve-factory-options.ts
2208
+ import { silentDiagnostics } from "../_shared/diagnostics.js";
2138
2209
  var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
2139
2210
  function composeNormalizers(normalizers, fn) {
2140
2211
  if (!normalizers?.length) return fn;
@@ -2226,21 +2297,25 @@ function validateRenderProps(diagnostics, options, props, recipeKey) {
2226
2297
  }
2227
2298
  }
2228
2299
 
2300
+ // ../core/src/factory/plugin-invariants.ts
2301
+ import { throwDiagnostics } from "../_shared/diagnostics.js";
2302
+
2229
2303
  // ../core/src/factory/plugin-diagnostics.ts
2304
+ import { DiagnosticCategory as DiagnosticCategory4, DiagnosticCode as DiagnosticCode4 } from "../_shared/diagnostics.js";
2230
2305
  var PluginDiagnostics = {
2231
2306
  invalidShape(received) {
2232
2307
  const got = received === null ? "null" : typeof received;
2233
2308
  return {
2234
- code: "PLUGIN7001" /* PluginInvalidShape */,
2235
- category: 7 /* Internal */,
2309
+ code: DiagnosticCode4.PluginInvalidShape,
2310
+ category: DiagnosticCategory4.Internal,
2236
2311
  message: `[praxis-kit] Plugin factory must return an object with a 'pipeline' function. Got: ${got}.`
2237
2312
  };
2238
2313
  },
2239
2314
  pipelineReturnType(received) {
2240
2315
  const got = received === null ? "null" : Array.isArray(received) ? "array" : typeof received;
2241
2316
  return {
2242
- code: "PLUGIN7002" /* PluginPipelineReturnType */,
2243
- category: 7 /* Internal */,
2317
+ code: DiagnosticCode4.PluginPipelineReturnType,
2318
+ category: DiagnosticCategory4.Internal,
2244
2319
  message: `[praxis-kit] Plugin pipeline must return a string. Got: ${got}.`
2245
2320
  };
2246
2321
  }
@@ -2264,89 +2339,82 @@ function guardPipeline(pipeline) {
2264
2339
  };
2265
2340
  }
2266
2341
 
2267
- // ../core/src/factory/create-polymorphic.ts
2268
- var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
2269
- function resolveClassPipeline(options, resolved, diagnostics, capabilities) {
2270
- const factory = options.styling?.plugin;
2271
- if (!factory) {
2272
- const createClassPipeline2 = capabilities?.createClassPipeline;
2273
- const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
2274
- return { pluginResult: void 0, classPipeline: classPipeline2 };
2275
- }
2342
+ // ../core/src/factory/create-polymorphic2.ts
2343
+ var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
2344
+ var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
2345
+ var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
2346
+ var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
2347
+ var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
2348
+ function resolveAriaRules(resolved) {
2349
+ return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
2350
+ }
2351
+ var createAriaPipeline = (resolved) => {
2352
+ const rules = resolveAriaRules(resolved);
2353
+ const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
2354
+ return (tag, props) => engine.validate(tag, props);
2355
+ };
2356
+ var memoizedTagPipeline = definePipeline(createTagPipeline);
2357
+ var memoizedPropsPipeline = definePipeline(createPropsPipeline);
2358
+ var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
2359
+ var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(createHtmlChildrenEvaluatorPipeline);
2360
+ var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
2361
+ var memoizedAriaPipeline = definePipeline(createAriaPipeline);
2362
+ function resolveAriaPassthrough(_tag, props) {
2363
+ return { props };
2364
+ }
2365
+ function resolveClassPlugin(factory, resolved, diagnostics) {
2366
+ if (!factory) return { pluginResult: void 0, classPipeline: memoizedClassPipeline(resolved) };
2276
2367
  const pluginResult = factory(resolved, diagnostics);
2277
2368
  assertPluginShape(pluginResult);
2278
- const classPipeline = guardPipeline(pluginResult.pipeline);
2279
- return { pluginResult, classPipeline };
2369
+ return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
2280
2370
  }
2281
- function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
2282
- return {
2283
- resolveTag: makeResolveTag(resolved.defaultTag),
2284
- resolveProps(props) {
2285
- return mergeProps(resolved.defaultProps, props);
2286
- },
2371
+ function createPolymorphic2(options = {}) {
2372
+ const baseResolved = resolveFactoryOptions(options);
2373
+ const anyBaseResolved = baseResolved;
2374
+ const resolved = Object.freeze({
2375
+ ...baseResolved,
2376
+ htmlPropNormalizersFn: memoizedHtmlPropNormalizersPipeline(anyBaseResolved),
2377
+ htmlChildrenEvaluatorFn: memoizedHtmlChildrenEvaluatorPipeline(anyBaseResolved)
2378
+ });
2379
+ const anyResolved = resolved;
2380
+ if (process.env.NODE_ENV !== "production") {
2381
+ validateFactoryOptions(resolved, resolved.diagnostics);
2382
+ }
2383
+ const { pluginResult, classPipeline } = resolveClassPlugin(
2384
+ options.styling?.plugin,
2385
+ anyResolved,
2386
+ resolved.diagnostics
2387
+ );
2388
+ const resolveTag2 = memoizedTagPipeline(anyResolved);
2389
+ const resolveProps = memoizedPropsPipeline(anyResolved);
2390
+ const resolveAriaFn = options.enforcement !== void 0 ? memoizedAriaPipeline(anyResolved) : resolveAriaPassthrough;
2391
+ const methods = {
2392
+ resolveTag: resolveTag2,
2393
+ resolveProps,
2287
2394
  resolveClasses(tag, props, className, recipe) {
2288
2395
  if (process.env.NODE_ENV !== "production") {
2289
- validateRenderProps(renderDiagnostics, resolved, props, recipe);
2396
+ validateRenderProps(resolved.diagnostics, resolved, props, recipe);
2290
2397
  }
2291
2398
  return classPipeline(tag, props, className, recipe);
2292
2399
  },
2293
2400
  resolveAria(tag, props) {
2294
- if (!engine) return { props };
2295
- const result = engine.validate(tag, props);
2296
- return { props: result.props };
2401
+ return resolveAriaFn(tag, props);
2297
2402
  }
2298
2403
  };
2299
- }
2300
- function createRuntimeObject(methods, resolved, pluginResult) {
2301
- return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2302
- }
2303
- function createPolymorphic(options = {}, capabilities) {
2304
- const baseResolved = resolveFactoryOptions(options);
2305
- const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
2306
- ...baseResolved,
2307
- htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
2308
- }) : baseResolved;
2309
- if (process.env.NODE_ENV !== "production") {
2310
- validateFactoryOptions(resolved, resolved.diagnostics);
2311
- }
2312
- const { pluginResult, classPipeline } = resolveClassPipeline(
2313
- options,
2314
- resolved,
2315
- resolved.diagnostics,
2316
- capabilities
2317
- );
2318
- const allAriaRules = [
2319
- .../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
2320
- ];
2321
- const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
2322
- resolved.diagnostics,
2323
- allAriaRules.length ? { rules: allAriaRules } : void 0
2324
- ) : null;
2325
- const methods = createRuntimeMethods(resolved, classPipeline, engine, resolved.diagnostics);
2326
- return createRuntimeObject(
2327
- methods,
2328
- resolved,
2329
- pluginResult
2330
- );
2331
- }
2332
-
2333
- // ../core/src/factory/create-polymorphic-full.ts
2334
- var FULL_CAPABILITIES = {
2335
- createClassPipeline,
2336
- AriaEngine: AriaPolicyEngine,
2337
- htmlAriaRules: HTML_ARIA_RULES,
2338
- htmlPropNormalizersFn: getHtmlPropNormalizers
2339
- };
2340
- function createPolymorphic2(options = {}) {
2341
- return createPolymorphic(options, FULL_CAPABILITIES);
2404
+ const runtimeObject = pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2405
+ return runtimeObject;
2342
2406
  }
2343
2407
 
2344
- // ../../lib/adapter-utils/src/define-component.ts
2345
- function defineContractComponent(options) {
2346
- return (factory) => factory(options);
2408
+ // ../core/src/resolver/resolver.ts
2409
+ import { silentDiagnostics as silentDiagnostics2 } from "../_shared/diagnostics.js";
2410
+ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
2411
+ if (allowedAs.includes(tag)) return;
2412
+ if (!diagnostics) return;
2413
+ const component = displayName ?? String(tag);
2414
+ diagnostics.error(ContractDiagnostics.allowedAsViolation(String(tag), allowedAs, component));
2347
2415
  }
2348
2416
 
2349
- // ../../lib/adapter-utils/src/build-core-runtime.ts
2417
+ // ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
2350
2418
  var EMPTY_SET = /* @__PURE__ */ new Set();
2351
2419
  function buildCoreRuntime(normalized) {
2352
2420
  const runtime = createPolymorphic2(normalized);
@@ -2354,57 +2422,41 @@ function buildCoreRuntime(normalized) {
2354
2422
  return { runtime, ownedKeys };
2355
2423
  }
2356
2424
 
2357
- // ../../lib/adapter-utils/src/build-engines.ts
2425
+ // ../../lib/adapter-utils/src/runtime/build-engines.ts
2358
2426
  function buildEngines(diagnostics, childRules, context) {
2359
2427
  return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
2360
2428
  }
2361
2429
 
2362
- // ../../lib/adapter-utils/src/compose-filter.ts
2363
- function composeFilter(ownedKeys, filterProps) {
2364
- const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
2365
- if (!filterProps) {
2366
- return defaultFilter;
2367
- }
2368
- return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
2369
- }
2370
-
2371
- // ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
2372
- function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics) {
2430
+ // ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
2431
+ import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
2432
+ function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
2373
2433
  return {
2374
2434
  name: options.name ?? defaultName,
2375
2435
  diagnostics: options.enforcement?.diagnostics ?? defaultDiagnostics
2376
2436
  };
2377
2437
  }
2378
2438
 
2379
- // ../../adapters/lit/src/build-runtime.ts
2380
- function normalizeOptions(options) {
2381
- return {
2382
- ...options,
2383
- ...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics)
2384
- };
2385
- }
2386
- function buildRuntime(options) {
2387
- const { filterProps: customFilter, enforcement } = options;
2388
- const normalized = normalizeOptions(options);
2389
- const { runtime, ownedKeys } = buildCoreRuntime(normalized);
2390
- const { childrenEvaluator } = buildEngines(
2391
- normalized.diagnostics,
2392
- enforcement?.children,
2393
- normalized.name
2394
- );
2395
- const filterProps = composeFilter(ownedKeys, customFilter);
2396
- return {
2397
- runtime,
2398
- filterProps,
2399
- ...childrenEvaluator !== void 0 && { childrenEvaluator }
2400
- };
2439
+ // ../../lib/adapter-utils/src/props/apply-filter.ts
2440
+ function applyFilter(props, filterProps, variantKeys) {
2441
+ const out = {};
2442
+ iterate.forEachEntry(props, (k) => {
2443
+ if (!Object.hasOwn(props, k)) return;
2444
+ if (filterProps(k, variantKeys)) return;
2445
+ out[k] = props[k];
2446
+ });
2447
+ return out;
2401
2448
  }
2402
2449
 
2403
- // ../../adapters/lit/src/render-to-string.ts
2404
- var ssrRegistry = /* @__PURE__ */ new WeakMap();
2405
- function registerForSsr(cls, bundle) {
2406
- ssrRegistry.set(cls, { bundle });
2450
+ // ../../lib/adapter-utils/src/props/compose-filter.ts
2451
+ function composeFilter(ownedKeys, filterProps) {
2452
+ const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
2453
+ if (!filterProps) {
2454
+ return defaultFilter;
2455
+ }
2456
+ return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
2407
2457
  }
2458
+
2459
+ // ../../lib/adapter-utils/src/render/render-to-string.ts
2408
2460
  function escapeAttr(value) {
2409
2461
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2410
2462
  }
@@ -2418,51 +2470,51 @@ function buildAttrString(attributes) {
2418
2470
  parts.push(`${key}="${escapeAttr(String(value))}"`);
2419
2471
  }
2420
2472
  });
2421
- return parts.length > 0 ? " " + parts.join(" ") : "";
2473
+ return parts.length > 0 ? ` ${parts.join(" ")}` : "";
2422
2474
  }
2423
- function renderToString(component, props = {}, innerHTML = "") {
2424
- const entry = ssrRegistry.get(component);
2425
- if (!entry) {
2426
- const name = component.name ?? "AnonymousComponent";
2427
- throw new Error(
2428
- `[renderToString] ${name} was not registered for SSR. Ensure it was created with createContractComponent from @praxis-kit/lit.`
2429
- );
2430
- }
2431
- const { bundle } = entry;
2475
+ function renderBundleToString(bundle, props = {}, innerHTML = "") {
2476
+ const {
2477
+ filterProps,
2478
+ runtime: { options, resolveAria, resolveClasses, resolveProps, resolveTag: resolveTag2 }
2479
+ } = bundle;
2432
2480
  const { as, className, recipe, class: classAttr, ...rest } = props;
2433
- const tag = bundle.runtime.resolveTag(as);
2434
- const mergedProps = bundle.runtime.resolveProps(rest);
2435
- const resolvedClass = bundle.runtime.resolveClasses(
2481
+ const tag = resolveTag2(as);
2482
+ if (options.allowedAs !== void 0) {
2483
+ enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
2484
+ }
2485
+ const mergedProps = resolveProps(rest);
2486
+ const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
2487
+ const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
2488
+ const finalProps = { ...normalizedProps };
2489
+ if (htmlNormalizers) {
2490
+ for (const normalize of htmlNormalizers) {
2491
+ Object.assign(finalProps, normalize(finalProps));
2492
+ }
2493
+ }
2494
+ const resolvedClass = resolveClasses(
2436
2495
  tag,
2437
- mergedProps,
2496
+ finalProps,
2438
2497
  // Accept both React-style className and HTML-native class
2439
2498
  className ?? classAttr,
2440
2499
  recipe
2441
2500
  );
2442
- const ariaResult = bundle.runtime.resolveAria(tag, mergedProps);
2443
- const filtered = applyFilter(
2444
- ariaResult.props,
2445
- bundle.filterProps,
2446
- bundle.runtime.options.variantKeys
2447
- );
2501
+ const ariaResult = resolveAria(tag, finalProps);
2502
+ const filtered = applyFilter(ariaResult.props, filterProps, options.variantKeys);
2448
2503
  const attrs = { ...filtered, class: resolvedClass || void 0 };
2449
2504
  const attrStr = buildAttrString(attrs);
2450
2505
  return `<${tag}${attrStr}>${innerHTML}</${tag}>`;
2451
2506
  }
2452
2507
 
2453
- // ../../adapters/lit/src/create-contract-component.ts
2454
- function isObject2(value) {
2455
- return typeof value === "object" && value !== null;
2456
- }
2508
+ // ../../lib/adapter-utils/src/render/host-state.ts
2457
2509
  function isLooseBundle(arg) {
2458
- if (!isObject2(arg)) return false;
2510
+ if (!isObject(arg)) return false;
2459
2511
  const { runtime, filterProps, childrenEvaluator } = arg;
2460
- if (!isObject2(runtime)) return false;
2461
- if (!isObject2(runtime["options"])) return false;
2512
+ if (!isObject(runtime)) return false;
2513
+ if (!isObject(runtime["options"])) return false;
2462
2514
  if (typeof runtime["resolveTag"] !== "function" || typeof runtime["resolveProps"] !== "function" || typeof runtime["resolveClasses"] !== "function" || typeof runtime["resolveAria"] !== "function")
2463
2515
  return false;
2464
2516
  if (typeof filterProps !== "function") return false;
2465
- if (childrenEvaluator !== void 0 && (!isObject2(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2517
+ if (childrenEvaluator !== void 0 && (!isObject(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2466
2518
  return false;
2467
2519
  return true;
2468
2520
  }
@@ -2474,41 +2526,46 @@ function toLooseBundle(bundle) {
2474
2526
  }
2475
2527
  function resolveHostState(bundle, props) {
2476
2528
  const { as, className, recipe, ...rest } = props;
2477
- const tag = bundle.runtime.resolveTag(as);
2478
- const mergedProps = bundle.runtime.resolveProps(rest);
2479
- const baseProps = bundle.runtime.options.normalizeFn ? bundle.runtime.options.normalizeFn(mergedProps) : mergedProps;
2480
- const htmlNormalizers = bundle.runtime.options.htmlPropNormalizersFn?.(tag);
2481
- const normalizedProps = htmlNormalizers?.length ? htmlNormalizers.reduce((acc, fn) => ({ ...acc, ...fn(acc) }), baseProps) : baseProps;
2482
- const resolvedClass = bundle.runtime.resolveClasses(
2529
+ const { options, resolveAria, resolveClasses, resolveProps, resolveTag: resolveTag2 } = bundle.runtime;
2530
+ const tag = resolveTag2(as);
2531
+ if (options.allowedAs !== void 0) {
2532
+ enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
2533
+ }
2534
+ const mergedProps = resolveProps(rest);
2535
+ const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
2536
+ const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
2537
+ const finalProps = { ...normalizedProps };
2538
+ if (htmlNormalizers) {
2539
+ for (const normalize of htmlNormalizers) {
2540
+ Object.assign(finalProps, normalize(finalProps));
2541
+ }
2542
+ }
2543
+ const resolvedClass = resolveClasses(
2483
2544
  tag,
2484
- normalizedProps,
2545
+ finalProps,
2485
2546
  className,
2486
2547
  recipe
2487
2548
  );
2488
- const ariaResult = bundle.runtime.resolveAria(tag, normalizedProps);
2489
- const attributes = applyFilter(
2490
- ariaResult.props,
2491
- bundle.filterProps,
2492
- bundle.runtime.options.variantKeys
2493
- );
2549
+ const ariaResult = resolveAria(tag, finalProps);
2550
+ const attributes = applyFilter(ariaResult.props, bundle.filterProps, options.variantKeys);
2494
2551
  return { className: resolvedClass, attributes };
2495
2552
  }
2496
- function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2553
+ function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
2554
+ const hasOwn2 = Object.hasOwn;
2555
+ const attrs = state.attributes;
2497
2556
  host.className = state.className;
2498
- iterate.forEachSet(prevPipelineAttrs, (key) => {
2499
- if (!Object.hasOwn(state.attributes, key)) {
2500
- host.removeAttribute(key);
2501
- }
2502
- });
2557
+ for (const key of prevPipelineAttrs) {
2558
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2559
+ }
2503
2560
  prevPipelineAttrs.clear();
2504
- iterate.forEachKey(incomingProps, (key) => {
2505
- if (!Object.hasOwn(incomingProps, key)) return;
2506
- if (!key.startsWith("aria-") && key !== "role") return;
2507
- if (!Object.hasOwn(state.attributes, key)) host.removeAttribute(key);
2508
- });
2509
- iterate.forEachKey(state.attributes, (key) => {
2510
- if (!Object.hasOwn(state.attributes, key)) return;
2511
- const value = state.attributes[key];
2561
+ for (const key in incomingProps) {
2562
+ if (!hasOwn2(incomingProps, key)) continue;
2563
+ if (!key.startsWith("aria-") && key !== "role") continue;
2564
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2565
+ }
2566
+ for (const key in attrs) {
2567
+ if (!hasOwn2(attrs, key)) continue;
2568
+ const value = attrs[key];
2512
2569
  if (value === void 0 || value === null || value === false) {
2513
2570
  host.removeAttribute(key);
2514
2571
  } else if (value === true) {
@@ -2518,8 +2575,54 @@ function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2518
2575
  host.setAttribute(key, String(value));
2519
2576
  prevPipelineAttrs.add(key);
2520
2577
  }
2521
- });
2578
+ }
2579
+ }
2580
+
2581
+ // ../../adapters/lit/src/create-contract-component.ts
2582
+ import { LitElement, html } from "lit";
2583
+
2584
+ // ../../adapters/lit/src/build-runtime.ts
2585
+ import { silentDiagnostics as silentDiagnostics4 } from "../_shared/diagnostics.js";
2586
+ function normalizeOptions(options) {
2587
+ return {
2588
+ ...options,
2589
+ ...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics4)
2590
+ };
2591
+ }
2592
+ function buildRuntime(options) {
2593
+ const { filterProps: customFilter, enforcement } = options;
2594
+ const normalized = normalizeOptions(options);
2595
+ const { runtime, ownedKeys } = buildCoreRuntime(normalized);
2596
+ const { childrenEvaluator } = buildEngines(
2597
+ normalized.diagnostics,
2598
+ enforcement?.children,
2599
+ normalized.name
2600
+ );
2601
+ const filterProps = composeFilter(ownedKeys, customFilter);
2602
+ return {
2603
+ runtime,
2604
+ filterProps,
2605
+ ...childrenEvaluator !== void 0 && { childrenEvaluator }
2606
+ };
2607
+ }
2608
+
2609
+ // ../../adapters/lit/src/render-to-string.ts
2610
+ var ssrRegistry = /* @__PURE__ */ new WeakMap();
2611
+ function registerForSsr(cls, bundle) {
2612
+ ssrRegistry.set(cls, { bundle });
2613
+ }
2614
+ function renderToString(component, props = {}, innerHTML = "") {
2615
+ const entry = ssrRegistry.get(component);
2616
+ if (!entry) {
2617
+ const name = component.name ?? "AnonymousComponent";
2618
+ throw new Error(
2619
+ `[renderToString] ${name} was not registered for SSR. Ensure it was created with createContractComponent from @praxis-kit/lit.`
2620
+ );
2621
+ }
2622
+ return renderBundleToString(entry.bundle, props, innerHTML);
2522
2623
  }
2624
+
2625
+ // ../../adapters/lit/src/create-contract-component.ts
2523
2626
  function createContractComponent(options) {
2524
2627
  const bundle = buildRuntime(options);
2525
2628
  const looseBundle = toLooseBundle(bundle);
@@ -2587,7 +2690,8 @@ function createContractComponent(options) {
2587
2690
  const self = this._self;
2588
2691
  const props = {};
2589
2692
  iterate.forEach(iterate.items(this.attributes), (attr) => {
2590
- if (attr.name !== "class") props[attr.name] = attr.value;
2693
+ if (attr.name === "class") return;
2694
+ props[attr.name] = attr.name === "disabled" ? true : attr.value;
2591
2695
  });
2592
2696
  props["as"] = self.as;
2593
2697
  props["recipe"] = self.recipe;
@@ -2596,12 +2700,15 @@ function createContractComponent(options) {
2596
2700
  const val = self[key];
2597
2701
  if (val != null) props[key] = val;
2598
2702
  });
2599
- applyHostState(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2703
+ diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2600
2704
  }
2601
2705
  render() {
2706
+ const children = Array.from(this.childNodes);
2602
2707
  if (bundle.childrenEvaluator) {
2603
- bundle.childrenEvaluator.evaluate(Array.from(this.childNodes));
2708
+ bundle.childrenEvaluator.evaluate(children);
2604
2709
  }
2710
+ const tag = bundle.runtime.resolveTag(this._self.as);
2711
+ bundle.runtime.options.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
2605
2712
  return html`<slot></slot>`;
2606
2713
  }
2607
2714
  }