praxis-kit 7.3.0 → 7.4.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/_shared/diagnostics.d.ts +6 -0
- package/dist/contract/index.d.ts +67 -1
- package/dist/guards/index.d.ts +6 -0
- package/dist/html/index.d.ts +6 -0
- package/dist/lit/index.d.ts +132 -8
- package/dist/preact/index.d.ts +138 -5
- package/dist/react/index.d.ts +25 -4
- package/dist/react/legacy.d.ts +25 -3
- package/dist/{react-options-DLDsA4Tn.d.ts → react-options-BnjZpdVh.d.ts} +116 -4
- package/dist/solid/index.d.ts +137 -5
- package/dist/svelte/Polymorphic.svelte +13 -0
- package/dist/svelte/index.d.ts +202 -15
- package/dist/tailwind/index.d.ts +12 -0
- package/dist/vite-plugin/index.d.ts +6 -0
- package/dist/vue/index.d.ts +140 -5
- package/dist/web/index.d.ts +105 -5
- package/package.json +3 -3
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory,
|
|
2
|
-
export {
|
|
1
|
+
import { U as UnknownProps, E as ElementType, a as EmptyRecord, V as VariantMap, N as NoVariants, R as RecipeMap, b as NoPreset, A as AnyClassPluginFactory, c as AnyRecord, d as ReactFactoryOptions, M as MergeRecords, P as PolymorphicComponent, e as PolymorphicGenerics, f as ExtractPluginProps } from '../react-options-BnjZpdVh.js';
|
|
2
|
+
export { g as AnyFactoryOptions, h as ElementRef, F as FactoryOptions, i as PolymorphicProps, j as PolymorphicWithAsChild, k as PolymorphicWithRender, l as RenderCallbackProps, S as Slottable, m as SlottableProps, n as composeRefs, o as defineContractComponent, n as mergeRefs } from '../react-options-BnjZpdVh.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactElement, Ref } from 'react';
|
|
5
5
|
import 'type-fest';
|
|
@@ -22,9 +22,30 @@ type CloneInput = {
|
|
|
22
22
|
ref: NormalizedRef;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Creates a polymorphic React 19 component with praxis-kit contracts applied.
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* const Button = createContractComponent({
|
|
30
|
+
* tag: 'button',
|
|
31
|
+
* name: 'Button',
|
|
32
|
+
* styling: {
|
|
33
|
+
* base: 'btn',
|
|
34
|
+
* variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
|
|
35
|
+
* defaults: { intent: 'primary' },
|
|
36
|
+
* },
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* <Button intent="ghost" as="a" href="/home">Home</Button>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* `ref` is accepted as a plain prop (React 19) and forwarded to the rendered host element or,
|
|
43
|
+
* with `asChild`, to the consumer's own element. Pass `subComponents` to attach named
|
|
44
|
+
* sub-components (`Card.Header`) and `onElement` to run setup once the real DOM element exists.
|
|
45
|
+
*/
|
|
46
|
+
declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<Variants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: ReactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin, TAllowed> & {
|
|
26
47
|
readonly subComponents?: TSubComponents;
|
|
27
|
-
}): PolymorphicComponent<PolymorphicGenerics<TDefault, Props
|
|
48
|
+
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset, TAllowed>>, TSubComponents>;
|
|
28
49
|
|
|
29
50
|
type SlotProps = {
|
|
30
51
|
ref?: Ref<unknown> | null;
|
package/dist/react/legacy.d.ts
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
|
-
import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, R as RecipeMap, A as AnyClassPluginFactory,
|
|
2
|
-
export {
|
|
1
|
+
import { E as ElementType, U as UnknownProps, a as EmptyRecord, V as VariantMap, N as NoVariants, R as RecipeMap, b as NoPreset, A as AnyClassPluginFactory, d as ReactFactoryOptions, P as PolymorphicComponent, e as PolymorphicGenerics, M as MergeRecords, f as ExtractPluginProps } from '../react-options-BnjZpdVh.js';
|
|
2
|
+
export { g as AnyFactoryOptions, h as ElementRef, F as FactoryOptions, i as PolymorphicProps, j as PolymorphicWithAsChild, k as PolymorphicWithRender, l as RenderCallbackProps, S as Slottable, m as SlottableProps, o as defineContractComponent, n as mergeRefs } from '../react-options-BnjZpdVh.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import 'type-fest';
|
|
5
5
|
import '../_shared/diagnostics.js';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Creates a polymorphic React component with praxis-kit contracts applied, for React 18 and
|
|
9
|
+
* earlier (use `praxis-kit/react` instead on React 19, which accepts `ref` as a plain prop).
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* const Button = createContractComponent({
|
|
13
|
+
* tag: 'button',
|
|
14
|
+
* name: 'Button',
|
|
15
|
+
* styling: {
|
|
16
|
+
* base: 'btn',
|
|
17
|
+
* variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
|
|
18
|
+
* defaults: { intent: 'primary' },
|
|
19
|
+
* },
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* <Button intent="ghost" as="a" href="/home">Home</Button>
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Returns a `forwardRef` component — `ref` is forwarded to the rendered host element the same
|
|
26
|
+
* way it works in `praxis-kit/react`. Pass `onElement` to run setup once the real DOM element
|
|
27
|
+
* exists; this adapter doesn't support `subComponents`.
|
|
28
|
+
*/
|
|
29
|
+
declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<Variants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType>(options: ReactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin, TAllowed>): PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset, TAllowed>>;
|
|
8
30
|
|
|
9
31
|
type SlotProps = {
|
|
10
32
|
[key: string]: unknown;
|
|
@@ -2,11 +2,72 @@ import { Ref, PropsWithChildren, ReactElement, ComponentType, JSX, ReactNode } f
|
|
|
2
2
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep, NonEmptyTuple } from 'type-fest';
|
|
3
3
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from './_shared/diagnostics.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A string-keyed object whose values are of type `T`.
|
|
7
|
+
*/
|
|
5
8
|
type StringMap<T = unknown> = Record<string, T>;
|
|
9
|
+
/**
|
|
10
|
+
* A string-keyed object with values of unknown type.
|
|
11
|
+
*/
|
|
6
12
|
type AnyRecord = StringMap<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* An object type with no named properties.
|
|
15
|
+
*
|
|
16
|
+
* Unlike `{}`, this excludes arbitrary properties during type operations while
|
|
17
|
+
* still satisfying `extends object`.
|
|
18
|
+
*/
|
|
7
19
|
type EmptyRecord = Record<never, never>;
|
|
8
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A compound component's named sub-components, for example
|
|
22
|
+
* `{ Header, Content, Footer }`.
|
|
23
|
+
*/
|
|
9
24
|
type SubComponentMap = Readonly<AnyRecord>;
|
|
25
|
+
/**
|
|
26
|
+
* Default `Variants` type for components that declare no variants.
|
|
27
|
+
*
|
|
28
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
29
|
+
* editor hovers remain self-descriptive.
|
|
30
|
+
*/
|
|
31
|
+
type NoVariants = Readonly<EmptyRecord>;
|
|
32
|
+
/**
|
|
33
|
+
* Default `TPreset` type for components that declare no named presets.
|
|
34
|
+
*
|
|
35
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
36
|
+
* editor hovers remain self-descriptive.
|
|
37
|
+
*/
|
|
38
|
+
type NoPreset = Readonly<EmptyRecord>;
|
|
39
|
+
/**
|
|
40
|
+
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
41
|
+
* props, including the no-plugin case.
|
|
42
|
+
*
|
|
43
|
+
* Structurally identical to `EmptyRecord`, but named separately so editor
|
|
44
|
+
* hovers remain self-descriptive.
|
|
45
|
+
*/
|
|
46
|
+
type NoPluginProps = EmptyRecord;
|
|
47
|
+
/**
|
|
48
|
+
* Determines whether an object type should be treated as empty.
|
|
49
|
+
*
|
|
50
|
+
* `keyof T` ignores call and construct signatures...
|
|
51
|
+
*/
|
|
52
|
+
type IsEmptyRecord<T extends object> = T extends (...args: never[]) => unknown ? false : T extends new (...args: never[]) => unknown ? false : keyof T extends never ? true : false;
|
|
53
|
+
/**
|
|
54
|
+
* Merges two object types while eliding empty operands.
|
|
55
|
+
*
|
|
56
|
+
* If either operand is {@link EmptyRecord}, the other operand is returned
|
|
57
|
+
* directly instead of producing intersections such as
|
|
58
|
+
* `Component & EmptyRecord` in editor hovers.
|
|
59
|
+
*
|
|
60
|
+
* Unlike a homomorphic mapped type (for example `Simplify<T>`), this preserves
|
|
61
|
+
* call and construct signatures. Many component types are callable objects,
|
|
62
|
+
* and mapped types silently discard those signatures.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Instantiate `MergeRecords` directly. Introducing an intermediate alias for
|
|
66
|
+
* one operand (for example `type C = PolymorphicComponent<G>`) can prevent
|
|
67
|
+
* `IsEmptyRecord` from evaluating eagerly, which breaks assignability under
|
|
68
|
+
* `exactOptionalPropertyTypes`.
|
|
69
|
+
*/
|
|
70
|
+
type MergeRecords<A extends object, B extends object> = IsEmptyRecord<A> extends true ? B : IsEmptyRecord<B> extends true ? A : A & B;
|
|
10
71
|
|
|
11
72
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
12
73
|
|
|
@@ -190,7 +251,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
190
251
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
191
252
|
* capability wiring). */
|
|
192
253
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
193
|
-
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ?
|
|
254
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
194
255
|
|
|
195
256
|
type AriaContext = {
|
|
196
257
|
readonly tag: IntrinsicTag;
|
|
@@ -254,6 +315,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
254
315
|
* `@praxis-kit/diagnostics`.
|
|
255
316
|
*/
|
|
256
317
|
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
318
|
+
/**
|
|
319
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
320
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
321
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
322
|
+
* and friends in `praxis-kit/contract`).
|
|
323
|
+
*/
|
|
257
324
|
readonly aria?: readonly AriaRule[];
|
|
258
325
|
/**
|
|
259
326
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -265,6 +332,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
265
332
|
* misleading `aria` name to get the machinery it needs.
|
|
266
333
|
*/
|
|
267
334
|
readonly rules?: readonly AriaRule[];
|
|
335
|
+
/**
|
|
336
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
337
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
338
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
339
|
+
*/
|
|
268
340
|
readonly children?: readonly ChildRuleInput[];
|
|
269
341
|
/**
|
|
270
342
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -277,19 +349,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
277
349
|
* or any listed rule. Default: true.
|
|
278
350
|
*/
|
|
279
351
|
readonly allowText?: boolean;
|
|
352
|
+
/**
|
|
353
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
354
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
355
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
356
|
+
*/
|
|
280
357
|
readonly props?: readonly PropNormalizer[];
|
|
281
358
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
282
359
|
readonly allowedAs?: readonly TAllowed[];
|
|
283
360
|
};
|
|
284
361
|
|
|
285
362
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
363
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
286
364
|
readonly base?: ClassName;
|
|
365
|
+
/**
|
|
366
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
367
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
368
|
+
*/
|
|
287
369
|
readonly variants?: V;
|
|
370
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
288
371
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
372
|
+
/**
|
|
373
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
374
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
375
|
+
* need a class neither variant would add on its own).
|
|
376
|
+
*/
|
|
289
377
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
378
|
+
/**
|
|
379
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
380
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
381
|
+
*/
|
|
290
382
|
readonly presets?: TPreset;
|
|
383
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
291
384
|
readonly tags?: Readonly<TagMap>;
|
|
385
|
+
/**
|
|
386
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
387
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
388
|
+
*/
|
|
292
389
|
readonly plugin?: TPlugin;
|
|
390
|
+
/**
|
|
391
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
392
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
393
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
394
|
+
*/
|
|
293
395
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
294
396
|
};
|
|
295
397
|
|
|
@@ -298,11 +400,21 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
298
400
|
}['normalize'];
|
|
299
401
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
300
402
|
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> = {
|
|
403
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
301
404
|
readonly tag?: TDefault;
|
|
405
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
302
406
|
readonly name?: string;
|
|
407
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
303
408
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
409
|
+
/**
|
|
410
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
411
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
412
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
413
|
+
*/
|
|
304
414
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
415
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
305
416
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
417
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
306
418
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
307
419
|
/**
|
|
308
420
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
|
@@ -533,7 +645,7 @@ interface CompiledArtifact {
|
|
|
533
645
|
* Extends FactoryOptions with React-specific configuration.
|
|
534
646
|
* slotComponent is intentionally not in core — it is a React rendering concern.
|
|
535
647
|
*/
|
|
536
|
-
type ReactFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> =
|
|
648
|
+
type ReactFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType> = FactoryOptions<TDefault, Props, Variants, TPreset, TPlugin, TAllowed> & {
|
|
537
649
|
/** Component used to render the asChild slot. Defaults to the built-in Slot. */
|
|
538
650
|
slotComponent?: SlotComponent;
|
|
539
651
|
/**
|
|
@@ -547,4 +659,4 @@ type ReactFactoryOptions<TDefault extends ElementType, Props extends UnknownProp
|
|
|
547
659
|
artifact?: CompiledArtifact;
|
|
548
660
|
};
|
|
549
661
|
|
|
550
|
-
export { type AnyClassPluginFactory as A, type ElementType as E, type FactoryOptions as F, type PolymorphicComponent as P, type RecipeMap as R, Slottable as S, type UnknownProps as U, type VariantMap as V, type EmptyRecord as a, type
|
|
662
|
+
export { type AnyClassPluginFactory as A, type ElementType as E, type FactoryOptions as F, type MergeRecords as M, type NoVariants as N, type PolymorphicComponent as P, type RecipeMap as R, Slottable as S, type UnknownProps as U, type VariantMap as V, type EmptyRecord as a, type NoPreset as b, type AnyRecord as c, type ReactFactoryOptions as d, type PolymorphicGenerics as e, type ExtractPluginProps as f, type AnyFactoryOptions as g, type ElementRef as h, type PolymorphicProps as i, type PolymorphicWithAsChild as j, type PolymorphicWithRender as k, type RenderCallbackProps as l, type SlottableProps as m, mergeRefs as n, defineContractComponent as o };
|
package/dist/solid/index.d.ts
CHANGED
|
@@ -2,11 +2,72 @@ import { RequireAtLeastOne, Simplify, ReadonlyDeep, OmitIndexSignature } from 't
|
|
|
2
2
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
3
3
|
import { JSX } from 'solid-js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A string-keyed object whose values are of type `T`.
|
|
7
|
+
*/
|
|
5
8
|
type StringMap<T = unknown> = Record<string, T>;
|
|
9
|
+
/**
|
|
10
|
+
* A string-keyed object with values of unknown type.
|
|
11
|
+
*/
|
|
6
12
|
type AnyRecord = StringMap<unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* An object type with no named properties.
|
|
15
|
+
*
|
|
16
|
+
* Unlike `{}`, this excludes arbitrary properties during type operations while
|
|
17
|
+
* still satisfying `extends object`.
|
|
18
|
+
*/
|
|
7
19
|
type EmptyRecord = Record<never, never>;
|
|
8
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A compound component's named sub-components, for example
|
|
22
|
+
* `{ Header, Content, Footer }`.
|
|
23
|
+
*/
|
|
9
24
|
type SubComponentMap = Readonly<AnyRecord>;
|
|
25
|
+
/**
|
|
26
|
+
* Default `Variants` type for components that declare no variants.
|
|
27
|
+
*
|
|
28
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
29
|
+
* editor hovers remain self-descriptive.
|
|
30
|
+
*/
|
|
31
|
+
type NoVariants = Readonly<EmptyRecord>;
|
|
32
|
+
/**
|
|
33
|
+
* Default `TPreset` type for components that declare no named presets.
|
|
34
|
+
*
|
|
35
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
36
|
+
* editor hovers remain self-descriptive.
|
|
37
|
+
*/
|
|
38
|
+
type NoPreset = Readonly<EmptyRecord>;
|
|
39
|
+
/**
|
|
40
|
+
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
41
|
+
* props, including the no-plugin case.
|
|
42
|
+
*
|
|
43
|
+
* Structurally identical to `EmptyRecord`, but named separately so editor
|
|
44
|
+
* hovers remain self-descriptive.
|
|
45
|
+
*/
|
|
46
|
+
type NoPluginProps = EmptyRecord;
|
|
47
|
+
/**
|
|
48
|
+
* Determines whether an object type should be treated as empty.
|
|
49
|
+
*
|
|
50
|
+
* `keyof T` ignores call and construct signatures...
|
|
51
|
+
*/
|
|
52
|
+
type IsEmptyRecord<T extends object> = T extends (...args: never[]) => unknown ? false : T extends new (...args: never[]) => unknown ? false : keyof T extends never ? true : false;
|
|
53
|
+
/**
|
|
54
|
+
* Merges two object types while eliding empty operands.
|
|
55
|
+
*
|
|
56
|
+
* If either operand is {@link EmptyRecord}, the other operand is returned
|
|
57
|
+
* directly instead of producing intersections such as
|
|
58
|
+
* `Component & EmptyRecord` in editor hovers.
|
|
59
|
+
*
|
|
60
|
+
* Unlike a homomorphic mapped type (for example `Simplify<T>`), this preserves
|
|
61
|
+
* call and construct signatures. Many component types are callable objects,
|
|
62
|
+
* and mapped types silently discard those signatures.
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* Instantiate `MergeRecords` directly. Introducing an intermediate alias for
|
|
66
|
+
* one operand (for example `type C = PolymorphicComponent<G>`) can prevent
|
|
67
|
+
* `IsEmptyRecord` from evaluating eagerly, which breaks assignability under
|
|
68
|
+
* `exactOptionalPropertyTypes`.
|
|
69
|
+
*/
|
|
70
|
+
type MergeRecords<A extends object, B extends object> = IsEmptyRecord<A> extends true ? B : IsEmptyRecord<B> extends true ? A : A & B;
|
|
10
71
|
|
|
11
72
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
12
73
|
|
|
@@ -189,7 +250,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
189
250
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
190
251
|
* capability wiring). */
|
|
191
252
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
192
|
-
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ?
|
|
253
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
193
254
|
|
|
194
255
|
type AriaContext = {
|
|
195
256
|
readonly tag: IntrinsicTag;
|
|
@@ -253,6 +314,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
253
314
|
* `@praxis-kit/diagnostics`.
|
|
254
315
|
*/
|
|
255
316
|
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
317
|
+
/**
|
|
318
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
319
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
320
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
321
|
+
* and friends in `praxis-kit/contract`).
|
|
322
|
+
*/
|
|
256
323
|
readonly aria?: readonly AriaRule[];
|
|
257
324
|
/**
|
|
258
325
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -264,6 +331,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
264
331
|
* misleading `aria` name to get the machinery it needs.
|
|
265
332
|
*/
|
|
266
333
|
readonly rules?: readonly AriaRule[];
|
|
334
|
+
/**
|
|
335
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
336
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
337
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
338
|
+
*/
|
|
267
339
|
readonly children?: readonly ChildRuleInput[];
|
|
268
340
|
/**
|
|
269
341
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -276,19 +348,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
276
348
|
* or any listed rule. Default: true.
|
|
277
349
|
*/
|
|
278
350
|
readonly allowText?: boolean;
|
|
351
|
+
/**
|
|
352
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
353
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
354
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
355
|
+
*/
|
|
279
356
|
readonly props?: readonly PropNormalizer[];
|
|
280
357
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
281
358
|
readonly allowedAs?: readonly TAllowed[];
|
|
282
359
|
};
|
|
283
360
|
|
|
284
361
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
362
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
285
363
|
readonly base?: ClassName;
|
|
364
|
+
/**
|
|
365
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
366
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
367
|
+
*/
|
|
286
368
|
readonly variants?: V;
|
|
369
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
287
370
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
371
|
+
/**
|
|
372
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
373
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
374
|
+
* need a class neither variant would add on its own).
|
|
375
|
+
*/
|
|
288
376
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
377
|
+
/**
|
|
378
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
379
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
380
|
+
*/
|
|
289
381
|
readonly presets?: TPreset;
|
|
382
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
290
383
|
readonly tags?: Readonly<TagMap>;
|
|
384
|
+
/**
|
|
385
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
386
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
387
|
+
*/
|
|
291
388
|
readonly plugin?: TPlugin;
|
|
389
|
+
/**
|
|
390
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
391
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
392
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
393
|
+
*/
|
|
292
394
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
293
395
|
};
|
|
294
396
|
|
|
@@ -297,11 +399,21 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
297
399
|
}['normalize'];
|
|
298
400
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
299
401
|
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> = {
|
|
402
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
300
403
|
readonly tag?: TDefault;
|
|
404
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
301
405
|
readonly name?: string;
|
|
406
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
302
407
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
408
|
+
/**
|
|
409
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
410
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
411
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
412
|
+
*/
|
|
303
413
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
414
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
304
415
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
416
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
305
417
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
306
418
|
/**
|
|
307
419
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
|
@@ -340,7 +452,7 @@ type UnknownProps = AnyRecord;
|
|
|
340
452
|
type SolidElement = JSX.Element;
|
|
341
453
|
type SlotRenderFn = (props: UnknownProps) => SolidElement;
|
|
342
454
|
|
|
343
|
-
type SolidFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> =
|
|
455
|
+
type SolidFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = FactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
|
|
344
456
|
/**
|
|
345
457
|
* Return true for any prop key that should be consumed but not forwarded to the DOM.
|
|
346
458
|
* Receives `runtime.options.variantKeys` as a convenience if needed.
|
|
@@ -383,8 +495,28 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
|
|
|
383
495
|
displayName?: string;
|
|
384
496
|
};
|
|
385
497
|
|
|
386
|
-
|
|
498
|
+
/**
|
|
499
|
+
* Creates a polymorphic Solid component with praxis-kit contracts applied.
|
|
500
|
+
*
|
|
501
|
+
* ```tsx
|
|
502
|
+
* const Button = createContractComponent({
|
|
503
|
+
* tag: 'button',
|
|
504
|
+
* name: 'Button',
|
|
505
|
+
* styling: {
|
|
506
|
+
* base: 'btn',
|
|
507
|
+
* variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
|
|
508
|
+
* defaults: { intent: 'primary' },
|
|
509
|
+
* },
|
|
510
|
+
* })
|
|
511
|
+
*
|
|
512
|
+
* <Button intent="ghost" as="a" href="/home">Home</Button>
|
|
513
|
+
* ```
|
|
514
|
+
*
|
|
515
|
+
* `ref` is forwarded as an ordinary Solid ref callback. Pass `subComponents` to attach named
|
|
516
|
+
* sub-components (`Card.Header`) and `onElement` to run setup once the real DOM element exists.
|
|
517
|
+
*/
|
|
518
|
+
declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = NoVariants, TPreset extends RecipeMap<Variants> = NoPreset, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: SolidFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
|
|
387
519
|
readonly subComponents?: TSubComponents;
|
|
388
|
-
}): PolymorphicComponent<PolymorphicGenerics<TDefault, Props
|
|
520
|
+
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>>, TSubComponents>;
|
|
389
521
|
|
|
390
522
|
export { type AnyFactoryOptions, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type SolidFactoryOptions, createContractComponent, defineContractComponent };
|
|
@@ -1,3 +1,16 @@
|
|
|
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
|
+
-->
|
|
1
14
|
<script module lang="ts">
|
|
2
15
|
declare const process: { env: { NODE_ENV: string } }
|
|
3
16
|
</script>
|