praxis-kit 0.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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/_shared/diagnostics.d.ts +312 -0
  4. package/dist/_shared/diagnostics.js +360 -0
  5. package/dist/build-runtime-CJ_nQEaZ.js +5065 -0
  6. package/dist/codemod/index.d.ts +2 -0
  7. package/dist/codemod/index.js +176520 -0
  8. package/dist/contract/index.d.ts +677 -0
  9. package/dist/contract/index.js +341 -0
  10. package/dist/eslint/index.d.ts +90 -0
  11. package/dist/eslint/index.js +1047 -0
  12. package/dist/guards/index.d.ts +78 -0
  13. package/dist/guards/index.js +118 -0
  14. package/dist/html/index.d.ts +151 -0
  15. package/dist/html/index.js +1244 -0
  16. package/dist/index-BIBd_iPD.d.ts +951 -0
  17. package/dist/lit/index.d.ts +862 -0
  18. package/dist/lit/index.js +4893 -0
  19. package/dist/preact/index.d.ts +796 -0
  20. package/dist/preact/index.js +5043 -0
  21. package/dist/react/index.d.ts +28 -0
  22. package/dist/react/index.js +205 -0
  23. package/dist/react/legacy.d.ts +29 -0
  24. package/dist/react/legacy.js +80 -0
  25. package/dist/solid/index.d.ts +728 -0
  26. package/dist/solid/index.js +4821 -0
  27. package/dist/svelte/Polymorphic.svelte +190 -0
  28. package/dist/svelte/_polymorphic-runtime.d.ts +102 -0
  29. package/dist/svelte/_polymorphic-runtime.js +371 -0
  30. package/dist/svelte/index.d.ts +994 -0
  31. package/dist/svelte/index.js +4482 -0
  32. package/dist/tailwind/index.d.ts +197 -0
  33. package/dist/tailwind/index.js +767 -0
  34. package/dist/tailwind/safelist.css +20 -0
  35. package/dist/ts-plugin/index.cjs +166 -0
  36. package/dist/ts-plugin/index.d.cts +9 -0
  37. package/dist/utils/index.d.ts +19 -0
  38. package/dist/utils/index.js +21 -0
  39. package/dist/vite-plugin/index.d.ts +200 -0
  40. package/dist/vite-plugin/index.js +2106 -0
  41. package/dist/vue/index.d.ts +729 -0
  42. package/dist/vue/index.js +4945 -0
  43. package/dist/web/index.d.ts +832 -0
  44. package/dist/web/index.js +4868 -0
  45. package/package.json +258 -0
