praxis-kit 4.0.3 → 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/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
+ }
458
440
  }
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);
441
+ function* values(object) {
442
+ for (const [, value] of entries(object)) {
443
+ yield value;
444
+ }
464
445
  }
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]);
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;
470
452
  }
471
- function isStandaloneTag(tag) {
472
- if (!(tag in IMPLICIT_ROLE_RECORD)) return false;
473
- return STANDALONE_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
+ }
474
457
  }
475
- function getInputImplicitRole(type) {
476
- if (type == null || !(type in INPUT_TYPE_ROLE_MAP)) return void 0;
477
- return INPUT_TYPE_ROLE_MAP[type];
458
+ function forEachKey(object, callback) {
459
+ for (const key of keys(object)) {
460
+ callback(key);
461
+ }
478
462
  }
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;
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
+ }
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,167 @@ 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) => 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
+
1811
2007
  // ../core/src/html/prop-normalizers.ts
1812
2008
  var HTML_FORM_NORMALIZERS = /* @__PURE__ */ new Map([
1813
2009
  ["button", [disabledProps]],
@@ -1995,6 +2191,19 @@ function createClassPipeline(resolved) {
1995
2191
  };
1996
2192
  }
1997
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
+
1998
2207
  // ../core/src/options/resolve-factory-options.ts
1999
2208
  import { silentDiagnostics } from "../_shared/diagnostics.js";
2000
2209
  var EMPTY_VARIANT_KEYS = /* @__PURE__ */ new Set();
@@ -2130,89 +2339,82 @@ function guardPipeline(pipeline) {
2130
2339
  };
2131
2340
  }
2132
2341
 
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
- }
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) };
2142
2367
  const pluginResult = factory(resolved, diagnostics);
2143
2368
  assertPluginShape(pluginResult);
2144
- const classPipeline = guardPipeline(pluginResult.pipeline);
2145
- return { pluginResult, classPipeline };
2369
+ return { pluginResult, classPipeline: guardPipeline(pluginResult.pipeline) };
2146
2370
  }
2147
- function createRuntimeMethods(resolved, classPipeline, engine, renderDiagnostics) {
2148
- return {
2149
- resolveTag: makeResolveTag(resolved.defaultTag),
2150
- resolveProps(props) {
2151
- return mergeProps(resolved.defaultProps, props);
2152
- },
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,
2153
2394
  resolveClasses(tag, props, className, recipe) {
2154
2395
  if (process.env.NODE_ENV !== "production") {
2155
- validateRenderProps(renderDiagnostics, resolved, props, recipe);
2396
+ validateRenderProps(resolved.diagnostics, resolved, props, recipe);
2156
2397
  }
2157
2398
  return classPipeline(tag, props, className, recipe);
2158
2399
  },
2159
2400
  resolveAria(tag, props) {
2160
- if (!engine) return { props };
2161
- const result = engine.validate(tag, props);
2162
- return { props: result.props };
2401
+ return resolveAriaFn(tag, props);
2163
2402
  }
2164
2403
  };
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);
2404
+ const runtimeObject = pluginResult ? { ...methods, options: resolved, hasStyling: true, classPlugin: pluginResult } : { ...methods, options: resolved };
2405
+ return runtimeObject;
2208
2406
  }
2209
2407
 
2210
- // ../../lib/adapter-utils/src/define-component.ts
2211
- function defineContractComponent(options) {
2212
- 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));
2213
2415
  }
2214
2416
 
2215
- // ../../lib/adapter-utils/src/build-core-runtime.ts
2417
+ // ../../lib/adapter-utils/src/runtime/build-core-runtime.ts
2216
2418
  var EMPTY_SET = /* @__PURE__ */ new Set();
2217
2419
  function buildCoreRuntime(normalized) {
2218
2420
  const runtime = createPolymorphic2(normalized);
@@ -2220,22 +2422,13 @@ function buildCoreRuntime(normalized) {
2220
2422
  return { runtime, ownedKeys };
2221
2423
  }
2222
2424
 
2223
- // ../../lib/adapter-utils/src/build-engines.ts
2425
+ // ../../lib/adapter-utils/src/runtime/build-engines.ts
2224
2426
  function buildEngines(diagnostics, childRules, context) {
2225
2427
  return childRules?.length ? { childrenEvaluator: new ChildrenEvaluator(childRules, diagnostics, context) } : {};
2226
2428
  }
2227
2429
 
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";
2430
+ // ../../lib/adapter-utils/src/runtime/resolve-adapter-common-options.ts
2431
+ import { throwDiagnostics as throwDiagnostics2, silentDiagnostics as silentDiagnostics3 } from "../_shared/diagnostics.js";
2239
2432
  function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponent", defaultDiagnostics = throwDiagnostics2) {
2240
2433
  return {
2241
2434
  name: options.name ?? defaultName,
@@ -2243,34 +2436,27 @@ function resolveAdapterCommonOptions(options, defaultName = "PolymorphicComponen
2243
2436
  };
2244
2437
  }
2245
2438
 
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
- };
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;
2267
2448
  }
