praxis-kit 4.0.3 → 4.1.1

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/web/index.js CHANGED
@@ -1,8 +1,16 @@
1
- // ../../lib/primitive/src/tag/resolve-tag.ts
2
- function makeResolveTag(defaultTag) {
3
- return function tag(as) {
4
- return as ?? defaultTag;
5
- };
1
+ // ../../lib/adapter-utils/src/runtime/define-component.ts
2
+ function defineContractComponent(options) {
3
+ return (factory) => factory(options);
4
+ }
5
+
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;
6
14
  }
7
15
 
8
16
  // ../../lib/primitive/src/utils/is-object.ts
@@ -17,195 +25,6 @@ function isNumber(value) {
17
25
  return typeof value === "number";
18
26
  }
19
27
 
20
- // ../../lib/primitive/src/utils/assert-never.ts
21
- function assertNever(value) {
22
- throw new Error(`Unexpected value: ${String(value)}`);
23
- }
24
-
25
- // ../../lib/primitive/src/utils/cn.ts
26
- import { clsx } from "clsx";
27
- function cn(...inputs) {
28
- return clsx(...inputs);
29
- }
30
-
31
- // ../../lib/primitive/src/utils/iterate.ts
32
- function find(iterable, callback) {
33
- for (const value of iterable) {
34
- const result = callback(value);
35
- if (result != null) {
36
- return result;
37
- }
38
- }
39
- return null;
40
- }
41
- function some(iterable, predicate) {
42
- for (const value of iterable) {
43
- if (predicate(value)) return true;
44
- }
45
- return false;
46
- }
47
- function every(iterable, predicate) {
48
- let index = 0;
49
- for (const value of iterable) {
50
- if (!predicate(value, index++)) {
51
- return false;
52
- }
53
- }
54
- return true;
55
- }
56
- function* filter(iterable, predicate) {
57
- let index = 0;
58
- for (const value of iterable) {
59
- if (predicate(value, index++)) {
60
- yield value;
61
- }
62
- }
63
- }
64
- function* map(iterable, callback) {
65
- let index = 0;
66
- for (const value of iterable) {
67
- yield callback(value, index++);
68
- }
69
- }
70
- function forEach(iterable, callback) {
71
- let index = 0;
72
- for (const value of iterable) {
73
- callback(value, index++);
74
- }
75
- }
76
- function reduce(iterable, initial, callback) {
77
- let accumulator = initial;
78
- let index = 0;
79
- for (const value of iterable) {
80
- accumulator = callback(accumulator, value, index++);
81
- }
82
- return accumulator;
83
- }
84
- function collect(iterable, callback) {
85
- const result = {};
86
- let index = 0;
87
- for (const value of iterable) {
88
- const entry = callback(value, index++);
89
- if (entry === null) {
90
- return null;
91
- }
92
- result[entry[0]] = entry[1];
93
- }
94
- return result;
95
- }
96
- function findLast(value, callback) {
97
- for (let index = value.length - 1; index >= 0; index--) {
98
- const result = callback(value[index], index);
99
- if (result != null) {
100
- return result;
101
- }
102
- }
103
- return null;
104
- }
105
- function* items(collection) {
106
- for (let i = 0; i < collection.length; i++) {
107
- const item = collection.item(i);
108
- if (item !== null) {
109
- yield item;
110
- }
111
- }
112
- }
113
- function nodeList(list) {
114
- return {
115
- *[Symbol.iterator]() {
116
- for (let i = 0; i < list.length; i++) {
117
- const node = list.item(i);
118
- if (node !== null) {
119
- yield node;
120
- }
121
- }
122
- }
123
- };
124
- }
125
- function mapEntries(m) {
126
- return m.entries();
127
- }
128
- function set(s) {
129
- return s.values();
130
- }
131
- function hasOwn(object, key) {
132
- return Object.hasOwn(object, key);
133
- }
134
- function* entries(object) {
135
- for (const key in object) {
136
- if (!hasOwn(object, key)) continue;
137
- yield [key, object[key]];
138
- }
139
- }
140
- function* keys(object) {
141
- for (const [key] of entries(object)) {
142
- yield key;
143
- }
144
- }
145
- function* values(object) {
146
- for (const [, value] of entries(object)) {
147
- yield value;
148
- }
149
- }
150
- function mapValues(object, callback) {
151
- const result = {};
152
- for (const [key, value] of entries(object)) {
153
- result[key] = callback(value, key);
154
- }
155
- return result;
156
- }
157
- function forEachEntry(object, callback) {
158
- for (const [key, value] of entries(object)) {
159
- callback(key, value);
160
- }
161
- }
162
- function forEachKey(object, callback) {
163
- for (const key of keys(object)) {
164
- callback(key);
165
- }
166
- }
167
- function forEachValue(object, callback) {
168
- for (const value of values(object)) {
169
- callback(value);
170
- }
171
- }
172
- function forEachSet(s, callback) {
173
- for (const value of s) {
174
- callback(value);
175
- }
176
- }
177
- var iterate = Object.freeze({
178
- entries,
179
- filter,
180
- find,
181
- findLast,
182
- forEach,
183
- forEachEntry,
184
- forEachKey,
185
- forEachSet,
186
- forEachValue,
187
- items,
188
- keys,
189
- map,
190
- mapEntries,
191
- mapValues,
192
- nodeList,
193
- reduce,
194
- collect,
195
- set,
196
- some,
197
- every,
198
- values
199
- });
200
-
201
- // ../../lib/primitive/src/utils/merge-props.ts
202
- function mergeProps(defaultProps, props) {
203
- return {
204
- ...defaultProps ?? {},
205
- ...props
206
- };
207
- }
208
-
209
28
  // ../../lib/primitive/src/constants/aria/global-aria-attributes.ts
210
29
  var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