@@ -0,0 +1,190 @@
1
+ <!--
2
+ @component
3
+ Renders a `createContractComponent` bundle. Every praxis-kit component in the Svelte adapter
4
+ is a bundle passed to this component via the `bundle` prop:
5
+
6
+ ```svelte
7
+ <Polymorphic {bundle} intent="ghost" as="a" href="/home">Home</Polymorphic>
8
+ ```
9
+
10
+ Resolves the tag (`as` or the bundle's default), variant classes, filtered props, and ARIA
11
+ attributes, then renders the result via `<svelte:element>` — or, with `asChild`, renders
12
+ `children` as a snippet receiving the resolved props instead of a host element.
13
+ -->
14
+ <script module lang="ts">
15
+ declare const process: { env: { NODE_ENV: string } }
16
+ </script>
17
+
18
+ <script lang="ts">
19
+ import { enforceAllowedAs, isKnownAriaRole } from './_polymorphic-runtime.js'
20
+ import type { ElementType, IntrinsicProps } from './_polymorphic-runtime.js'
21
+ import { isObject, isString } from './_polymorphic-runtime.js'
22
+ import { applyFilter, resolveNormalizedProps } from './_polymorphic-runtime.js'
23
+ import type { Snippet } from 'svelte'
24
+ import type {
25
+ PolymorphicComponentProps,
26
+ ResolvedAttributes,
27
+ StyleObject,
28
+ UnknownProps,
29
+ } from './index.js'
30
+
31
+ let {
32
+ bundle,
33
+ as: asProp,
34
+ asChild,
35
+ class: cls,
36
+ recipe,
37
+ children,
38
+ ...rest
39
+ }: PolymorphicComponentProps = $props()
40
+ let hostEl: Element | undefined = $state()
41
+
42
+ // Svelte 5 event delegation requires lowercase handler names (onclick, onfocus…). This is a
43
+ // deliberate, documented compatibility feature — not an accident of the regex — so a bundle's
44
+ // caller can write React-style camelCase (onClick, onPointerDown) and it reaches
45
+ // <svelte:element> as the native lowercase name Svelte's runtime binds via addEventListener.
46
+ //
47
+ // The contract only covers camelCase→lowercase for keys already shaped like `onXxx`; every
48
+ // "on"-prefixed key, normalized or not, is still treated as event-related by Svelte's own
49
+ // attribute-spreading runtime (a non-function value is silently dropped, not rendered as a
50
+ // literal attribute) — including a component-level "callback prop" that happens to start with
51
+ // "on" (`onValueChange`), which becomes a dead listener rather than a plain callback. See
52
+ // `DECISIONS.md` → "`adapters/svelte` — the event-normalization contract" and
53
+ // `event-normalization.test.ts` for the exact pinned cases.
54
+ const EVENT_RE = /^on[A-Z]/
55
+ function normalizeEventKeys(props: UnknownProps): UnknownProps {
56
+ const out: ResolvedAttributes = {}
57
+ for (const k in props) {
58
+ out[EVENT_RE.test(k) ? k.toLowerCase() : k] = (props as ResolvedAttributes)[k]
59
+ }
60
+ return out as UnknownProps
61
+ }
62
+
63
+ // key.replace(/([A-Z])/g, '-$1') camelCase→kebab-case is also what makes a CSS custom property
64
+ // (`'--my-color'`) pass through untouched — it has no uppercase letters to rewrite — and what
65
+ // makes a vendor-prefixed key (`WebkitLineClamp`) come out correctly hyphenated
66
+ // (`-webkit-line-clamp`, a leading dash and all — that IS the real CSS property name). Both are
67
+ // asserted by test, not left as an implicit property of the regex. `value == null` (not
68
+ // `=== undefined`) skips both `null` and `undefined` values but keeps a falsy `0`.
69
+ function serializeStyle(style: StyleObject): string {
70
+ let result = ''
71
+ for (const key in style) {
72
+ const value = style[key]
73
+ if (value == null) continue
74
+ if (result) result += ';'
75
+ result += `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}:${value}`
76
+ }
77
+ return result
78
+ }
79
+
80
+ function buildDomProps(
81
+ props: UnknownProps,
82
+ classStr: string | undefined,
83
+ tag: ElementType,
84
+ normalizedProps: UnknownProps,
85
+ ): ResolvedAttributes {
86
+ const { role, style, ...r } = normalizeEventKeys(props)
87
+ const styleStr = isObject(style, true)
88
+ ? serializeStyle(style as StyleObject)
89
+ : (style as string | undefined)
90
+ const ep: IntrinsicProps = {
91
+ ...(r as IntrinsicProps),
92
+ class: classStr,
93
+ ...(styleStr !== undefined && { style: styleStr }),
94
+ }
95
+ if (isKnownAriaRole(role)) ep.role = role
96
+ if (!isString(tag)) return ep as ResolvedAttributes
97
+ return bundle.runtime.resolveAria(tag, ep, normalizedProps as IntrinsicProps)
98
+ .props as ResolvedAttributes
99
+ }
100
+
101
+ // Unlike buildDomProps above, this intentionally skips normalizeEventKeys and style
102
+ // serialization — the asChild path hands props straight to a caller-authored snippet, which
103
+ // spreads them onto its own element via ordinary JSX/attribute semantics, not through
104
+ // <svelte:element>'s own attribute application; event-handler keys keep their caller-authored
105
+ // casing (`onClick`, not lowercased to `onclick`), and `style` passes through however the
106
+ // caller wrote it (object or string), unserialized. See `ResolvedSlotProps<G>`
107
+ // (types/resolved-slot-props.ts) for the type this produces — it deliberately omits `style`
108
+ // rather than asserting either shape, for this exact reason.
109
+ function buildSlotProps(props: UnknownProps, classStr: string | undefined): UnknownProps {
110
+ const { role, ...r } = props
111
+ return {
112
+ ...r,
113
+ class: classStr,
114
+ ...(isKnownAriaRole(role) && { role }),
115
+ }
116
+ }
117
+
118
+ const tag = $derived(bundle.runtime.resolveTag(asProp as ElementType | undefined))
119
+ const mergedProps = $derived(bundle.runtime.resolveProps(rest as UnknownProps))
120
+ const normalizedProps = $derived.by(() => {
121
+ const { runtime: { options } } = bundle
122
+ // Folded into this derived (rather than a standalone one) so it's guaranteed to run on
123
+ // both SSR and DOM — $derived is lazy in Svelte 5 and only evaluates when read; this one
124
+ // is read downstream by resolvedClass/filteredProps/domProps, which the template renders.
125
+ if (options.allowedAs !== undefined) {
126
+ enforceAllowedAs(
127
+ tag,
128
+ options.allowedAs,
129
+ options.diagnostics,
130
+ options.displayName,
131
+ )
132
+ }
133
+ return resolveNormalizedProps(options, tag, mergedProps)
134
+ })
135
+ const resolvedClass = $derived(
136
+ bundle.runtime.resolveClasses(tag, normalizedProps, cls as string | undefined, recipe),
137
+ )
138
+ const filteredProps = $derived(
139
+ applyFilter(normalizedProps, bundle.filterProps, bundle.runtime.options.variantKeys),
140
+ )
141
+ const domProps = $derived(buildDomProps(filteredProps, resolvedClass, tag, normalizedProps))
142
+
143
+ // Resolves whether to render as child slot; also enforces as+asChild mutual exclusion.
144
+ const useAsChild = $derived.by(() => {
145
+ if (!asChild) return false
146
+ if (asProp !== undefined) {
147
+ bundle.slotValidator.assertExclusive()
148
+ return false
149
+ }
150
+ return true
151
+ })
152
+
153
+ // DOM-only (like Lit skipping htmlChildrenEvaluatorFn for its SSR renderToString). Merely
154
+ // *registering* $effect during svelte/server's render() throws ("effect_orphan") — it's not
155
+ // enough to no-op inside the callback, the rune call itself must never happen during SSR.
156
+ // Reads real child nodes off the mounted host, same approach as Lit's Array.from(this.childNodes).
157
+ // Not reachable in the asChild branch — no host element there.
158
+ if (typeof document !== 'undefined') {
159
+ $effect(() => {
160
+ if (process.env.NODE_ENV === 'production' || !hostEl) return
161
+ const childArray = Array.from(hostEl.childNodes)
162
+ bundle.childrenEvaluator?.evaluate(childArray, { tag, props: normalizedProps })
163
+ bundle.runtime.options.htmlChildrenEvaluatorFn
164
+ ?.(tag)
165
+ ?.evaluate(childArray, { tag, props: normalizedProps })
166
+ })
167
+
168
+ const onElement = $derived(bundle.onElement)
169
+
170
+ // Unlike the effect above, this runs in every environment (not dev-only) — onElement is a
171
+ // real runtime feature, not a diagnostic. Re-runs (cleaning up the previous call first, via
172
+ // the returned teardown) whenever hostEl changes identity, e.g. the resolved tag changes and
173
+ // Svelte mounts a new host element.
174
+ $effect(() => {
175
+ if (!hostEl) return
176
+ const cleanup = onElement?.(hostEl, () => normalizedProps)
177
+ return () => cleanup?.()
178
+ })
179
+ }
180
+ </script>
181
+
182
+ {#if useAsChild}
183
+ {#if children}
184
+ {@render (children as Snippet<[UnknownProps]>)(buildSlotProps(filteredProps, resolvedClass))}
185
+ {/if}
186
+ {:else}
187
+ <svelte:element this={tag as string} bind:this={hostEl} {...domProps}>
188
+ {@render (children as Snippet | undefined)?.()}
189
+ </svelte:element>
190
+ {/if}
@@ -0,0 +1,102 @@
1
+ import "clsx";
2
+ import { DiagnosticCode, Diagnostics } from "../_shared/diagnostics.js";
3
+ import "type-fest";
4
+ //#region ../../lib/foundation/src/string-map.d.ts
5
+ /**
6
+ * A string-keyed object whose values are of type `T`.
7
+ */
8
+ type StringMap<T = unknown> = Record<string, T>;
9
+ /**
10
+ * A string-keyed object with values of unknown type.
11
+ */
12
+ type AnyRecord = StringMap<unknown>;
13
+ //#endregion
14
+ //#region ../../lib/foundation/src/type-guards.d.ts
15
+ export declare function isString(value: unknown): value is string;
16
+ export declare function isObject(value: unknown, excludeArrays: true): value is AnyRecord;
17
+ export declare function isObject(value: unknown, excludeArrays?: false): value is object;
18
+ //#endregion
19
+ //#region ../../lib/primitive/src/types/intrinsic-tag.d.ts
20
+ type IntrinsicTag = keyof HTMLElementTagNameMap;
21
+ //#endregion
22
+ //#region ../../lib/primitive/src/types/element-type.d.ts
23
+ type ElementType = IntrinsicTag | (string & {});
24
+ //#endregion
25
+ //#region ../../lib/primitive/src/constants/aria/known-aria-roles.d.ts
26
+ declare const KNOWN_ARIA_ROLES: readonly ["alert", "alertdialog", "application", "article", "banner", "blockquote", "button", "caption", "cell", "checkbox", "code", "columnheader", "combobox", "complementary", "contentinfo", "definition", "deletion", "dialog", "document", "emphasis", "feed", "figure", "form", "generic", "grid", "gridcell", "group", "heading", "img", "insertion", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "meter", "navigation", "none", "note", "option", "paragraph", "presentation", "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", "searchbox", "separator", "slider", "spinbutton", "status", "strong", "subscript", "superscript", "switch", "tab", "table", "tablist", "tabpanel", "term", "textbox", "time", "timer", "toolbar", "tooltip", "tree", "treegrid", "treeitem"];
27
+ type KnownAriaRole = (typeof KNOWN_ARIA_ROLES)[number];
28
+ //#endregion
29
+ //#region ../../lib/primitive/src/types/primitives/index.d.ts
30
+ type AriaRole = KnownAriaRole | (string & {});
31
+ type IntrinsicProps = AnyRecord & {
32
+ role?: AriaRole;
33
+ };
34
+ //#endregion
35
+ //#region ../../lib/primitive/src/types/factory/prop-normalizer.d.ts
36
+ type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
37
+ //#endregion
38
+ //#region ../../lib/primitive/src/types/factory/factory-options.d.ts
39
+ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
40
+ normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
41
+ }['normalize'];
42
+ //#endregion
43
+ //#region ../../lib/primitive/src/guards/aria/is-known-aria-role.d.ts
44
+ export declare function isKnownAriaRole(value: unknown): value is KnownAriaRole;
45
+ //#endregion
46
+ //#region ../core/src/resolver/resolver.d.ts
47
+ export declare function enforceAllowedAs(tag: ElementType, allowedAs: readonly ElementType[], diagnostics: Diagnostics | undefined, displayName?: string): void;
48
+ //#endregion
49
+ //#region ../../lib/adapter-utils/src/types/filter-predicate.d.ts
50
+ /**
51
+ * Determines whether a prop should be stripped before forwarding to the
52
+ * rendered element.
53
+ *
54
+ * Returning `true` excludes the prop from the output; returning `false`
55
+ * keeps it. This is the inverse polarity of `shouldForwardProp`-style
56
+ * predicates (Emotion/styled-components), where `true` means include.
57
+ *
58
+ * @param key - The prop name being evaluated.
59
+ * @param variantKeys - The set of configured variant prop names.
60
+ * @returns `true` to strip the prop; `false` to forward it.
61
+ */
62
+ type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
63
+ //#endregion
64
+ //#region ../../lib/adapter-utils/src/props/apply-filter.d.ts
65
+ export declare function applyFilter(props: Readonly<AnyRecord>, filterProps: FilterPredicate, variantKeys: ReadonlySet<string>): AnyRecord;
66
+ //#endregion
67
+ //#region ../../lib/adapter-utils/src/props/resolve-normalized-props.d.ts
68
+ /**
69
+ * The subset of the resolved runtime options that {@link resolveNormalizedProps}
70
+ * reads. Kept structural so every adapter's own `runtime.options` type satisfies
71
+ * it without a shared nominal import.
72
+ */
73
+ interface NormalizeCapableOptions {
74
+ readonly htmlPropNormalizersFn?: ((tag: ElementType) => readonly PropNormalizer[] | undefined) | undefined;
75
+ readonly normalizeFn?: NormalizeFn | undefined;
76
+ }
77
+ /**
78
+ * The single canonical prop-normalization step for every render path — the five
79
+ * VDOM adapters (React, Preact, Vue, Solid, Svelte) and the host-state path
80
+ * shared by Lit, Web, and SSR.
81
+ *
82
+ * Ordering is fixed and load-bearing:
83
+ *
84
+ * ```text
85
+ * mergedProps → HTML built-in normalizers → normalizeFn
86
+ * ```
87
+ *
88
+ * `normalizeFn` is the primitive's composed `enforcement.props` normalizers plus
89
+ * the caller's `normalize` option (folded together by `composeNormalizers`).
90
+ * Running it last means a caller's `normalize` always observes — and can
91
+ * override — an HTML built-in's output for the same key. This must be identical
92
+ * across adapters: the same component with the same props has to normalize the
93
+ * same way whether it renders through React or through SSR.
94
+ *
95
+ * `mergedProps` must already be the result of `runtime.resolveProps(rest)`. The
96
+ * input object is never mutated; a copy is taken only when an HTML normalizer
97
+ * actually runs — most tags have none (`htmlPropNormalizersFn` returns
98
+ * `undefined` for every non-form element).
99
+ */
100
+ export declare function resolveNormalizedProps(options: NormalizeCapableOptions, tag: ElementType, mergedProps: AnyRecord): AnyRecord;
101
+ //#endregion
102
+ export type { ElementType, IntrinsicProps };
@@ -0,0 +1,371 @@
1
+ import { DiagnosticCategory, DiagnosticCode } from "../_shared/diagnostics.js";
2
+ //#region ../../lib/foundation/src/iterate.ts
3
+ function find(iterable, callback) {
4
+ for (const value of iterable) {
5
+ const result = callback(value);
6
+ if (result != null) return result;
7
+ }
8
+ return null;
9
+ }
10
+ function some(iterable, predicate) {
11
+ for (const value of iterable) if (predicate(value)) return true;
12
+ return false;
13
+ }
14
+ function every(iterable, predicate) {
15
+ let index = 0;
16
+ for (const value of iterable) if (!predicate(value, index++)) return false;
17
+ return true;
18
+ }
19
+ function* filter(iterable, predicate) {
20
+ let index = 0;
21
+ for (const value of iterable) if (predicate(value, index++)) yield value;
22
+ }
23
+ function* map(iterable, callback) {
24
+ let index = 0;
25
+ for (const value of iterable) yield callback(value, index++);
26
+ }
27
+ function forEach(iterable, callback) {
28
+ let index = 0;
29
+ for (const value of iterable) callback(value, index++);
30
+ }
31
+ function reduce(iterable, initial, callback) {
32
+ let accumulator = initial;
33
+ let index = 0;
34
+ for (const value of iterable) accumulator = callback(accumulator, value, index++);
35
+ return accumulator;
36
+ }
37
+ /**
38
+ * Transforms an iterable into a Record.
39
+ *
40
+ * The callback returns a `[key, value]` tuple for each element. Returning
41
+ * `null` aborts the collection and causes `collect()` to return `null`.
42
+ */
43
+ function collect(iterable, callback) {
44
+ const result = {};
45
+ let index = 0;
46
+ for (const value of iterable) {
47
+ const entry = callback(value, index++);
48
+ if (entry === null) return null;
49
+ result[entry[0]] = entry[1];
50
+ }
51
+ return result;
52
+ }
53
+ function findLast(value, callback) {
54
+ for (let index = value.length - 1; index >= 0; index--) {
55
+ const result = callback(value[index], index);
56
+ if (result != null) return result;
57
+ }
58
+ return null;
59
+ }
60
+ function* items(collection) {
61
+ for (let i = 0; i < collection.length; i++) {
62
+ const item = collection.item(i);
63
+ if (item !== null) yield item;
64
+ }
65
+ }
66
+ function nodeList(list) {
67
+ return { *[Symbol.iterator]() {
68
+ for (let i = 0; i < list.length; i++) {
69
+ const node = list.item(i);
70
+ if (node !== null) yield node;
71
+ }
72
+ } };
73
+ }
74
+ function mapEntries(m) {
75
+ return m.entries();
76
+ }
77
+ function set(s) {
78
+ return s.values();
79
+ }
80
+ function hasOwn(object, key) {
81
+ return Object.hasOwn(object, key);
82
+ }
83
+ function* entries(object) {
84
+ for (const key in object) {
85
+ if (!hasOwn(object, key)) continue;
86
+ yield [key, object[key]];
87
+ }
88
+ }
89
+ function* keys(object) {
90
+ for (const [key] of entries(object)) yield key;
91
+ }
92
+ function* values(object) {
93
+ for (const [, value] of entries(object)) yield value;
94
+ }
95
+ function mapValues(object, callback) {
96
+ const result = {};
97
+ for (const [key, value] of entries(object)) result[key] = callback(value, key);
98
+ return result;
99
+ }
100
+ function forEachEntry(object, callback) {
101
+ for (const [key, value] of entries(object)) callback(key, value);
102
+ }
103
+ function forEachKey(object, callback) {
104
+ for (const key of keys(object)) callback(key);
105
+ }
106
+ function forEachValue(object, callback) {
107
+ for (const value of values(object)) callback(value);
108
+ }
109
+ function forEachSet(s, callback) {
110
+ for (const value of s) callback(value);
111
+ }
112
+ const iterate = Object.freeze({
113
+ entries,
114
+ filter,
115
+ find,
116
+ findLast,
117
+ forEach,
118
+ forEachEntry,
119
+ forEachKey,
120
+ forEachSet,
121
+ forEachValue,
122
+ items,
123
+ keys,
124
+ map,
125
+ mapEntries,
126
+ mapValues,
127
+ nodeList,
128
+ reduce,
129
+ collect,
130
+ set,
131
+ some,
132
+ every,
133
+ values
134
+ });
135
+ //#endregion
136
+ //#region ../../lib/foundation/src/type-guards.ts
137
+ function isString(value) {
138
+ return typeof value === "string";
139
+ }
140
+ function isObject(value, excludeArrays = false) {
141
+ if (value === null || typeof value !== "object") return false;
142
+ return excludeArrays ? !Array.isArray(value) : true;
143
+ }
144
+ //#endregion
145
+ //#region ../../lib/primitive/src/constants/aria/known-aria-roles.ts
146
+ const KNOWN_ARIA_ROLES = Object.freeze([
147
+ "alert",
148
+ "alertdialog",
149
+ "application",
150
+ "article",
151
+ "banner",
152
+ "blockquote",
153
+ "button",
154
+ "caption",
155
+ "cell",
156
+ "checkbox",
157
+ "code",
158
+ "columnheader",
159
+ "combobox",
160
+ "complementary",
161
+ "contentinfo",
162
+ "definition",
163
+ "deletion",
164
+ "dialog",
165
+ "document",
166
+ "emphasis",
167
+ "feed",
168
+ "figure",
169
+ "form",
170
+ "generic",
171
+ "grid",
172
+ "gridcell",
173
+ "group",
174
+ "heading",
175
+ "img",
176
+ "insertion",
177
+ "link",
178
+ "list",
179
+ "listbox",
180
+ "listitem",
181
+ "log",
182
+ "main",
183
+ "marquee",
184
+ "math",
185
+ "menu",
186
+ "menubar",
187
+ "menuitem",
188
+ "menuitemcheckbox",
189
+ "menuitemradio",
190
+ "meter",
191
+ "navigation",
192
+ "none",
193
+ "note",
194
+ "option",
195
+ "paragraph",
196
+ "presentation",
197
+ "progressbar",
198
+ "radio",
199
+ "radiogroup",
200
+ "region",
201
+ "row",
202
+ "rowgroup",
203
+ "rowheader",
204
+ "scrollbar",
205
+ "search",
206
+ "searchbox",
207
+ "separator",
208
+ "slider",
209
+ "spinbutton",
210
+ "status",
211
+ "strong",
212
+ "subscript",
213
+ "superscript",
214
+ "switch",
215
+ "tab",
216
+ "table",
217
+ "tablist",
218
+ "tabpanel",
219
+ "term",
220
+ "textbox",
221
+ "time",
222
+ "timer",
223
+ "toolbar",
224
+ "tooltip",
225
+ "tree",
226
+ "treegrid",
227
+ "treeitem"
228
+ ]);
229
+ const KNOWN_ARIA_ROLES_SET = new Set(KNOWN_ARIA_ROLES);
230
+ //#endregion
231
+ //#region ../../lib/primitive/src/guards/aria/is-known-aria-role.ts
232
+ function isKnownAriaRole(value) {
233
+ return isString(value) && KNOWN_ARIA_ROLES_SET.has(value);
234
+ }
235
+ //#endregion
236
+ //#region ../../lib/contract/src/diagnostics/contract.ts
237
+ const ContractDiagnostics = {
238
+ unexpectedChild(typeName, index, context) {
239
+ return {
240
+ code: DiagnosticCode.UnexpectedChild,
241
+ category: DiagnosticCategory.Contract,
242
+ component: context,
243
+ message: `${context}: unexpected child "${typeName}" at index ${index}.`
244
+ };
245
+ },
246
+ ambiguousChild(typeName, index, ruleNames, context) {
247
+ const quoted = ruleNames.map((n) => `"${n}"`).join(" and ");
248
+ return {
249
+ code: DiagnosticCode.AmbiguousChild,
250
+ category: DiagnosticCategory.Contract,
251
+ component: context,
252
+ message: `${context}: child "${typeName}" at index ${index} matches multiple child rules: ${quoted}.`
253
+ };
254
+ },
255
+ cardinalityMin(ruleName, min, context) {
256
+ return {
257
+ code: DiagnosticCode.CardinalityMin,
258
+ category: DiagnosticCategory.Contract,
259
+ component: context,
260
+ message: `${context}: "${ruleName}" requires at least ${min}.`
261
+ };
262
+ },
263
+ cardinalityMax(ruleName, max, context) {
264
+ return {
265
+ code: DiagnosticCode.CardinalityMax,
266
+ category: DiagnosticCategory.Contract,
267
+ component: context,
268
+ message: `${context}: "${ruleName}" allows at most ${max}.`
269
+ };
270
+ },
271
+ positionViolation(ruleName, position, index, context) {
272
+ return {
273
+ code: DiagnosticCode.PositionViolation,
274
+ category: DiagnosticCategory.Contract,
275
+ component: context,
276
+ message: `${context}: "${ruleName}" must be ${position}, got index ${index}`
277
+ };
278
+ },
279
+ unknownVariantDim(component, label, dim) {
280
+ return {
281
+ code: DiagnosticCode.ContractUnknownVariantDim,
282
+ category: DiagnosticCategory.Contract,
283
+ message: `${component}: ${label} references unknown variant "${dim}".`
284
+ };
285
+ },
286
+ unknownVariantValue(component, label, dim, value, valid) {
287
+ return {
288
+ code: DiagnosticCode.ContractUnknownVariantValue,
289
+ category: DiagnosticCategory.Contract,
290
+ message: `${component}: ${label} sets "${dim}" to unknown value "${value}" (valid: ${valid.join(", ")}).`
291
+ };
292
+ },
293
+ unknownRecipeKey(component, key) {
294
+ return {
295
+ code: DiagnosticCode.ContractUnknownRecipeKey,
296
+ category: DiagnosticCategory.Contract,
297
+ message: `${component}: unknown recipeKey "${key}" — no preset with that name exists.`
298
+ };
299
+ },
300
+ invalidVariantValue(component, key, value) {
301
+ return {
302
+ code: DiagnosticCode.ContractInvalidVariantValue,
303
+ category: DiagnosticCategory.Contract,
304
+ message: `${component}: variant "${key}=${value}" is not a defined value for the "${key}" dimension.`
305
+ };
306
+ },
307
+ allowedAsViolation(tag, allowedAs, component) {
308
+ const allowed = allowedAs.map((t) => `"${String(t)}"`).join(", ");
309
+ return {
310
+ code: DiagnosticCode.AllowedAsViolation,
311
+ category: DiagnosticCategory.Contract,
312
+ component,
313
+ message: `<${component}>: "as" prop received "${tag}" but only [${allowed}] are allowed.`
314
+ };
315
+ }
316
+ };
317
+ //#endregion
318
+ //#region ../core/src/resolver/resolver.ts
319
+ function enforceAllowedAs(tag, allowedAs, diagnostics, displayName) {
320
+ if (allowedAs.includes(tag)) return;
321
+ if (!diagnostics) return;
322
+ const component = displayName ?? String(tag);
323
+ diagnostics.error(ContractDiagnostics.allowedAsViolation(String(tag), allowedAs, component));
324
+ }
325
+ //#endregion
326
+ //#region ../../lib/adapter-utils/src/props/apply-filter.ts
327
+ function applyFilter(props, filterProps, variantKeys) {
328
+ const out = {};
329
+ iterate.forEachEntry(props, (k) => {
330
+ if (!Object.hasOwn(props, k)) return;
331
+ if (filterProps(k, variantKeys)) return;
332
+ out[k] = props[k];
333
+ });
334
+ return out;
335
+ }
336
+ //#endregion
337
+ //#region ../../lib/adapter-utils/src/props/resolve-normalized-props.ts
338
+ /**
339
+ * The single canonical prop-normalization step for every render path — the five
340
+ * VDOM adapters (React, Preact, Vue, Solid, Svelte) and the host-state path
341
+ * shared by Lit, Web, and SSR.
342
+ *
343
+ * Ordering is fixed and load-bearing:
344
+ *
345
+ * ```text
346
+ * mergedProps → HTML built-in normalizers → normalizeFn
347
+ * ```
348
+ *
349
+ * `normalizeFn` is the primitive's composed `enforcement.props` normalizers plus
350
+ * the caller's `normalize` option (folded together by `composeNormalizers`).
351
+ * Running it last means a caller's `normalize` always observes — and can
352
+ * override — an HTML built-in's output for the same key. This must be identical
353
+ * across adapters: the same component with the same props has to normalize the
354
+ * same way whether it renders through React or through SSR.
355
+ *
356
+ * `mergedProps` must already be the result of `runtime.resolveProps(rest)`. The
357
+ * input object is never mutated; a copy is taken only when an HTML normalizer
358
+ * actually runs — most tags have none (`htmlPropNormalizersFn` returns
359
+ * `undefined` for every non-form element).
360
+ */
361
+ function resolveNormalizedProps(options, tag, mergedProps) {
362
+ const htmlNormalizers = options.htmlPropNormalizersFn?.(tag);
363
+ let base = mergedProps;
364
+ if (htmlNormalizers?.length) {
365
+ base = { ...mergedProps };
366
+ for (const normalize of htmlNormalizers) Object.assign(base, normalize(base));
367
+ }
368
+ return typeof options.normalizeFn === "function" ? options.normalizeFn(base) : base;
369
+ }
370
+ //#endregion
371
+ export { applyFilter, enforceAllowedAs, isKnownAriaRole, isObject, isString, resolveNormalizedProps };