2268
2449
 
2269
- // ../../adapters/web/src/render-to-string.ts
2270
- var ssrRegistry = /* @__PURE__ */ new WeakMap();
2271
- function registerForSsr(cls, bundle) {
2272
- 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);
2273
2457
  }
2458
+
2459
+ // ../../lib/adapter-utils/src/render/render-to-string.ts
2274
2460
  function escapeAttr(value) {
2275
2461
  return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
2276
2462
  }
@@ -2284,50 +2470,51 @@ function buildAttrString(attributes) {
2284
2470
  parts.push(`${key}="${escapeAttr(String(value))}"`);
2285
2471
  }
2286
2472
  });
2287
- return parts.length > 0 ? " " + parts.join(" ") : "";
2473
+ return parts.length > 0 ? ` ${parts.join(" ")}` : "";
2288
2474
  }
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;
2475
+ function renderBundleToString(bundle, props = {}, innerHTML = "") {
2476
+ const {
2477
+ filterProps,
2478
+ runtime: { options, resolveAria, resolveClasses, resolveProps, resolveTag: resolveTag2 }
2479
+ } = bundle;
2298
2480
  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(
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(
2302
2495
  tag,
2303
- mergedProps,
2496
+ finalProps,
2497
+ // Accept both React-style className and HTML-native class
2304
2498
  className ?? classAttr,
2305
2499
  recipe
2306
2500
  );
2307
- const ariaResult = bundle.runtime.resolveAria(tag, mergedProps);
2308
- const filtered = applyFilter(
2309
- ariaResult.props,
2310
- bundle.filterProps,
2311
- bundle.runtime.options.variantKeys
2312
- );
2501
+ const ariaResult = resolveAria(tag, finalProps);
2502
+ const filtered = applyFilter(ariaResult.props, filterProps, options.variantKeys);
2313
2503
  const attrs = { ...filtered, class: resolvedClass || void 0 };
2314
2504
  const attrStr = buildAttrString(attrs);
2315
2505
  return `<${tag}${attrStr}>${innerHTML}</${tag}>`;
2316
2506
  }
2317
2507
 
2318
- // ../../adapters/web/src/create-contract-component.ts
2319
- function isObject2(value) {
2320
- return typeof value === "object" && value !== null;
2321
- }
2508
+ // ../../lib/adapter-utils/src/render/host-state.ts
2322
2509
  function isLooseBundle(arg) {
2323
- if (!isObject2(arg)) return false;
2510
+ if (!isObject(arg)) return false;
2324
2511
  const { runtime, filterProps, childrenEvaluator } = arg;
2325
- if (!isObject2(runtime)) return false;
2326
- if (!isObject2(runtime["options"])) return false;
2512
+ if (!isObject(runtime)) return false;
2513
+ if (!isObject(runtime["options"])) return false;
2327
2514
  if (typeof runtime["resolveTag"] !== "function" || typeof runtime["resolveProps"] !== "function" || typeof runtime["resolveClasses"] !== "function" || typeof runtime["resolveAria"] !== "function")
2328
2515
  return false;
2329
2516
  if (typeof filterProps !== "function") return false;
2330
- if (childrenEvaluator !== void 0 && (!isObject2(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2517
+ if (childrenEvaluator !== void 0 && (!isObject(childrenEvaluator) || typeof childrenEvaluator["evaluate"] !== "function"))
2331
2518
  return false;
2332
2519
  return true;
2333
2520
  }
@@ -2339,39 +2526,46 @@ function toLooseBundle(bundle) {
2339
2526
  }
2340
2527
  function resolveHostState(bundle, props) {
2341
2528
  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(
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(
2348
2544
  tag,
2349
- normalizedProps,
2545
+ finalProps,
2350
2546
  className,
2351
2547
  recipe
2352
2548
  );
2353
- const ariaResult = bundle.runtime.resolveAria(tag, normalizedProps);
2354
- const attributes = applyFilter(
2355
- ariaResult.props,
2356
- bundle.filterProps,
2357
- bundle.runtime.options.variantKeys
2358
- );
2549
+ const ariaResult = resolveAria(tag, finalProps);
2550
+ const attributes = applyFilter(ariaResult.props, bundle.filterProps, options.variantKeys);
2359
2551
  return { className: resolvedClass, attributes };
2360
2552
  }
2361
- function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2553
+ function diffAndApplyAttributes(host, state, prevPipelineAttrs, incomingProps) {
2554
+ const hasOwn2 = Object.hasOwn;
2555
+ const attrs = state.attributes;
2362
2556
  host.className = state.className;
2363
2557
  for (const key of prevPipelineAttrs) {
2364
- if (!Object.hasOwn(state.attributes, key)) host.removeAttribute(key);
2558
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2365
2559
  }
2366
2560
  prevPipelineAttrs.clear();
2367
2561
  for (const key in incomingProps) {
2368
- if (!Object.hasOwn(incomingProps, key)) continue;
2562
+ if (!hasOwn2(incomingProps, key)) continue;
2369
2563
  if (!key.startsWith("aria-") && key !== "role") continue;
2370
- if (!Object.hasOwn(state.attributes, key)) host.removeAttribute(key);
2564
+ if (!hasOwn2(attrs, key)) host.removeAttribute(key);
2371
2565
  }
2372
- for (const key in state.attributes) {
2373
- if (!Object.hasOwn(state.attributes, key)) continue;
2374
- const value = state.attributes[key];
2566
+ for (const key in attrs) {
2567
+ if (!hasOwn2(attrs, key)) continue;
2568
+ const value = attrs[key];
2375
2569
  if (value === void 0 || value === null || value === false) {
2376
2570
  host.removeAttribute(key);
2377
2571
  } else if (value === true) {
@@ -2383,6 +2577,47 @@ function applyHostState(host, state, prevPipelineAttrs, incomingProps) {
2383
2577
  }
2384
2578
  }
2385
2579
  }
2580
+
2581
+ // ../../adapters/web/src/build-runtime.ts
2582
+ import { silentDiagnostics as silentDiagnostics4 } from "../_shared/diagnostics.js";
2583
+ function buildRuntime(options) {
2584
+ const normalized = {
2585
+ ...options,
2586
+ ...resolveAdapterCommonOptions(options, "PolymorphicElement", silentDiagnostics4)
2587
+ };
2588
+ const { filterProps: customFilter, enforcement } = normalized;
2589
+ const { runtime, ownedKeys } = buildCoreRuntime(normalized);
2590
+ const { childrenEvaluator } = buildEngines(
2591
+ normalized.diagnostics,
2592
+ enforcement?.children,
2593
+ normalized.name
2594
+ );
2595
+ const filterProps = composeFilter(ownedKeys, customFilter);
2596
+ return {
2597
+ runtime,
2598
+ filterProps,
2599
+ diagnostics: normalized.diagnostics,
2600
+ ...childrenEvaluator !== void 0 && { childrenEvaluator }
2601
+ };
2602
+ }
2603
+
2604
+ // ../../adapters/web/src/render-to-string.ts
2605
+ var ssrRegistry = /* @__PURE__ */ new WeakMap();
2606
+ function registerForSsr(cls, bundle) {
2607
+ ssrRegistry.set(cls, { bundle });
2608
+ }
2609
+ function renderToString(component, props = {}, innerHTML = "") {
2610
+ const entry = ssrRegistry.get(component);
2611
+ if (!entry) {
2612
+ const name = component.name ?? "AnonymousComponent";
2613
+ throw new Error(
2614
+ `[renderToString] ${name} was not registered for SSR. Ensure it was created with createContractComponent from @praxis-kit/web.`
2615
+ );
2616
+ }
2617
+ return renderBundleToString(entry.bundle, props, innerHTML);
2618
+ }
2619
+
2620
+ // ../../adapters/web/src/create-contract-component.ts
2386
2621
  function createContractComponent(options) {
2387
2622
  const bundle = buildRuntime(options);
2388
2623
  const looseBundle = toLooseBundle(bundle);
@@ -2417,16 +2652,23 @@ function createContractComponent(options) {
2417
2652
  }
2418
2653
  _applyPraxis() {
2419
2654
  const self = this._self;
2420
- if (bundle.childrenEvaluator) {
2421
- bundle.childrenEvaluator.evaluate(Array.from(this.childNodes));
2655
+ const {
2656
+ childrenEvaluator,
2657
+ runtime: { options: options2, resolveTag: resolveTag2 }
2658
+ } = bundle;
2659
+ const tag = resolveTag2(self.as);
2660
+ const children = Array.from(this.childNodes);
2661
+ if (childrenEvaluator) {
2662
+ childrenEvaluator.evaluate(children);
2422
2663
  }
2664
+ options2.htmlChildrenEvaluatorFn?.(tag)?.evaluate(children);
2423
2665
  const observedSet = new Set(
2424
2666
  this.constructor.observedAttributes ?? []
2425
2667
  );
2426
2668
  const props = {};
2427
2669
  for (const attr of Array.from(this.attributes)) {
2428
2670
  if (attr.name === "class" || observedSet.has(attr.name)) continue;
2429
- props[attr.name] = attr.value;
2671
+ props[attr.name] = attr.name === "disabled" ? true : attr.value;
2430
2672
  }
2431
2673
  props["as"] = self.as ?? this.getAttribute("as") ?? void 0;
2432
2674
  props["recipe"] = self.recipe ?? this.getAttribute("variant-key") ?? void 0;
@@ -2435,7 +2677,7 @@ function createContractComponent(options) {
2435
2677
  const val = self[key] ?? this.getAttribute(key);
2436
2678
  if (val != null) props[key] = val;
2437
2679
  }
2438
- applyHostState(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2680
+ diffAndApplyAttributes(this, resolveHostState(looseBundle, props), this._pipelineAttrs, props);
2439
2681
  }
2440
2682
  }
2441
2683
  if (options.name) {