211
30
  "aria-atomic",
@@ -228,7 +47,7 @@ var GLOBAL_ARIA_ATTRIBUTES = /* @__PURE__ */ new Set([
228
47
  ]);
229
48
 
230
49
  // ../../lib/primitive/src/constants/aria/implicit-role-record.ts
231
- var IMPLICIT_ROLE_RECORD = {
50
+ var IMPLICIT_ROLE_RECORD = Object.freeze({
232
51
  // Landmarks
233
52
  article: "article",
234
53
  aside: "complementary",
@@ -264,8 +83,8 @@ var IMPLICIT_ROLE_RECORD = {
264
83
  meter: "meter",
265
84
  output: "status",
266
85
  progress: "progressbar"
267
- };
268
- var INPUT_TYPE_ROLE_MAP = {
86
+ });
87
+ var INPUT_TYPE_ROLE_MAP = Object.freeze({
269
88
  checkbox: "checkbox",
270
89
  radio: "radio",
271
90
  range: "slider",
@@ -279,15 +98,17 @@ var INPUT_TYPE_ROLE_MAP = {
279
98
  submit: "button",
280
99
  reset: "button",
281
100
  image: "button"
282
- };
283
- var STRONG_ROLES = [
101
+ });
102
+ var STRONG_ROLES = Object.freeze([
284
103
  "main",
285
104
  "navigation",
286
105
  "complementary",
287
106
  "contentinfo",
288
107
  "banner"
289
- ];
290
- var STANDALONE_ROLES = ["article"];
108
+ ]);
109
+ var STANDALONE_ROLES = Object.freeze([
110
+ "article"
111
+ ]);
291
112
  var STRONG_ROLES_SET = new Set(STRONG_ROLES);
292
113
  var STANDALONE_ROLES_SET = new Set(STANDALONE_ROLES);
293
114
 
@@ -442,69 +263,280 @@ var ROLE_RESTRICTED_ATTRIBUTES = /* @__PURE__ */ new Map([
442
263
  ]
443
264
  ]);
444
265
 
445
- // ../../lib/primitive/src/guards/foundational/is-defined.ts
446
- function isUndefined(value) {
447
- return value === void 0;
266
+ // ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
267
+ function isGlobalAriaAttribute(attr) {
268
+ return GLOBAL_ARIA_ATTRIBUTES.has(attr);
269
+ }
270
+ function isAriaAttributeValidForRole(attr, role) {
271
+ const allowedRoles = ROLE_RESTRICTED_ATTRIBUTES.get(attr);
272
+ if (isUndefined(allowedRoles)) return true;
273
+ if (isUndefined(role)) return false;
274
+ return allowedRoles.has(role);
448
275
  }
449
276
 
450
- // ../../lib/primitive/src/guards/foundational/is-null.ts
451
- function isNull(value) {
452
- return value === null;
277
+ // ../../lib/primitive/src/guards/aria/is-aria-role.ts
278
+ function isStrongImplicitRole(tag) {
279
+ if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
280
+ return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
281
+ }
282
+ function isStandaloneTag(tag) {
283
+ if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
284
+ return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
285
+ }
286
+ function getInputImplicitRole(type) {
287
+ if (!isString(type) || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
288
+ return INPUT_TYPE_ROLE_MAP[type];
289
+ }
290
+ function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
291
+ const isNamed = isString(ariaLabel) || isString(ariaLabelledBy);
292
+ if (!isNamed) return void 0;
293
+ if (tag === "section") return "region";
294
+ if (tag === "form") return "form";
295
+ return void 0;
453
296
  }
454
297
 
455
- // ../../lib/primitive/src/guards/aria/is-aria-attribute.ts
456
- function isGlobalAriaAttribute(attr) {
457
- return GLOBAL_ARIA_ATTRIBUTES.has(attr);
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
+ }
458
445
  }
459
- function isAriaAttributeValidForRole(attr, role) {
460
- const allowedRoles = ROLE_RESTRICTED_ATTRIBUTES.get(attr);
461
- if (isUndefined(allowedRoles)) return true;
462
- if (isUndefined(role)) return false;
463
- return allowedRoles.has(role);
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;
464
452
  }
465
-
466
- // ../../lib/primitive/src/guards/aria/is-aria-role.ts
467
- function isStrongImplicitRole(tag) {
468
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
469
- return STRONG_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
453
+ function forEachEntry(object, callback) {
454
+ for (const [key, value] of entries(object)) {
455
+ callback(key, value);
456
+ }
470
457
  }
471
- function isStandaloneTag(tag) {
472
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
473
- return STANDALONE_ROLES_SET.has(IMPLICIT_ROLE_RECORD[tag]);
458
+ function forEachKey(object, callback) {
459
+ for (const key of keys(object)) {
460
+ callback(key);
461
+ }
474
462
  }
475
- function getInputImplicitRole(type) {
476
- if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
477
- return INPUT_TYPE_ROLE_MAP[type];
463
+ function forEachValue(object, callback) {
464
+ for (const value of values(object)) {
465
+ callback(value);
466
+ }
478
467
  }
479
- function getConditionalImplicitRole(tag, ariaLabel, ariaLabelledBy) {
480
- const isNamed = typeof ariaLabel === "string" || typeof ariaLabelledBy === "string";
481
- if (!isNamed) return void 0;
482
- if (tag === "section") return "region";
483
- if (tag === "form") return "form";
484
- return void 0;
468
+ function forEachSet(s, callback) {
469
+ for (const value of s) {
470
+ callback(value);
471
+ }
485
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
+ });
486
496
 
487
- // ../../lib/adapter-utils/src/apply-filter.ts
488
- function applyFilter(props, filterProps, variantKeys) {
489
- const out = {};
490
- iterate.forEachEntry(props, (k) => {
491
- if (!Object.hasOwn(props, k)) return;
492
- if (filterProps(k, variantKeys)) return;
493
- out[k] = props[k];
494
- });
495
- return out;
497
+ // ../../lib/primitive/src/utils/merge-props.ts
498
+ function mergeProps(defaultProps, props) {
499
+ return {
500
+ ...defaultProps ?? {},
501
+ ...props
502
+ };
496
503
  }
497
504
 
498
- // ../../lib/contract/src/aria/aria-role-policy.ts
499
- function getImplicitRole(tag, props) {
500
- if (tag in IMPLICIT_ROLE_RECORD) return IMPLICIT_ROLE_RECORD[tag];
501
- if (tag === "input") return getInputImplicitRole(props?.type);
502
- if (tag === "img") return props?.alt === "" ? "none" : "img";
503
- if (tag === "section" || tag === "form") {
504
- 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;
505
524
  }
506
525
  return void 0;
507
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
+ }
508
540
 
509
541
  // ../../lib/contract/src/strict/invariant-base.ts
510
542
  var InvariantBase = class {
@@ -1515,7 +1547,7 @@ function getTypeName(value) {
1515
1547
  return primitive;
1516
1548
  }
1517
1549
  const name = value.constructor?.name;
1518
- return typeof name === "string" && name !== "Object" ? name : "object";
1550
+ return isString(name) && name !== "Object" ? name : "object";
1519
1551
  }
1520
1552
 
1521
1553
  // ../../lib/contract/src/children/normalize-child-rule.ts
@@ -1766,6 +1798,9 @@ var readonlyProps = ({
1766
1798
  };
1767
1799
  };
1768
1800
 
1801
+ // ../core/src/html/evaluators.ts
1802
+ import { warnDiagnostics as warnDiagnostics2 } from "../_shared/diagnostics.js";
1803
+
1769
1804
  // ../core/src/html/aria-rules.ts
1770
1805
  var LANDMARK_TAG_SET = /* @__PURE__ */ new Set(["article", "aside", "footer", "header", "main", "nav"]);
1771
1806
  var removeLandmarkRoleOverride = {
@@ -1808,6 +1843,171 @@ function landmarkNameAdvisory(ctx) {
1808
1843
  }
1809
1844
  var HTML_ARIA_RULES = [landmarkRoleRule, landmarkNameAdvisory];
1810
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) => {
1851
+ if (!isObject(child) || !("type" in child)) return false;
1852
+ const tag = getTag(child);
1853
+ return tag === void 0 || !set2.has(tag);
1854
+ };
1855
+ }
1856
+ var METADATA_TAGS = ["script", "template"];
1857
+ var metadataMatch = isTag(...METADATA_TAGS);
1858
+ function metadata(name = "metadata") {
1859
+ return { name, match: metadataMatch };
1860
+ }
1861
+ function firstOptional(name, tag) {
1862
+ return { name, match: isTag(tag), cardinality: { max: 1 }, position: "first" };
1863
+ }
1864
+ function contract(children) {
1865
+ return { diagnostics: warnDiagnostics, children };
1866
+ }
1867
+ function ariaContract(aria) {
1868
+ return { diagnostics: warnDiagnostics, aria };
1869
+ }
1870
+ function firstChildContract(name, tag) {
1871
+ return contract([firstOptional(name, tag), { name: "content", match: isOpenContent(tag) }]);
1872
+ }
1873
+ var VOID_TAGS = [
1874
+ "area",
1875
+ "base",
1876
+ "br",
1877
+ "col",
1878
+ "embed",
1879
+ "hr",
1880
+ "img",
1881
+ "input",
1882
+ "link",
1883
+ "meta",
1884
+ "param",
1885
+ "source",
1886
+ "track",
1887
+ "wbr"
1888
+ ];
1889
+ var TEXT_ONLY_TAGS = ["option", "script", "style", "textarea", "title"];
1890
+ var LANDMARK_TAGS = ["article", "aside", "footer", "header", "main", "nav"];
1891
+ var listContract = contract([{ name: "list-item", match: isTag("li", ...METADATA_TAGS) }]);
1892
+ var tableContract = contract([
1893
+ firstOptional("caption", "caption"),
1894
+ { name: "colgroup", match: isTag("colgroup") },
1895
+ { name: "thead", match: isTag("thead"), cardinality: { max: 1 } },
1896
+ { name: "tbody", match: isTag("tbody") },
1897
+ { name: "tfoot", match: isTag("tfoot"), cardinality: { max: 1 } },
1898
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
1899
+ ]);
1900
+ var tableBodyContract = contract([
1901
+ { name: "table-row", match: isTag("tr", ...METADATA_TAGS) }
1902
+ ]);
1903
+ var tableRowContract = contract([
1904
+ { name: "table-cell", match: isTag("td", "th", ...METADATA_TAGS) }
1905
+ ]);
1906
+ var colgroupContract = contract([{ name: "column", match: isTag("col", "template") }]);
1907
+ var dlContract = contract([
1908
+ { name: "term", match: isTag("dt") },
1909
+ { name: "description", match: isTag("dd") },
1910
+ { name: "group", match: isTag("div") },
1911
+ metadata()
1912
+ ]);
1913
+ var selectContract = contract([
1914
+ { name: "option", match: isTag("option", "optgroup", "hr", ...METADATA_TAGS) }
1915
+ ]);
1916
+ var optgroupContract = contract([
1917
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
1918
+ ]);
1919
+ var datalistContract = contract([
1920
+ { name: "option", match: isTag("option", ...METADATA_TAGS) }
1921
+ ]);
1922
+ var pictureContract = contract([
1923
+ { name: "source", match: isTag("source", ...METADATA_TAGS) },
1924
+ { name: "image", match: isTag("img"), cardinality: { min: 1, max: 1 }, position: "last" }
1925
+ ]);
1926
+ var figureContract = contract([
1927
+ { name: "caption", match: isTag("figcaption"), cardinality: { max: 1 } },
1928
+ { name: "content", match: isOpenContent("figcaption") }
1929
+ ]);
1930
+ var detailsContract = firstChildContract("summary", "summary");
1931
+ var fieldsetContract = firstChildContract("legend", "legend");
1932
+ var mediaContract = contract([
1933
+ { name: "source", match: isTag("source") },
1934
+ { name: "track", match: isTag("track") },
1935
+ metadata(),
1936
+ { name: "content", match: isOpenContent("source", "track", ...METADATA_TAGS) }
1937
+ ]);
1938
+ var headContract = contract([
1939
+ {
1940
+ name: "metadata",
1941
+ match: isTag("base", "link", "meta", "noscript", "script", "style", "template", "title")
1942
+ }
1943
+ ]);
1944
+ var htmlContract = contract([
1945
+ { name: "head", match: isTag("head"), cardinality: { min: 1, max: 1 }, position: "first" },
1946
+ { name: "body", match: isTag("body"), cardinality: { min: 1, max: 1 } }
1947
+ ]);
1948
+ var voidContract = contract([]);
1949
+ var textOnlyContract = contract([
1950
+ {
1951
+ name: "text",
1952
+ match: (child) => isString(child) || isNumber(child)
1953
+ }
1954
+ ]);
1955
+ var landmarkContract = ariaContract([landmarkRoleRule, landmarkNameAdvisory]);
1956
+ var dialogContract = ariaContract([requireAccessibleName]);
1957
+ var menuContract = ariaContract([requireAccessibleName]);
1958
+ var menubarContract = ariaContract([requireAccessibleName]);
1959
+ var treeContract = ariaContract([requireAccessibleName]);
1960
+ var gridContract = ariaContract([requireAccessibleName]);
1961
+ var listboxContract = ariaContract([requireAccessibleName]);
1962
+ var tablistContract = ariaContract([requireAccessibleName]);
1963
+ var radiogroupContract = ariaContract([requireAccessibleName]);
1964
+ var CONTRACT_GROUPS = [
1965
+ [VOID_TAGS, voidContract],
1966
+ [TEXT_ONLY_TAGS, textOnlyContract],
1967
+ [LANDMARK_TAGS, landmarkContract],
1968
+ [["ul", "ol", "menu"], listContract],
1969
+ [["audio", "video"], mediaContract],
1970
+ [["thead", "tbody", "tfoot"], tableBodyContract]
1971
+ ];
1972
+ function contractMap(groups) {
1973
+ return Object.fromEntries(
1974
+ groups.flatMap(([tags, enforcement]) => tags.map((tag) => [tag, enforcement]))
1975
+ );
1976
+ }
1977
+ var htmlContracts = {
1978
+ ...contractMap(CONTRACT_GROUPS),
1979
+ table: tableContract,
1980
+ tr: tableRowContract,
1981
+ colgroup: colgroupContract,
1982
+ dl: dlContract,
1983
+ select: selectContract,
1984
+ optgroup: optgroupContract,
1985
+ datalist: datalistContract,
1986
+ picture: pictureContract,
1987
+ figure: figureContract,
1988
+ details: detailsContract,
1989
+ fieldset: fieldsetContract,
1990
+ dialog: dialogContract,
1991
+ head: headContract,
1992
+ html: htmlContract
1993
+ };
1994
+
1995
+ // ../core/src/html/evaluators.ts
1996
+ var htmlDiagnostics = warnDiagnostics2;
1997
+ function buildEvaluatorMap() {
1998
+ const map2 = /* @__PURE__ */ new Map();
1999
+ iterate.forEachEntry(htmlContracts, (tag, { children }) => {
2000
+ if (children?.length) {
2001
+ map2.set(tag, new ChildrenEvaluator(children, htmlDiagnostics, `<${tag}>`));
2002
+ }
2003
+ });
2004
+ return map2;
2005
+ }
2006
+ var HTML_EVALUATORS = buildEvaluatorMap();
2007
+ function getHtmlChildrenEvaluator(tag) {
2008
+ return typeof tag === "string" ? HTML_EVALUATORS.get(tag) : void 0;
2009
+ }
2010
+
1811
2011
  // ../core/src/html/prop-normalizers.ts
1812
2012
  var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
1813
2013
  ["button", [disabledProps]],
@@ -1995,6 +2195,19 @@ function createClassPipeline(resolved) {
1995
2195
  };
1996
2196
  }
1997
2197
 
2198
+ // ../../lib/pipeline-kit/src/factory/define-pipeline.ts
2199
+ function definePipeline(factory) {
2200
+ const cache = /* @__PURE__ */ new WeakMap();
2201
+ return (resolved) => {
2202
+ let pipeline = cache.get(resolved);
2203
+ if (!pipeline) {
2204
+ pipeline = factory(resolved);
2205
+ cache.set(resolved, pipeline);
2206
+ }
2207
+ return pipeline;
2208
+ };
2209
+ }
2210
+
1998
2211
  // ../core/src/options/resolve-factory-options.ts
1999
2212
  import { silentDiagnostics } from "../_shared/diagnostics.js";
2000
2213
  var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
@@ -2130,89 +2343,82 @@ function guardPipeline(pipeline) {
2130
2343
  };
2131
2344
  }
2132
2345
 
2133
- // ../core/src/factory/create-polymorphic.ts
2134
- var NOOP_CLASS_PIPELINE = (_tag, _props, className) => Array.isArray(className) ? className.join(" ") : className ?? "";
2135
- function resolveClassPipeline(options, resolved, diagnostics, capabilities) {
2136
- const factory = options.styling?.plugin;
2137
- if (!factory) {
2138
- const createClassPipeline2 = capabilities?.createClassPipeline;
2139
- const classPipeline2 = createClassPipeline2 ? createClassPipeline2(resolved) : NOOP_CLASS_PIPELINE;
2140
- return { pluginResult: void 0, classPipeline: classPipeline2 };
2141
- }
2346
+ // ../core/src/factory/create-polymorphic2.ts
2347
+ var createTagPipeline = (resolved) => makeResolveTag(resolved.defaultTag);
2348
+ var createPropsPipeline = (resolved) => (props) => mergeProps(resolved.defaultProps, props);
2349
+ var createHtmlPropNormalizersPipeline = () => getHtmlPropNormalizers;
2350
+ var createHtmlChildrenEvaluatorPipeline = () => getHtmlChildrenEvaluator;
2351
+ var createStylingClassPipeline = (resolved) => createClassPipeline(resolved);
2352
+ function resolveAriaRules(resolved) {
2353
+ return [.../* @__PURE__ */ new Set([...HTML_ARIA_RULES, ...resolved.ariaRules ?? []])];
2354
+ }
2355
+ var createAriaPipeline = (resolved) => {
2356
+ const rules = resolveAriaRules(resolved);
2357
+ const engine = new AriaPolicyEngine(resolved.diagnostics, rules.length ? { rules } : void 0);
2358
+ return (tag, props) => engine.validate(tag, props);
2359
+ };
2360
+ var memoizedTagPipeline = definePipeline(createTagPipeline);
2361
+ var memoizedPropsPipeline = definePipeline(createPropsPipeline);
2362
+ var memoizedHtmlPropNormalizersPipeline = definePipeline(createHtmlPropNormalizersPipeline);
2363
+ var memoizedHtmlChildrenEvaluatorPipeline = definePipeline(createHtmlChildrenEvaluatorPipeline);
2364
+ var memoizedClassPipeline = definePipeline(createStylingClassPipeline);
2365
+ var memoizedAriaPipeline = definePipeline(createAriaPipeline);
2366
+ function resolveAriaPassthrough(_tag, props) {
2367
+ return { props };
2368
+ }
2369
+ function resolveClassPlugin(factory, resolved, diagnostics) {
2370
+ if (!factory) return { pluginResult: void 0, classPipeline: memoizedClassPipeline(resolved) };
2142
2371
  const pluginResult = factory(resolved, diagnostics);
2143
2372
  assertPluginShape(pluginResult);
2144
- const classPipeline = guardPipeline(pluginResult.pipeline);
2145
- return { pluginResult, classPipeline };
2373
+ return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
2146
2374
  }
2147
- function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
2148
- return {
2149
- resolveTag: makeResolveTag(resolved.defaultTag),
2150
- resolveProps(props) {
2151
- return mergeProps(resolved.defaultProps, props);
2152
- },
2375
+ function createPolymorphic2(options = {}) {
2376
+ const baseResolved = resolveFactoryOptions(options);
2377
+ const anyBaseResolved = baseResolved;
2378
+ const resolved = Object.freeze({
2379
+ ...baseResolved,
2380
+ htmlPropNormalizersFn: memoizedHtmlPropNormalizersPipeline(anyBaseResolved),
2381
+ htmlChildrenEvaluatorFn: memoizedHtmlChildrenEvaluatorPipeline(anyBaseResolved)
2382
+ });
2383
+ const anyResolved = resolved;
2384
+ if (process.env.NODE_ENV !== "production") {
2385
+ validateFactoryOptions(resolved, resolved.diagnostics);
2386
+ }
2387
+ const { pluginResult, classPipeline } = resolveClassPlugin(
2388
+ options.styling?.plugin,
2389
+ anyResolved,
2390
+ resolved.diagnostics
2391
+ );
2392
+ const resolveTag2 = memoizedTagPipeline(anyResolved);
2393
+ const resolveProps = memoizedPropsPipeline(anyResolved);
2394
+ const resolveAriaFn = options.enforcement !== void 0 ? memoizedAriaPipeline(anyResolved) : resolveAriaPassthrough;
2395
+ const methods = {
2396
+ resolveTag: resolveTag2,
2397
+ resolveProps,
2153
2398
  resolveClasses(tag, props, className, recipe) {
2154
2399
  if (process.env.NODE_ENV !== "production") {
2155
- validateRenderProps(renderDiagnostics, resolved, props, recipe);
2400
+ validateRenderProps(resolved.diagnostics, resolved, props, recipe);
2156
2401
  }
2157
2402
  return classPipeline(tag, props, className, recipe);
2158
2403
  },
2159
2404
  resolveAria(tag, props) {
2160
- if (!engine) return { props };
2161
- const result = engine.validate(tag, props);
2162
- return { props: result.props };
2405
+ return resolveAriaFn(tag, props);
2163
2406
  }
2164
2407
  };
2165
- }
2166
- function createRuntimeObject(methods, resolved, pluginResult) {
2167
- return pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2168
- }
2169
- function createPolymorphic(options = {}, capabilities) {
2170
- const baseResolved = resolveFactoryOptions(options);
2171
- const resolved = capabilities?.htmlPropNormalizersFn !== void 0 ? Object.freeze({
2172
- ...baseResolved,
2173
- htmlPropNormalizersFn: capabilities.htmlPropNormalizersFn
2174
- }) : baseResolved;
2175
- if (process.env.NODE_ENV !== "production") {
2176
- validateFactoryOptions(resolved, resolved.diagnostics);
2177
- }
2178
- const { pluginResult, classPipeline } = resolveClassPipeline(
2179
- options,
2180
- resolved,
2181
- resolved.diagnostics,
2182
- capabilities
2183
- );
2184
- const allAriaRules = [
2185
- .../* @__PURE__ */ new Set([...capabilities?.htmlAriaRules ?? [], ...resolved.ariaRules ?? []])
2186
- ];
2187
- const engine = options.enforcement !== void 0 && capabilities?.AriaEngine ? new capabilities.AriaEngine(
2188
- resolved.diagnostics,
2189
- allAriaRules.length ? { rules: allAriaRules } : void 0
2190
- ) : null;
2191
- const methods = createRuntimeMethods(resolved, classPipeline, engine, resolved.diagnostics);
2192
- return createRuntimeObject(
2193
- methods,
2194
- resolved,
2195
- pluginResult
2196
- );
2197
- }
2198
-
2199
- // ../core/src/factory/create-polymorphic-full.ts
2200
- var FULL_CAPABILITIES = {
2201
- createClassPipeline,
2202
- AriaEngine: AriaPolicyEngine,
2203
- htmlAriaRules: HTML_ARIA_RULES,
2204
- htmlPropNormalizersFn: getHtmlPropNormalizers
2205
- };
2206
- function createPolymorphic2(options = {}) {
2207
- return createPolymorphic(options, FULL_CAPABILITIES);
2408
+ const runtimeObject = pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2409
+ return runtimeObject;
2208
2410
  }
2209
2411
 
2210
- // ../../lib/adapter-utils/src/define-component.ts
2211
- function defineContractComponent(options) {
2212
- return (factory) => factory(options);
2412
+ // ../core/src/resolver/resolver.ts
2413
+ import { silentDiagnostics as silentDiagnostics2 } from "../_shared/diagnostics.js";
2414
+ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
2415
+ if (allowedAs.includes(tag)) return;
2416
+ if (!diagnostics) return;
2417
+ const component = displayName ?? String(tag);
2418
+ diagnostics.error(ContractDiagnostics.allowedAsViolation(String(tag), allowedAs, component));
2213
2419
  }
2214
2420
 
2215
- // ../../lib/adapter-utils/src/build-core-runtime.ts
2421
+ // ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
2216
2422
  var EMPTY_SET = /* @__PURE__ */ new Set();
2217
2423
  function buildCoreRuntime(normalized) {
2218
2424
  const runtime = createPolymorphic2(normalized);
@@ -2220,22 +2426,13 @@ function buildCoreRuntime(normalized) {
2220
2426
  return { runtime, ownedKeys };
2221
2427
  }
2222
2428
 
2223
- // ../../lib/adapter-utils/src/build-engines.ts
2429
+ // ../../lib/adapter-utils/src/runtime/build-engines.ts
2224
2430
  function buildEngines(diagnostics, childRules, context) {
2225
2431
  return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
2226
2432
  }
2227
2433
 
2228
- // ../../lib/adapter-utils/src/compose-filter.ts
2229
- function composeFilter(ownedKeys, filterProps) {
2230
- const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
2231
- if (!filterProps) {
2232
- return defaultFilter;
2233
- }
2234
- return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
2235
- }
2236
-
2237
- // ../../lib/adapter-utils/src/resolve-adapter-common-options.ts
2238
- import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics2 } from "../_shared/diagnostics.js";
2434
+ // ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
2435
+ import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
2239
2436
  function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
2240
2437
  return {
2241
2438
  name: options.name ?? defaultName,
@@ -2243,34 +2440,27 @@ function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponen
2243
2440
  };
2244
2441
  }
2245
2442
 
2246
- // ../../adapters/web/src/build-runtime.ts
2247
- import { silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
2248
- function buildRuntime(options) {
2249
- const normalized = {
2250
- ...options,
2251
- ...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics3)
2252
- };
2253
- const { filterProps: customFilter, enforcement } = normalized;
2254
- const { runtime, ownedKeys } = buildCoreRuntime(normalized);
2255
- const { childrenEvaluator } = buildEngines(
2256
- normalized.diagnostics,
2257
- enforcement?.children,
2258
- normalized.name
2259
- );
2260
- const filterProps = composeFilter(ownedKeys, customFilter);
2261
- return {
2262
- runtime,
2263
- filterProps,
2264
- diagnostics: normalized.diagnostics,
2265
- ...childrenEvaluator !== void 0 && { childrenEvaluator }
2266
- };
2443
+ // ../../lib/adapter-utils/src/props/apply-filter.ts
2444
+ function applyFilter(props, filterProps, variantKeys) {
2445
+ const out = {};
2446
+ iterate.forEachEntry(props, (k) => {
2447
+ if (!Object.hasOwn(props, k)) return;
2448
+ if (filterProps(k, variantKeys)) return;
2449
+ out[k] = props[k];
2450
+ });
2451
+ return out;
2267
2452
  }
2268
2453
 
2269
- // ../../adapters/web/src/render-to-string.ts
2270
- var ssrRegistry = /* @__PURE__ */ new WeakMap();
2271
- function registerForSsr(cls, bundle) {
2272
- ssrRegistry.set(cls, { bundle });
2454
+ // ../../lib/adapter-utils/src/props/compose-filter.ts
2455
+ function composeFilter(ownedKeys, filterProps) {
2456
+ const defaultFilter = (key, variantKeys) => variantKeys.has(key) || ownedKeys.has(key);
2457
+ if (!filterProps) {
2458
+ return defaultFilter;
2459
+ }
2460
+ return (key, variantKeys) => defaultFilter(key, variantKeys) || filterProps(key, variantKeys);
2273
2461
  }
2462
+
2463
+ // ../../lib/adapter-utils/src/render/render-to-string.ts
2274
2464
  function escapeAttr(value) {
2275
2465
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2276
2466
  }
@@ -2284,50 +2474,51 @@ function buildAttrString(attributes) {
2284
2474
  parts.push(`${key}="${escapeAttr(String(value))}"`);
2285
2475
  }
2286
2476
  });
2287
- return parts.length > 0 ? " " + parts.join(" ") : "";
2477
+ return parts.length > 0 ? ` ${parts.join(" ")}` : "";
2288
2478
  }
2289
- function renderToString(component, props = {}, innerHTML = "") {
2290
- const entry = ssrRegistry.get(component);
2291
- if (!entry) {
2292
- const name = component.name ?? "AnonymousComponent";
2293
- throw new Error(
2294
- `[renderToString] ${name} was not registered for SSR. Ensure it was created with createContractComponent from @praxis-kit/web.`
2295
- );
2296
- }
2297
- const { bundle } = entry;
2479
+ function renderBundleToString(bundle, props = {}, innerHTML = "") {
2480
+ const {
2481
+ filterProps,
2482
+ runtime: { options, resolveAria, resolveClasses, resolveProps, resolveTag: resolveTag2 }
2483
+ } = bundle;
2298
2484
  const { as, className, recipe, class: classAttr, ...rest } = props;
2299
- const tag = bundle.runtime.resolveTag(as);
2300
- const mergedProps = bundle.runtime.resolveProps(rest);
2301
- const resolvedClass = bundle.runtime.resolveClasses(
2485
+ const tag = resolveTag2(as);
2486
+ if (options.allowedAs !== void 0) {
2487
+ enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
2488
+ }
2489
+ const mergedProps = resolveProps(rest);
2490
+ const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
2491
+ const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
2492
+ const finalProps = { ...normalizedProps };
2493
+ if (htmlNormalizers) {
2494
+ for (const normalize of htmlNormalizers) {
2495
+ Object.assign(finalProps, normalize(finalProps));
2496
+ }
2497
+ }
2498
+ const resolvedClass = resolveClasses(
2302
2499
  tag,
2303
- mergedProps,
2500
+ finalProps,
2501
+ // Accept both React-style className and HTML-native class
2304
2502
  className ?? classAttr,
2305
2503
  recipe
2306
2504
  );
2307
- const ariaResult = bundle.runtime.resolveAria(tag, mergedProps);
2308
- const filtered = applyFilter(
2309
- ariaResult.props,
2310
- bundle.filterProps,
2311
- bundle.runtime.options.variantKeys
2312
- );
2505
+ const ariaResult = resolveAria(tag, finalProps);
2506
+ const filtered = applyFilter(ariaResult.props, filterProps, options.variantKeys);
2313
2507
  const attrs = { ...filtered, class: resolvedClass || void 0 };
2314
2508
  const attrStr = buildAttrString(attrs);
2315
2509
  return `<${tag}${attrStr}>${innerHTML}</${tag}>`;
2316
2510
  }
2317
2511
 
2318
- // ../../adapters/web/src/create-contract-component.ts
2319
- function isObject2(value) {
2320
- return typeof value === "object" && value !== null;
2321
- }
2512
+ // ../../lib/adapter-utils/src/render/host-state.ts
2322
2513
  function isLooseBundle(arg) {
2323
- if (!isObject2(arg)) return false;
2514
+ if (!isObject(arg)) return false;
2324
2515
  const { runtime, filterProps, childrenEvaluator } = arg;
2325
- if (!isObject2(runtime)) return false;
2326
- if (!isObject2(runtime["options"])) return false;
2516
+ if (!isObject(runtime)) return false;
2517
+ if (!isObject(runtime["options"])) return false;
2327
2518
  if (typeof runtime["resolveTag"] !== "function" || typeof runtime["resolveProps"] !== "function" || typeof runtime["resolveClasses"] !== "function" || typeof runtime["resolveAria"] !== "function")
2328
2519
  return false;
2329
2520
  if (typeof filterProps !== "function") return false;
2330
- if (childrenEvaluator !== void 0 && (!isObject2(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2521
+ if (childrenEvaluator !== void 0 && (!isObject(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2331
2522
  return false;
2332
2523
  return true;
2333
2524
  }
@@ -2339,39 +2530,46 @@ function toLooseBundle(bundle) {
2339
2530
  }
2340
2531
  function resolveHostState(bundle, props) {
2341
2532
  const { as, className, recipe, ...rest } = props;
2342
- const tag = bundle.runtime.resolveTag(as);
2343
- const mergedProps = bundle.runtime.resolveProps(rest);
2344
- const baseProps = bundle.runtime.options.normalizeFn ? bundle.runtime.options.normalizeFn(mergedProps) : mergedProps;
2345
- const htmlNormalizers = bundle.runtime.options.htmlPropNormalizersFn?.(tag);
2346
- const normalizedProps = htmlNormalizers?.length ? htmlNormalizers.reduce((acc, fn) => ({ ...acc, ...fn(acc) }), baseProps) : baseProps;
2347
- const resolvedClass = bundle.runtime.resolveClasses(
2533
+ const { options, resolveAria, resolveClasses, resolveProps, resolveTag: resolveTag2 } = bundle.runtime;
2534
+ const tag = resolveTag2(as);
2535
+ if (options.allowedAs !== void 0) {
2536
+ enforceAllowedAs(tag, options.allowedAs, options.diagnostics, options.displayName);
2537
+ }
2538
+ const mergedProps = resolveProps(rest);
2539
+ const normalizedProps = typeof options.normalizeFn === "function" ? options.normalizeFn(mergedProps) : mergedProps;
2540
+ const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
2541
+ const finalProps = { ...normalizedProps };
2542
+ if (htmlNormalizers) {
2543
+ for (const normalize of htmlNormalizers) {
2544
+ Object.assign(finalProps, normalize(finalProps));
2545
+ }
2546
+ }
2547
+ const resolvedClass = resolveClasses(
2348
2548
  tag,
2349
- normalizedProps,
2549
+ finalProps,
2350
2550
  className,
2351
2551
  recipe
2352
2552
  );
2353
- const ariaResult = bundle.runtime.resolveAria(tag, normalizedProps);
2354
- const attributes = applyFilter(
2355
- ariaResult.props,
2356
- bundle.filterProps,
2357
- bundle.runtime.options.variantKeys
2358
- );
2553
+ const ariaResult = resolveAria(tag, finalProps);
2554
+ const attributes = applyFilter(ariaResult.props, bundle.filterProps, options.variantKeys);
2359
2555
  return { className: resolvedClass, attributes };
2360
2556
  }
2361
- function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2557
+ function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
2558
+ const hasOwn2 = Object.hasOwn;
2559
+ const attrs = state.attributes;
2362
2560
  host.className = state.className;
2363
2561
  for (const key of prevPipelineAttrs) {
2364
- if (!Object.hasOwn(state.attributes, key)) host.removeAttribute(key);
2562
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2365
2563
  }
2366
2564
  prevPipelineAttrs.clear();
2367
2565
  for (const key in incomingProps) {
2368
- if (!Object.hasOwn(incomingProps, key)) continue;
2566
+ if (!hasOwn2(incomingProps, key)) continue;
2369
2567
  if (!key.startsWith("aria-") && key !== "role") continue;
2370
- if (!Object.hasOwn(state.attributes, key)) host.removeAttribute(key);
2568
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2371
2569
  }
2372
- for (const key in state.attributes) {
2373
- if (!Object.hasOwn(state.attributes, key)) continue;
2374
- const value = state.attributes[key];
2570
+ for (const key in attrs) {
2571
+ if (!hasOwn2(attrs, key)) continue;
2572
+ const value = attrs[key];
2375
2573
  if (value === void 0 || value === null || value === false) {
2376
2574
  host.removeAttribute(key);
2377
2575
  } else if (value === true) {
@@ -2383,6 +2581,47 @@ function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2383
2581
  }
2384
2582
  }
2385
2583
  }
2584
+
2585
+ // ../../adapters/web/src/build-runtime.ts
2586
+ import { silentDiagnostics as silentDiagnostics4 } from "../_shared/diagnostics.js";
2587
+ function buildRuntime(options) {
2588
+ const normalized = {
2589
+ ...options,
2590
+ ...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics4)
2591
+ };
2592
+ const { filterProps: customFilter, enforcement } = normalized;
2593
+ const { runtime, ownedKeys } = buildCoreRuntime(normalized);
2594
+ const { childrenEvaluator } = buildEngines(
2595
+ normalized.diagnostics,
2596
+ enforcement?.children,
2597
+ normalized.name
2598
+ );
2599
+ const filterProps = composeFilter(ownedKeys, customFilter);
2600
+ return {
2601
+ runtime,
2602
+ filterProps,
2603
+ diagnostics: normalized.diagnostics,
2604
+ ...childrenEvaluator !== void 0 && { childrenEvaluator }
2605
+ };
2606
+ }
2607
+
2608
+ // ../../adapters/web/src/render-to-string.ts
2609
+ var ssrRegistry = /* @__PURE__ */ new WeakMap();
2610
+ function registerForSsr(cls, bundle) {
2611
+ ssrRegistry.set(cls, { bundle });
2612
+ }
2613
+ function renderToString(component, props = {}, innerHTML = "") {
2614
+ const entry = ssrRegistry.get(component);
2615
+ if (!entry) {
2616
+ const name = component.name ?? "AnonymousComponent";
2617
+ throw new Error(
2618
+ `[renderToString] ${name} was not registered for SSR. Ensure it was created with createContractComponent from @praxis-kit/web.`
2619
+ );
2620
+ }
2621
+ return renderBundleToString(entry.bundle, props, innerHTML);
2622
+ }
2623
+
2624
+ // ../../adapters/web/src/create-contract-component.ts
2386
2625
  function createContractComponent(options) {
2387
2626
  const bundle = buildRuntime(options);
2388
2627
  const looseBundle = toLooseBundle(bundle);
@@ -2417,16 +2656,23 @@ function createContractComponent(options) {
2417
2656
  }
2418
2657
  _applyPraxis() {
2419
2658
  const self = this._self;
2420
- if (bundle.childrenEvaluator) {
2421
- bundle.childrenEvaluator.evaluate(Array.from(this.childNodes));
2659
+ const {
2660
+ childrenEvaluator,
2661
+ runtime: { options: options2, resolveTag: resolveTag2 }
2662
+ } = bundle;
2663
+ const tag = resolveTag2(self.as);
2664
+ const children = Array.from(this.childNodes);
2665
+ if (childrenEvaluator) {
2666
+ childrenEvaluator.evaluate(children);
2422
2667
  }
2668
+ options2.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
2423
2669
  const observedSet = new Set(
2424
2670
  this.constructor.observedAttributes ?? []
2425
2671
  );
2426
2672
  const props = {};
2427
2673
  for (const attr of Array.from(this.attributes)) {
2428
2674
  if (attr.name === "class" || observedSet.has(attr.name)) continue;
2429
- props[attr.name] = attr.value;
2675
+ props[attr.name] = attr.name === "disabled" ? true : attr.value;
2430
2676
  }
2431
2677
  props["as"] = self.as ?? this.getAttribute("as") ?? void 0;
2432
2678
  props["recipe"] = self.recipe ?? this.getAttribute("variant-key") ?? void 0;
@@ -2435,7 +2681,7 @@ function createContractComponent(options) {
2435
2681
  const val = self[key] ?? this.getAttribute(key);
2436
2682
  if (val != null) props[key] = val;
2437
2683
  }
2438
- applyHostState(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2684
+ diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2439
2685
  }
2440
2686
  }
2441
2687
  if (options.name) {