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,832 @@
1
+ import "clsx";
2
+ import { DiagnosticCode, DiagnosticInput, Diagnostics, DiagnosticsMode } from "../_shared/diagnostics.js";
3
+ import { OmitIndexSignature, ReadonlyDeep, RequireAtLeastOne, Simplify } from "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/primitive/src/types/any-record.d.ts
15
+ /**
16
+ * An object type with no named properties.
17
+ *
18
+ * Unlike `{}`, this excludes arbitrary properties during type operations while
19
+ * still satisfying `extends object`.
20
+ */
21
+ type EmptyRecord = Record<never, never>;
22
+ /**
23
+ * A compound component's named sub-components, for example
24
+ * `{ Header, Content, Footer }`.
25
+ */
26
+ type SubComponentMap = Readonly<AnyRecord>;
27
+ /**
28
+ * Default `Variants` type for components that declare no variants.
29
+ *
30
+ * Structurally identical to `Readonly<EmptyRecord>`, but named separately so
31
+ * editor hovers remain self-descriptive.
32
+ */
33
+ type NoVariants = Readonly<EmptyRecord>;
34
+ /**
35
+ * Default `TPreset` type for components that declare no named presets.
36
+ *
37
+ * Structurally identical to `Readonly<EmptyRecord>`, but named separately so
38
+ * editor hovers remain self-descriptive.
39
+ */
40
+ type NoPreset = Readonly<EmptyRecord>;
41
+ /**
42
+ * Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
43
+ * props, including the no-plugin case.
44
+ *
45
+ * Structurally identical to `EmptyRecord`, but named separately so editor
46
+ * hovers remain self-descriptive.
47
+ */
48
+ type NoPluginProps = EmptyRecord;
49
+ //#endregion
50
+ //#region ../../lib/primitive/src/types/intrinsic-tag.d.ts
51
+ type IntrinsicTag = keyof HTMLElementTagNameMap;
52
+ //#endregion
53
+ //#region ../../lib/primitive/src/types/element-type.d.ts
54
+ type ElementType = IntrinsicTag | (string & {});
55
+ /**
56
+ * Resolves a component's default tag to its real DOM interface — `HTMLDialogElement` for
57
+ * `'dialog'`, `HTMLDetailsElement` for `'details'`, and so on — falling back to `HTMLElement`
58
+ * for custom-element tags or anything not in `HTMLElementTagNameMap`. Used to type
59
+ * `FactoryOptions.onElement`'s `element` param so component authors get direct, correctly-typed
60
+ * access to tag-specific native members (`dialogEl.showModal()`) without an unsafe cast.
61
+ *
62
+ * The fallback is `HTMLElement`, not the more generic `Element` — every tag reachable through
63
+ * `IntrinsicTag` extends it, and so does every custom element per spec, so members `HTMLElement`
64
+ * itself declares (`showPopover()`/`hidePopover()`/`togglePopover()`, the `popover` attribute)
65
+ * stay directly accessible even for tags with no dedicated entry in `HTMLElementTagNameMap`.
66
+ */
67
+ type ElementForTag<TDefault extends ElementType> = TDefault extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[TDefault] : HTMLElement;
68
+ //#endregion
69
+ //#region ../../lib/primitive/src/constants/aria/known-aria-roles.d.ts
70
+ 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"];
71
+ type KnownAriaRole = (typeof KNOWN_ARIA_ROLES)[number];
72
+ //#endregion
73
+ //#region ../../lib/primitive/src/types/primitives/index.d.ts
74
+ type Booleanish = boolean | 'true' | 'false';
75
+ type ClassName = string | string[];
76
+ type NonEmptyArray<T> = [T, ...T[]];
77
+ type Numberish = number | `${number}`;
78
+ type Primitive = string | number | boolean;
79
+ type AriaRole = KnownAriaRole | (string & {});
80
+ type IntrinsicProps = AnyRecord & {
81
+ role?: AriaRole;
82
+ };
83
+ type TagMap = Partial<Record<IntrinsicTag | (string & {}), ClassName>>;
84
+ //#endregion
85
+ //#region ../../lib/primitive/src/types/contracts/cardinality.d.ts
86
+ type MinMax = {
87
+ min: number;
88
+ max: number;
89
+ };
90
+ type CardinalityInput = Partial<MinMax>;
91
+ //#endregion
92
+ //#region ../../lib/primitive/src/types/contracts/child-rule-context.d.ts
93
+ /**
94
+ * Resolved per-instance state available to a dynamic (`dynamic(...)`) child
95
+ * rule field — the same tag/props every adapter already computes before
96
+ * evaluating children, exposed so a rule can vary by them (e.g. cardinality
97
+ * that depends on the resolved `as` tag).
98
+ */
99
+ type ChildRuleContext = {
100
+ readonly tag: unknown;
101
+ readonly props: Readonly<AnyRecord>;
102
+ };
103
+ //#endregion
104
+ //#region ../../lib/primitive/src/rule/rule-brand.d.ts
105
+ declare const RULE_BRAND: unique symbol;
106
+ //#endregion
107
+ //#region ../../lib/primitive/src/types/rule/dynamic-rule.d.ts
108
+ type DynamicRule<T, C = unknown> = {
109
+ readonly [RULE_BRAND]: true;
110
+ resolve(context: C): T;
111
+ };
112
+ //#endregion
113
+ //#region ../../lib/primitive/src/types/rule/rule.d.ts
114
+ type Rule<T, C = unknown> = T | DynamicRule<T, C>;
115
+ //#endregion
116
+ //#region ../../lib/primitive/src/types/contracts/child-rule-match.d.ts
117
+ type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
118
+ //#endregion
119
+ //#region ../../lib/primitive/src/types/contracts/child-rule-position.d.ts
120
+ type ChildRulePosition = 'first' | 'last' | 'any';
121
+ //#endregion
122
+ //#region ../../lib/primitive/src/types/contracts/child-rule-input.d.ts
123
+ type ChildRuleInput<T = unknown, U extends T = T> = {
124
+ name: string;
125
+ match: ChildRuleMatch<T, U>;
126
+ /**
127
+ * Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
128
+ * the resolved tag/props (e.g. a different max depending on `as`). `match`
129
+ * stays static-only — it's already a function, so a dynamic wrapper would
130
+ * be indistinguishable from the predicate itself without one.
131
+ */
132
+ cardinality?: Rule<CardinalityInput, ChildRuleContext>;
133
+ position?: ChildRulePosition;
134
+ /**
135
+ * Optional component-type reference for O(1) dispatch index.
136
+ * When provided for every rule, the matcher reads child.type instead of
137
+ * calling every match function on every child (O(n×m) → O(n+m)).
138
+ */
139
+ type?: unknown;
140
+ };
141
+ //#endregion
142
+ //#region ../../lib/primitive/src/types/validation/valid-result.d.ts
143
+ type ValidResult = {
144
+ valid: true;
145
+ };
146
+ //#endregion
147
+ //#region ../../lib/primitive/src/types/variants/string-to-boolean.d.ts
148
+ type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
149
+ //#endregion
150
+ //#region ../../lib/primitive/src/types/variants/variant-value.d.ts
151
+ type VariantValue = string | string[];
152
+ //#endregion
153
+ //#region ../../lib/primitive/src/types/variants/variant-states.d.ts
154
+ type VariantStates<K extends string = string> = Record<K, VariantValue>;
155
+ //#endregion
156
+ //#region ../../lib/primitive/src/types/variants/variant-map.d.ts
157
+ type VariantMap<V extends string = string, K extends string = string> = Record<V, VariantStates<K>>;
158
+ //#endregion
159
+ //#region ../../lib/primitive/src/types/variants/variant-key.d.ts
160
+ type VariantKey<V extends VariantMap, K extends keyof V> = StringToBoolean<keyof V[K] & string>;
161
+ //#endregion
162
+ //#region ../../lib/primitive/src/types/variants/variant-selection.d.ts
163
+ /**
164
+ * A partial selection of variant states authored at factory definition time.
165
+ *
166
+ * Uses `keyof V[K]` directly (not `VariantKey`) so TypeScript can eagerly
167
+ * resolve the union at constraint-check time without deferred conditional types.
168
+ */
169
+ type VariantSelection<V extends VariantMap> = { [K in keyof V]?: keyof V[K]; };
170
+ //#endregion
171
+ //#region ../../lib/primitive/src/types/variants/variant-props.d.ts
172
+ /** The full optional prop surface exposed to callers for a given variant map. */
173
+ type VariantProps<V extends VariantMap> = { [K in keyof V]?: VariantKey<V, K>; };
174
+ //#endregion
175
+ //#region ../../lib/primitive/src/types/variants/default-variants.d.ts
176
+ type NormalizedVariantValue<K extends string> = string extends K ? Primitive : K extends 'true' | 'false' ? Booleanish : K extends `${number}` ? Numberish : K;
177
+ type DefaultVariants<V extends VariantMap> = { [K in keyof V]?: NormalizedVariantValue<keyof V[K] & string>; };
178
+ //#endregion
179
+ //#region ../../lib/primitive/src/types/variants/recipe-map.d.ts
180
+ /**
181
+ * A static, immutable map of named presets to partial variant selections.
182
+ *
183
+ * Presets are named bundles of variant props that callers activate by key,
184
+ * avoiding the need to repeat variant combinations at each call site.
185
+ */
186
+ type RecipeMap<V extends VariantMap = VariantMap> = Readonly<StringMap<VariantSelection<V>>>;
187
+ //#endregion
188
+ //#region ../../lib/primitive/src/types/variants/recipe-target.d.ts
189
+ type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
190
+ //#endregion
191
+ //#region ../../lib/primitive/src/types/variants/polymorphic-generics.d.ts
192
+ /**
193
+ * The framework-neutral descriptor for a single praxis-kit component's contract — every render
194
+ * mechanism (tag resolution, prop merging, classes, ARIA) and every framework adapter's
195
+ * component type is built from this one shape. Deliberately just data: five type parameters and
196
+ * their corresponding properties, with no notion of JSX, call signatures, refs, or any
197
+ * framework-specific rendering concern. Each adapter (React, Vue, Svelte, Solid, Lit, Web) builds
198
+ * its own idiomatic component type on top of a `PolymorphicGenerics<...>` instantiation — see
199
+ * `PolymorphicComponent<G>` (`adapters/react/src/shared/types/polymorphic-props.ts`) for the
200
+ * React example — rather than this interface knowing anything about any of them.
201
+ *
202
+ * Use the `*Of<T>` accessor aliases below (`DefaultOf<G>`, `PropsOf<G>`, etc.) to read a single
203
+ * field back out of an already-resolved `G`, instead of indexing `G['default']` etc. directly at
204
+ * call sites — same rationale as any accessor: the property name stays an implementation detail,
205
+ * and every reader benefits together if it ever needs to change.
206
+ */
207
+ interface PolymorphicGenerics<
208
+ /**
209
+ * The element/tag this component renders as when the consumer doesn't override it via `as`
210
+ * (`AllowedOf<G>` permitting) — e.g. `'button'`, `'div'`. Defaults to the widest `ElementType`
211
+ * so a generic `PolymorphicGenerics` reference (with nothing else specified) still compiles.
212
+ */
213
+ TDefault extends ElementType = ElementType,
214
+ /**
215
+ * The props this specific component declares — its own contract, before variants are mixed
216
+ * in. Defaults to `AnyRecord` for the same "still compiles unspecified" reason as `TDefault`.
217
+ */
218
+ Props extends AnyRecord = AnyRecord,
219
+ /**
220
+ * This component's variant definitions (e.g. `{ intent: { primary: ..., ghost: ... } }`).
221
+ * Constrained to `Readonly<VariantMap>` — not the wider `AnyRecord` — specifically so `TPreset`
222
+ * below can be expressed as `RecipeMap<Variants>` and get real per-variant-key checking,
223
+ * instead of falling back to an unconstrained `RecipeMap<VariantMap>`.
224
+ */
225
+ Variants extends Readonly<VariantMap> = Readonly<VariantMap>,
226
+ /**
227
+ * Named presets (`RecipeMap<Variants>`) — bundles of variant selections a consumer activates
228
+ * by key instead of repeating the same variant combination at every call site. Tied to
229
+ * `Variants`, not `AnyRecord`, precisely so a preset can only ever select keys/values that
230
+ * `Variants` actually defines — an invalid preset is a type error, not a silent no-op.
231
+ * Defaults to `Readonly<EmptyRecord>` (no presets), which is the common case: a component can
232
+ * have variants without necessarily defining any named presets over them, and most don't.
233
+ */
234
+ TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>,
235
+ /**
236
+ * The set of elements/tags a consumer is allowed to switch to via `as`. Defaults to the widest
237
+ * `ElementType`, under which `AllowedOf<G>` imposes no restriction at all (see
238
+ * `PolymorphicControlProps.as`'s own comment in the React adapter for the concrete effect this
239
+ * has at a component's actual call site).
240
+ */
241
+ TAllowed extends ElementType = ElementType> {
242
+ default: TDefault;
243
+ props: Props;
244
+ variants: Variants;
245
+ preset: TPreset;
246
+ allowed: TAllowed;
247
+ }
248
+ /** This component's variant definitions. See `PolymorphicGenerics`'s `Variants` parameter. */
249
+ type VariantsOf<T extends PolymorphicGenerics> = T['variants'];
250
+ /** This component's named presets. See `PolymorphicGenerics`'s `TPreset` parameter. */
251
+ type RecipeOf<T extends PolymorphicGenerics> = T['preset'];
252
+ /** This component's own declared props, before variants are mixed in. See `PolymorphicGenerics`'s
253
+ * `Props` parameter. */
254
+ type PropsOf<T extends PolymorphicGenerics> = T['props'];
255
+ //#endregion
256
+ //#region ../../lib/primitive/src/types/variants/compound/compound-variant.d.ts
257
+ type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
258
+ type CompoundVariantConditionValue<V extends VariantMap, K extends keyof V> = VariantKey<V, K> | NonEmptyArray<VariantKey<V, K>>;
259
+ type CompoundVariantConditions<V extends VariantMap> = Simplify<{ [K in keyof V]: CompoundVariantConditionValue<V, K>; }>;
260
+ type CompoundVariantRequiredConditions<V extends VariantMap> = RequireAtLeastOneIfNotEmpty<CompoundVariantConditions<V>>;
261
+ type CompoundVariantBase<V extends VariantMap> = keyof V extends never ? EmptyRecord : CompoundVariantRequiredConditions<V>;
262
+ type CompoundVariant<V extends VariantMap> = CompoundVariantBase<V> & {
263
+ class: VariantValue;
264
+ };
265
+ //#endregion
266
+ //#region ../../lib/primitive/src/types/variants/compound/cva-compounds.d.ts
267
+ interface CVACompounds<V extends VariantMap> {
268
+ compoundVariants?: readonly CompoundVariant<V>[];
269
+ }
270
+ //#endregion
271
+ //#region ../../lib/primitive/src/types/variants/compound/cva-defaults.d.ts
272
+ interface CVADefaults<V extends VariantMap> {
273
+ defaultVariants?: DefaultVariants<V>;
274
+ }
275
+ //#endregion
276
+ //#region ../../lib/primitive/src/types/variants/compound/cva-variants.d.ts
277
+ interface CVAVariants<V extends VariantMap> {
278
+ variants?: V;
279
+ }
280
+ //#endregion
281
+ //#region ../../lib/primitive/src/types/pipeline/base-class-options.d.ts
282
+ interface BaseClassOptions {
283
+ baseClassName?: ClassName;
284
+ }
285
+ //#endregion
286
+ //#region ../../lib/primitive/src/types/pipeline/class-pipeline-fn.d.ts
287
+ type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string | undefined;
288
+ //#endregion
289
+ //#region ../../lib/primitive/src/types/pipeline/recipe-options.d.ts
290
+ interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
291
+ recipeMap?: StringMap<RecipeTarget<TVariants>>;
292
+ }
293
+ //#endregion
294
+ //#region ../../lib/primitive/src/types/pipeline/tag-map-options.d.ts
295
+ interface TagMapOptions {
296
+ tagMap?: TagMap;
297
+ }
298
+ //#endregion
299
+ //#region ../../lib/primitive/src/types/pipeline/composition-options.d.ts
300
+ type CompositionOptions<TVariants extends VariantMap = VariantMap> = Simplify<TagMapOptions & RecipeOptions<TVariants>>;
301
+ //#endregion
302
+ //#region ../../lib/primitive/src/types/pipeline/cva-system-options.d.ts
303
+ type CVASystemOptions<TVariants extends VariantMap = VariantMap> = Simplify<CVAVariants<TVariants> & CVADefaults<TVariants> & CVACompounds<TVariants>>;
304
+ //#endregion
305
+ //#region ../../lib/primitive/src/types/pipeline/style-options.d.ts
306
+ type StyleOptions<TVariants extends VariantMap = VariantMap> = Simplify<BaseClassOptions & CVASystemOptions<TVariants>>;
307
+ //#endregion
308
+ //#region ../../lib/primitive/src/types/pipeline/class-pipeline-options.d.ts
309
+ type ClassPipelineOptions<TVariants extends VariantMap = VariantMap> = Simplify<StyleOptions<TVariants> & CompositionOptions<TVariants>>;
310
+ //#endregion
311
+ //#region ../../lib/primitive/src/types/class/owned-prop-keys.d.ts
312
+ type OwnedPropKeys = ReadonlySet<string>;
313
+ //#endregion
314
+ //#region ../../lib/primitive/src/types/class/class-plugin.d.ts
315
+ type ClassPlugin<TProps extends AnyRecord = EmptyRecord> = Readonly<{
316
+ pipeline: ClassPipelineFn;
317
+ ownedKeys?: OwnedPropKeys;
318
+ readonly _pluginProps?: TProps;
319
+ }>;
320
+ //#endregion
321
+ //#region ../../lib/primitive/src/types/class/class-plugin-factory.d.ts
322
+ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends VariantMap>(options: ClassPipelineOptions<V>, diagnostics: Diagnostics) => ClassPlugin<TProps>;
323
+ /** `ClassPluginFactory` with its plugin-owned-props generic erased — the common form used
324
+ * wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
325
+ * capability wiring). */
326
+ type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
327
+ type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
328
+ //#endregion
329
+ //#region ../../lib/primitive/src/types/aria-rule/aria-context.d.ts
330
+ type AriaContext = {
331
+ /**
332
+ * The intrinsic HTML tag being evaluated.
333
+ */
334
+ readonly tag: IntrinsicTag;
335
+ /**
336
+ * The implicit ARIA role associated with the intrinsic tag.
337
+ */
338
+ readonly implicitRole: AriaRole | undefined;
339
+ /**
340
+ * The effective ARIA role after considering the element's explicit
341
+ * `role` attribute or component-provided role.
342
+ */
343
+ readonly effectiveRole: string | undefined;
344
+ /**
345
+ * The component's props available to the ARIA policy engine.
346
+ */
347
+ readonly props: ReadonlyDeep<IntrinsicProps>;
348
+ /**
349
+ * Variant prop names declared by the component.
350
+ *
351
+ * The adapter uses these names to determine which props are intercepted
352
+ * before reaching the DOM. A rule asserting a fact about a real HTML
353
+ * attribute should therefore treat a key present here as a component
354
+ * variant rather than a DOM attribute.
355
+ *
356
+ * An empty set indicates no variant props are declared — the case for
357
+ * evaluations with no factory context, such as `AriaPolicyEngine.evaluate`.
358
+ */
359
+ readonly variantKeys: ReadonlySet<string>;
360
+ };
361
+ //#endregion
362
+ //#region ../../lib/primitive/src/types/aria-rule/fix-kind.d.ts
363
+ type RemoveAttributeFixKind = 'removeAttribute';
364
+ type InjectLiveFixKind = 'injectLive';
365
+ type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
366
+ //#endregion
367
+ //#region ../../lib/primitive/src/types/aria-rule/aria-fix.d.ts
368
+ type AriaFixResult = {
369
+ applied: false;
370
+ next: ReadonlyDeep<IntrinsicProps>;
371
+ } | {
372
+ applied: true;
373
+ next: ReadonlyDeep<IntrinsicProps>;
374
+ previous: ReadonlyDeep<IntrinsicProps>;
375
+ };
376
+ type AriaFix = {
377
+ readonly kind: FixKind;
378
+ /** The attribute a `'removeAttribute'`/`'injectLive'` fix targets — always set for those
379
+ * kinds, absent for kinds with no single-attribute target (`'removeRole'`, etc.). */
380
+ readonly attribute?: string;
381
+ readonly priority?: number;
382
+ readonly source?: string;
383
+ readonly apply: (context: AriaContext) => AriaFixResult;
384
+ };
385
+ //#endregion
386
+ //#region ../../lib/primitive/src/types/aria-rule/severity.d.ts
387
+ type Severity = 'error' | 'warning' | (string & {});
388
+ //#endregion
389
+ //#region ../../lib/primitive/src/types/aria-rule/aria-result.d.ts
390
+ type AriaInvalidBase<M extends string = string> = {
391
+ valid: false;
392
+ severity: Severity;
393
+ message?: M;
394
+ attribute?: string;
395
+ diagnostic?: DiagnosticInput;
396
+ };
397
+ type AriaInvalidWithFix<M extends string = string> = AriaInvalidBase<M> & {
398
+ fixable: true;
399
+ fix: AriaFix;
400
+ };
401
+ type AriaInvalidWithoutFix<M extends string = string> = AriaInvalidBase<M> & {
402
+ fixable: false;
403
+ };
404
+ type AriaInvalidResult<M extends string = string> = AriaInvalidWithFix<M> | AriaInvalidWithoutFix<M>;
405
+ type AriaResult = ValidResult | AriaInvalidResult;
406
+ //#endregion
407
+ //#region ../../lib/primitive/src/types/aria-rule/aria-rule.d.ts
408
+ type AriaRule<C extends AriaContext = AriaContext> = ((context: C) => readonly AriaResult[]) & {
409
+ readonly readsProps?: readonly string[];
410
+ readonly tags?: readonly string[];
411
+ };
412
+ //#endregion
413
+ //#region ../../lib/primitive/src/types/factory/prop-normalizer.d.ts
414
+ type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
415
+ //#endregion
416
+ //#region ../../lib/primitive/src/types/factory/enforcement-options.d.ts
417
+ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
418
+ /**
419
+ * Accepts a preset name (`'warn'`, `'throw'`, `'silent'`) or a full `Diagnostics`
420
+ * instance for custom reporting/policy. The string form needs no import from
421
+ * `@praxis-kit/diagnostics`.
422
+ */
423
+ readonly diagnostics?: Diagnostics | DiagnosticsMode;
424
+ /**
425
+ * ARIA/accessibility rules evaluated against the resolved tag and props on every render.
426
+ * Each rule is a function receiving the current context and returning zero or more
427
+ * violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
428
+ * and friends in `praxis-kit/contract`).
429
+ */
430
+ readonly aria?: readonly AriaRule[];
431
+ /**
432
+ * Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
433
+ * (`AriaRule`'s `readsProps`, fixable `AriaFix` results) but have no
434
+ * relationship to ARIA semantics — an HTML fact or a security check like a
435
+ * dangerous-URL-scheme guard, for example. Evaluated together with `aria`
436
+ * (both run through the same engine, merged into one rule set) — this is a
437
+ * separate bucket purely so a non-ARIA rule doesn't have to sit under the
438
+ * misleading `aria` name to get the machinery it needs.
439
+ */
440
+ readonly rules?: readonly AriaRule[];
441
+ /**
442
+ * Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
443
+ * least 1, at most 4 `Button` children"). Open by default — children matching no rule are
444
+ * still allowed unless `exclusiveChildren` is set.
445
+ */
446
+ readonly children?: readonly ChildRuleInput[];
447
+ /**
448
+ * When true, only children matching a `children` rule (or text, per `allowText`)
449
+ * are valid — anything else is rejected. Default: false (open — children not
450
+ * matching any rule are allowed).
451
+ */
452
+ readonly exclusiveChildren?: boolean;
453
+ /**
454
+ * When false, text/number child nodes are rejected regardless of exclusiveChildren
455
+ * or any listed rule. Default: true.
456
+ */
457
+ readonly allowText?: boolean;
458
+ /**
459
+ * Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
460
+ * run before it. Unlike `normalize`, these live in the enforcement bucket because they
461
+ * typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
462
+ */
463
+ readonly props?: readonly PropNormalizer[];
464
+ /** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
465
+ readonly allowedAs?: readonly TAllowed[];
466
+ };
467
+ //#endregion
468
+ //#region ../../lib/primitive/src/types/factory/styling-options.d.ts
469
+ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
470
+ /** Class applied to every instance regardless of variant selection. */
471
+ readonly base?: ClassName;
472
+ /**
473
+ * Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
474
+ * class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
475
+ */
476
+ readonly variants?: V;
477
+ /** Value used for a variant group when the consumer doesn't pass one explicitly. */
478
+ readonly defaults?: Partial<DefaultVariants<V>>;
479
+ /**
480
+ * Applies an extra class only when a specific *combination* of variant selections matches —
481
+ * for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
482
+ * need a class neither variant would add on its own).
483
+ */
484
+ readonly compounds?: readonly CompoundVariant<V>[];
485
+ /**
486
+ * Named bundles of variant values a component defines up front. A caller activates one by name
487
+ * through the `recipe` prop (e.g. `<Button recipe="cta">` instead of setting `intent`/`size`
488
+ * individually) — `presets` is the store, `recipe` is the selector, which is why the field and
489
+ * the prop read differently. Explicit props always win over the activated bundle. The value type
490
+ * is `RecipeMap` (see `lib/primitive/src/types/variants/recipe-map.ts`).
491
+ */
492
+ readonly presets?: TPreset;
493
+ /** Maps a resolved tag directly to a raw class string, independent of the variant system. */
494
+ readonly tags?: Readonly<TagMap>;
495
+ /**
496
+ * A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
497
+ * with its own owned props, layered on top of `variants`/`presets`/`tags`.
498
+ */
499
+ readonly plugin?: TPlugin;
500
+ /**
501
+ * A cache-key → resolved-class-string lookup for every statically-known variant
502
+ * combination, skipping runtime class computation entirely when a match is found. Normally
503
+ * generated by a build-time class-extraction plugin rather than hand-authored.
504
+ */
505
+ readonly precomputedClasses?: Readonly<StringMap<string>>;
506
+ };
507
+ //#endregion
508
+ //#region ../../lib/primitive/src/types/factory/factory-options.d.ts
509
+ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
510
+ normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
511
+ }['normalize'];
512
+ /**
513
+ * The type-erased shape of {@link FactoryOptions} — every generic parameter widened to its bound.
514
+ *
515
+ * Use it for a value that must hold *any* factory config (a registry, a generic wrapper). It
516
+ * cannot check `styling.compounds` conditions against the real variant keys/values, because it
517
+ * has forgotten what they are — for that, annotate against `FactoryOptions<...>` with the concrete
518
+ * generics (or `satisfies FactoryOptions<'button', Props, typeof variants>`), which keeps an
519
+ * invalid compound condition a type error rather than a silent no-op.
520
+ */
521
+ type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
522
+ /**
523
+ * The framework-neutral component-authoring config passed to `createContractComponent` in every
524
+ * adapter: default tag + name, own-prop defaults, a `normalize` transform, `styling` (variants,
525
+ * base classes, presets, class plugin), `enforcement` (ARIA + children contracts), `subComponents`,
526
+ * and `onElement`.
527
+ *
528
+ * `satisfies FactoryOptions<TDefault, Props, typeof variants, ...>` on a config object narrows
529
+ * `styling.compounds` conditions to the real per-variant-key shape — including resolving a
530
+ * boolean-shaped axis (`{ true, false }`) to a real `boolean` — so a condition naming a variant or
531
+ * value that does not exist is a compile error. `AnyFactoryOptions` cannot do this.
532
+ */
533
+ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType> = {
534
+ /** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
535
+ readonly tag?: TDefault;
536
+ /** Display name used in diagnostics, dev tools, and generated component naming. */
537
+ readonly name?: string;
538
+ /** Values used for the component's own (non-variant) props when the consumer omits them. */
539
+ readonly defaults?: Partial<NoInfer<Props>>;
540
+ /**
541
+ * A pure `(props) => props` transform run on every render, after `enforcement.props`'s
542
+ * normalizers see the same input. Use this for component-specific prop shaping — anything
543
+ * that depends on live instance state or the real DOM element belongs in `onElement` instead.
544
+ *
545
+ * Accepts either a single transform or an array of them, mirroring the `enforcement.props`
546
+ * array convention. An array is composed left to right — each entry receives the previous
547
+ * entry's *complete* output, not a merged patch — so unlike an `enforcement.props` normalizer
548
+ * (which returns a partial patch), a later `normalize` entry can also remove a key an earlier
549
+ * one added. An empty array is treated as no transform.
550
+ */
551
+ readonly normalize?: NormalizeFn<NoInfer<Props>> | ReadonlyArray<NormalizeFn<NoInfer<Props>>>;
552
+ /** Variant groups, base classes, presets, and the optional class-resolution plugin. */
553
+ readonly styling?: StylingOptions<V, TPreset, TPlugin>;
554
+ /** ARIA rules, child-content contracts, and other runtime validation for this component. */
555
+ readonly enforcement?: EnforcementOptions<TAllowed>;
556
+ /**
557
+ * Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
558
+ * be set directly by component authors — use `enforcement.diagnostics` to override per component.
559
+ */
560
+ readonly diagnostics?: Diagnostics;
561
+ /**
562
+ * Sub-components to attach to the generated root component, producing a
563
+ * compound component API (for example, `Card.Header`, `Card.Content`,
564
+ * and `Card.Footer`). Purely additive — has no effect on
565
+ * `enforcement.children`; author child rules explicitly if the component
566
+ * needs to validate its children.
567
+ */
568
+ readonly subComponents?: SubComponentMap;
569
+ /**
570
+ * Called once per instance, when the real underlying DOM element first
571
+ * exists, in every adapter — via that adapter's own native mount
572
+ * lifecycle, never through the props/attribute pipeline. Use this for
573
+ * wiring that needs the actual element (native imperative methods like
574
+ * `dialogEl.showModal()`, native events like `close`/`cancel` that have
575
+ * no prop-based equivalent), not for anything expressible as a plain
576
+ * prop.
577
+ *
578
+ * `element` is typed to the real DOM interface of every tag the rendered
579
+ * element could actually be — `TDefault` plus whatever `enforcement.allowed`
580
+ * permits via `as` (`HTMLDialogElement` for `tag: 'dialog'`,
581
+ * `HTMLDetailsElement` for `tag: 'details'`, and so on) — no cast needed to
582
+ * reach tag-specific members. A component that leaves `allowed`
583
+ * unconstrained (any tag reachable via `as`) falls back to `HTMLElement`,
584
+ * which still covers members every element shares (`showPopover()` and
585
+ * friends); restrict `enforcement.allowed` to the tags `onElement`
586
+ * actually knows how to handle to get real narrowing.
587
+ *
588
+ * `getProps` returns the instance's *current* resolved props at call
589
+ * time — read it from inside a listener registered once at mount, rather
590
+ * than re-subscribing on every prop change.
591
+ *
592
+ * Return a cleanup function to run when the instance unmounts.
593
+ */
594
+ readonly onElement?: (element: ElementForTag<TDefault | TAllowed>, getProps: () => Readonly<Props>) => void | (() => void);
595
+ };
596
+ //#endregion
597
+ //#region ../../adapters/web/src/types/generics.d.ts
598
+ type RuntimeG<TDefault extends ElementType, Props extends AnyRecord, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants>> = PolymorphicGenerics<TDefault, Props, Variants, TPreset>;
599
+ //#endregion
600
+ //#region ../../lib/adapter-utils/src/types/filter-predicate.d.ts
601
+ /**
602
+ * Determines whether a prop should be stripped before forwarding to the
603
+ * rendered element.
604
+ *
605
+ * Returning `true` excludes the prop from the output; returning `false`
606
+ * keeps it. This is the inverse polarity of `shouldForwardProp`-style
607
+ * predicates (Emotion/styled-components), where `true` means include.
608
+ *
609
+ * @param key - The prop name being evaluated.
610
+ * @param variantKeys - The set of configured variant prop names.
611
+ * @returns `true` to strip the prop; `false` to forward it.
612
+ */
613
+ type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
614
+ //#endregion
615
+ //#region ../../lib/adapter-utils/src/runtime/define-component.d.ts
616
+ export declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
617
+ //#endregion
618
+ //#region ../../adapters/web/src/types/web-options.d.ts
619
+ /**
620
+ * Options accepted by createContractComponent in the web adapter.
621
+ *
622
+ * Identical shape to LitFactoryOptions — a plain HTMLElement subclass with
623
+ * no framework dependency. Light DOM only; Shadow DOM is out of scope.
624
+ */
625
+ type WebFactoryOptions<TDefault extends ElementType = ElementType, TProps extends AnyRecord = EmptyRecord, TVariants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<TVariants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = FactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
626
+ readonly filterProps?: FilterPredicate;
627
+ };
628
+ //#endregion
629
+ //#region ../../adapters/web/src/types/primitives.d.ts
630
+ type UnknownProps = AnyRecord;
631
+ /**
632
+ * Constructor type returned by createContractComponent.
633
+ *
634
+ * Describes the public contract without exposing HTMLElement's internal members.
635
+ * Variant key instance properties are typed via TVariants.
636
+ *
637
+ * No `as` field, unlike an earlier design — see the `as` note on
638
+ * `createContractComponent`'s own doc comment for why: a custom element's tag is
639
+ * fixed at `customElements.define()` time, so there is no tag for `as` to switch.
640
+ *
641
+ * `G` is a phantom marker only — see `__generics` below — and defaults to the
642
+ * widest `PolymorphicGenerics` so existing two-argument usages of this type keep
643
+ * resolving exactly as before. Mirrors the Lit adapter's `LitContractComponent`.
644
+ */
645
+ type WebContractComponent<TVariants extends Readonly<VariantMap> = NoVariants, TPluginProps extends AnyRecord = EmptyRecord, G extends PolymorphicGenerics = PolymorphicGenerics> = {
646
+ new (): HTMLElement & {
647
+ recipe: string | undefined;
648
+ praxisClass: string | undefined;
649
+ /** Re-runs the pipeline — call after setting non-reactive attributes (aria-*, role, data-*)
650
+ * or a praxis-owned property directly (property assignment doesn't trigger
651
+ * attributeChangedCallback — see createContractComponent's own doc comment). */
652
+ update(): void;
653
+ } & { [K in Extract<keyof TVariants, string>]?: string | null; } & TPluginProps;
654
+ /** The resolved diagnostics for this component — usable by subclasses for custom enforcement. */
655
+ readonly diagnostics: Diagnostics;
656
+ /**
657
+ * Type-only; never assigned at runtime. `createContractComponent` erases
658
+ * `TDefault`/`TProps`/`TPreset` entirely from its return type — only `TVariants`
659
+ * and `TPluginProps` survive as real instance-shape information. This field
660
+ * carries the full `PolymorphicGenerics` the component was built from so
661
+ * `GenericsOf`/`ContractProps` (`./contract-props`) can recover it from outside
662
+ * the file that built it — identical to `LitContractComponent.__generics`.
663
+ */
664
+ readonly __generics?: G;
665
+ };
666
+ //#endregion
667
+ //#region ../../lib/contract-props/src/has-generics.d.ts
668
+ /**
669
+ * The phantom-marker shape read back via `T extends HasGenerics<infer G> ? G : never`. See the
670
+ * README for why this exists.
671
+ *
672
+ * Type-only: never assigned at runtime. In React's `PolymorphicComponent<G>`, declaring `readonly
673
+ * __generics?: G` inline (structurally matching this shape) rather than writing `HasGenerics<G> &
674
+ * { ...call signatures... }` was necessary to keep `PolymorphicComponent<any>`-typed test helpers
675
+ * assignable — confirmed directly against that adapter's own real component type (see
676
+ * `adapters/react/src/shared/types/polymorphic-props.test.ts`), not reproducible in an isolated
677
+ * minimal mock (see this file's own `has-generics.test.ts`), so treat "inline, not intersected"
678
+ * as an adapter-level implementation detail this package's marker shape must stay compatible
679
+ * with, not a property `HasGenerics<G>` itself enforces.
680
+ *
681
+ * Do **not** "harden" this with a `unique symbol` or other nominal brand: the whole point is that
682
+ * an adapter's real callable component type structurally satisfies this shape by declaring the
683
+ * same optional string-keyed field inline. Nominal purity here would break that compatibility.
684
+ */
685
+ interface HasGenerics<G> {
686
+ readonly __generics?: G;
687
+ }
688
+ //#endregion
689
+ //#region ../../adapters/web/src/types/contract-props.d.ts
690
+ /**
691
+ * Recovers a `WebContractComponent`'s `PolymorphicGenerics` descriptor from its own value type —
692
+ * identical to the Lit adapter's `GenericsOf<T>` (`adapters/lit/src/types/contract-props.ts`),
693
+ * since both adapters build a fixed-identity custom element with the same erased return type.
694
+ * Needs the phantom `__generics` marker (unlike Svelte's `GenericsOf<T>`) because
695
+ * `createContractComponent` here returns `WebContractComponent<TVariants, TPluginProps, G>`, not a
696
+ * `BuiltRuntime<G, TOptions>` — `TDefault`/`TProps`/`TPreset` are genuinely erased from the return
697
+ * type, so there is no ordinary type parameter left to `infer` them back out of.
698
+ * `WebContractComponent`'s own `__generics` field (`./primitives`) exists purely to make this
699
+ * recovery possible. Falls back to the widest `PolymorphicGenerics` for any non-praxis-kit value.
700
+ */
701
+ type GenericsOf<T extends HasGenerics<PolymorphicGenerics>> = T extends HasGenerics<infer G extends PolymorphicGenerics> ? G : PolymorphicGenerics;
702
+ /**
703
+ * A component's full prop contract — the attributes a caller can set on the custom element,
704
+ * recovered from outside the file that built it. The Web adapter has exactly one render mode (no
705
+ * `asChild`/`render` — see the "known limitations" note atop `conformance.test.ts`), so unlike
706
+ * React's/Preact's `ContractProps<T, Mode>` this takes no `Mode` parameter: there is only ever one
707
+ * prop shape to pick.
708
+ *
709
+ * `as?: never` — deliberately absent, not merely undocumented. Every VDOM adapter's `as` is real
710
+ * tag polymorphism (it changes the rendered host element); a custom element's tag is fixed at
711
+ * `customElements.define()` time, so there is nothing for `as` to do here. `createContractComponent`
712
+ * strips it from the prop pipeline entirely (see that function's own doc comment) — this `never`
713
+ * makes that a type-level fact too, so `{ as: 'a' }` written against `ContractProps<T>` is a compile
714
+ * error, not a silently-ignored no-op a caller could believe was doing something.
715
+ *
716
+ * ```ts
717
+ * const Button = createContractComponent({ tag: 'button', name: 'Button', /* ... *\/ })
718
+ *
719
+ * type ButtonProps = ContractProps<typeof Button>
720
+ * ```
721
+ */
722
+ type ContractProps<T extends HasGenerics<PolymorphicGenerics>> = Simplify<OmitIndexSignature<PropsOf<GenericsOf<T>>> & OmitIndexSignature<VariantProps<VariantsOf<GenericsOf<T>>>> & {
723
+ as?: never;
724
+ recipe?: keyof RecipeOf<GenericsOf<T>>;
725
+ }>;
726
+ //#endregion
727
+ //#region ../../adapters/web/src/create-contract-component.d.ts
728
+ /**
729
+ * Creates a plain `HTMLElement` subclass with praxis-kit contracts applied.
730
+ *
731
+ * No framework dependency. Register with `customElements.define()`:
732
+ *
733
+ * ```ts
734
+ * const Button = createContractComponent({
735
+ * tag: 'button',
736
+ * name: 'Button',
737
+ * styling: {
738
+ * base: 'btn',
739
+ * variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
740
+ * defaults: { intent: 'primary' },
741
+ * },
742
+ * enforcement: { diagnostics: warnDiagnostics },
743
+ * })
744
+ *
745
+ * customElements.define('praxis-button', Button)
746
+ * ```
747
+ *
748
+ * The pipeline runs synchronously on `connectedCallback` and on every
749
+ * `attributeChangedCallback` for praxis-owned attributes (variant keys,
750
+ * `variant-key`, `praxis-class`).
751
+ *
752
+ * For non-reactive attributes (`aria-*`, `role`, `data-*`) — or a praxis-owned
753
+ * property set directly rather than via `setAttribute` (property assignment
754
+ * alone never fires `attributeChangedCallback`) — call `element.update()` after
755
+ * to trigger an explicit pipeline re-run.
756
+ *
757
+ * **This adapter is a Custom Element host carrying a Praxis semantic contract — not a
758
+ * reimplementation of native HTML element behavior.** `options.tag` (`'button'` above) names the
759
+ * _intrinsic model_ Praxis resolves ARIA roles, content-model rules, and built-in prop
760
+ * normalizers (`disabledProps`, etc.) against — it is not, and was never meant to be, the tag
761
+ * actually written to the DOM. The DOM tag is whatever name a caller later passes to
762
+ * `customElements.define(name, Button)`, entirely separate from `options.tag` and not knowable by
763
+ * this function at all (registration happens externally, after this returns, possibly under
764
+ * multiple names or never). So for the example above:
765
+ *
766
+ * ```text
767
+ * Praxis intrinsic model: button (options.tag — drives ARIA/content-model/normalizers)
768
+ * DOM host: praxis-button (customElements.define()'s name — the actual element)
769
+ * ```
770
+ *
771
+ * A concrete consequence worth internalizing: `<praxis-button disabled>` gets `aria-disabled` from
772
+ * the `disabledProps` normalizer (correctly, since `disabled`'s HTML-boolean-attribute semantics
773
+ * are honored in `_buildProps()` below), but the browser does **not** make the custom element
774
+ * keyboard-inert, form-participating, or otherwise behave like a real `HTMLButtonElement` — that
775
+ * gap isn't a bug, it's the direct consequence of `class X extends HTMLElement`, and no ARIA
776
+ * attribute on any element, custom or not, ever supplies real interactive behavior. The contract
777
+ * layer (styling, variants, ARIA policy, child enforcement, attribute management, lifecycle hooks,
778
+ * diagnostics) and the host's actual interactive behavior are — and have to stay — conceptually
779
+ * separate; a caller who needs real button/link/input behavior supplies it themselves (`onElement`
780
+ * is the wiring point), the same way any `role="button"` `<div>` would require it. (Customized
781
+ * built-ins — `class X extends HTMLButtonElement` + `{ extends: 'button' }` — were considered and
782
+ * rejected for solving this: a real platform mechanism, but a different consumer-facing API
783
+ * (`<button is="…">` instead of `<praxis-button>`) with its own platform constraints, not worth the
784
+ * complexity it would add here.)
785
+ *
786
+ * **No `as` prop.** Like the Lit adapter (this one's closest sibling — both are fixed-identity
787
+ * custom elements, sharing `resolveHostState`/`renderBundleToString` from the shared adapter runtime),
788
+ * a custom element's DOM tag is fixed at `customElements.define()` time — once the model/host
789
+ * distinction above is explicit, this becomes easy: there is no tag for `as` to switch. An earlier
790
+ * design accepted `as` as a semantic-only override (never changing the rendered element, but
791
+ * changing which ARIA/content-model rules applied, as if it really were a different tag). That was
792
+ * worse than not having it: it could produce `role="link"`-shaped output with none of an anchor's
793
+ * actual keyboard/click/middle-click behavior — a real accessibility footgun regardless of the
794
+ * option's name — and it made `renderContractToString`'s output disagree with itself across calls
795
+ * to the same component, which can only ever produce `<praxis-button>…</praxis-button>` on the live
796
+ * client regardless of what tag `as` named. `as` is filtered out unconditionally in `_buildProps()`
797
+ * below (including as a raw, undeclared HTML attribute, not just a declared property) so
798
+ * `resolveHostState`/`renderBundleToString` — shared, unmodified, cross-adapter code — always
799
+ * resolve to `options.tag` here, on both the client and SSR paths. Need different semantics for one
800
+ * instance? Register a second component with a different `tag`, or set `role` directly — both
801
+ * already work today, unaffected by this.
802
+ */
803
+ export declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<TVariants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: WebFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
804
+ readonly subComponents?: TSubComponents;
805
+ }): WebContractComponent<TVariants, ExtractPluginProps<TPlugin>, RuntimeG<TDefault, TProps, TVariants, TPreset>> & TSubComponents;
806
+ //#endregion
807
+ //#region ../../adapters/web/src/render-to-string.d.ts
808
+ /**
809
+ * Serializes a praxis-kit web component's **resolved contract** to an HTML string, without
810
+ * requiring a DOM — not Custom Element SSR, and not a hydration mechanism.
811
+ *
812
+ * This distinction matters and is easy to get wrong: the output element is `options.tag`
813
+ * (`<button>…</button>`, say), never the registered custom-element tag (`<praxis-button>`) —
814
+ * `createContractComponent`'s own doc comment covers why the two are different concepts ("the
815
+ * element Praxis models" vs. "the element actually in the DOM"). `customElements.define()` happens
816
+ * externally, after `createContractComponent()` returns, and this function has no way to know what
817
+ * name (if any) a caller eventually registers the class under, so there is no tag it could emit
818
+ * that's guaranteed to match. Even if it could, the browser's Custom Element upgrade mechanism only
819
+ * upgrades an exact tag-name match — a server-sent `<button>` can never become the live
820
+ * `<praxis-button>` no matter what the client bundle does, so this was never a viable
821
+ * SSR-then-upgrade path regardless of naming.
822
+ *
823
+ * Use this for what it actually is: previewing/testing the resolved styling + ARIA + attribute
824
+ * pipeline as plain HTML (static generation, snapshot tests, non-interactive contexts) — not for
825
+ * server-rendering markup you intend the live custom element to take over.
826
+ *
827
+ * `innerHTML` is treated as a pre-sanitized HTML string and inserted verbatim.
828
+ * Callers are responsible for escaping any untrusted content before passing it.
829
+ */
830
+ export declare function renderContractToString(component: WebContractComponent, props?: UnknownProps, innerHTML?: string): string;
831
+ //#endregion
832
+ export type { AnyFactoryOptions, ContractProps, ElementType, EmptyRecord, FactoryOptions, GenericsOf, PolymorphicGenerics, WebContractComponent, WebFactoryOptions };