praxis-kit 7.5.0 → 7.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_shared/diagnostics.d.ts +3 -0
- package/dist/_shared/diagnostics.js +3 -0
- package/dist/{chunk-SMHJEFNE.js → chunk-CCWOPNX2.js} +335 -163
- package/dist/contract/index.d.ts +3 -3
- package/dist/eslint/index.js +227 -187
- package/dist/html/index.d.ts +6 -1
- package/dist/html/index.js +234 -68
- package/dist/lit/index.d.ts +3 -3
- package/dist/lit/index.js +323 -149
- package/dist/preact/index.d.ts +90 -5
- package/dist/preact/index.js +335 -161
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +1 -1
- package/dist/react/legacy.d.ts +8 -5
- package/dist/react/legacy.js +8 -8
- package/dist/{react-options-5GbZ8Tbv.d.ts → react-options-DU3EdFOv.d.ts} +102 -6
- package/dist/solid/index.d.ts +103 -7
- package/dist/solid/index.js +337 -163
- package/dist/svelte/Polymorphic.svelte +12 -2
- package/dist/svelte/index.d.ts +197 -11
- package/dist/svelte/index.js +337 -160
- package/dist/tailwind/index.d.ts +1 -1
- package/dist/vite-plugin/index.d.ts +6 -3
- package/dist/vue/index.d.ts +70 -5
- package/dist/vue/index.js +339 -161
- package/dist/web/index.d.ts +3 -3
- package/dist/web/index.js +323 -149
- package/package.json +9 -9
package/dist/react/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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-
|
|
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-
|
|
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-DU3EdFOv.js';
|
|
2
|
+
export { g as AnyFactoryOptions, C as ContractProps, 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-DU3EdFOv.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactElement, Ref } from 'react';
|
|
5
5
|
import 'type-fest';
|
|
6
|
+
import '@praxis-kit/contract-props';
|
|
6
7
|
import '../_shared/diagnostics.js';
|
|
7
8
|
|
|
8
9
|
/**
|
package/dist/react/index.js
CHANGED
package/dist/react/legacy.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
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,
|
|
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-
|
|
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, c as AnyRecord, d as ReactFactoryOptions, M as MergeRecords, P as PolymorphicComponent, e as PolymorphicGenerics, f as ExtractPluginProps } from '../react-options-DU3EdFOv.js';
|
|
2
|
+
export { g as AnyFactoryOptions, C as ContractProps, 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-DU3EdFOv.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import 'type-fest';
|
|
5
|
+
import '@praxis-kit/contract-props';
|
|
5
6
|
import '../_shared/diagnostics.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -23,10 +24,12 @@ import '../_shared/diagnostics.js';
|
|
|
23
24
|
* ```
|
|
24
25
|
*
|
|
25
26
|
* Returns a `forwardRef` component — `ref` is forwarded to the rendered host element the same
|
|
26
|
-
* way it works in `praxis-kit/react`. Pass `
|
|
27
|
-
*
|
|
27
|
+
* way it works in `praxis-kit/react`. Pass `subComponents` to attach named sub-components
|
|
28
|
+
* (`Card.Header`) and `onElement` to run setup once the real DOM element exists.
|
|
28
29
|
*/
|
|
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>
|
|
30
|
+
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> & {
|
|
31
|
+
readonly subComponents?: TSubComponents;
|
|
32
|
+
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset, TAllowed>>, TSubComponents>;
|
|
30
33
|
|
|
31
34
|
type SlotProps = {
|
|
32
35
|
[key: string]: unknown;
|
package/dist/react/legacy.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
COMPONENT_DEFAULT_TAG,
|
|
3
2
|
SLOT_NAME,
|
|
4
3
|
Slottable,
|
|
5
4
|
applyDisplayName,
|
|
6
5
|
applySlot,
|
|
7
6
|
buildRuntime,
|
|
8
7
|
defineContractComponent,
|
|
8
|
+
finalizeComponent,
|
|
9
9
|
getElementRef,
|
|
10
10
|
getPropsRef,
|
|
11
11
|
hasWarningGetter,
|
|
12
|
-
isString,
|
|
13
12
|
makeCloneSlotChild,
|
|
14
13
|
mergeRefs,
|
|
15
14
|
render
|
|
16
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-CCWOPNX2.js";
|
|
17
16
|
|
|
18
17
|
// ../../adapters/react/src/legacy/create-contract-component.ts
|
|
19
18
|
import { forwardRef as forwardRef2, useCallback, useRef } from "react";
|
|
@@ -71,11 +70,12 @@ function createContractComponent(options) {
|
|
|
71
70
|
return render({ ...bundle, props, ref: mergedRef });
|
|
72
71
|
});
|
|
73
72
|
applyDisplayName(Component, options.name);
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
const assembled = finalizeComponent(
|
|
74
|
+
Component,
|
|
75
|
+
bundle.runtime.options.defaultTag,
|
|
76
|
+
options.subComponents
|
|
77
|
+
);
|
|
78
|
+
return assembled;
|
|
79
79
|
}
|
|
80
80
|
export {
|
|
81
81
|
Slot,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Ref, PropsWithChildren, ReactElement, ComponentType, JSX, ReactNode } from 'react';
|
|
2
2
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep, NonEmptyTuple } from 'type-fest';
|
|
3
|
+
import { HasGenerics, Mode, PickMode } from '@praxis-kit/contract-props';
|
|
3
4
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from './_shared/diagnostics.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -189,21 +190,78 @@ type DefaultVariants<V extends VariantMap> = {
|
|
|
189
190
|
* Presets are named bundles of variant props that callers activate by key,
|
|
190
191
|
* avoiding the need to repeat variant combinations at each call site.
|
|
191
192
|
*/
|
|
192
|
-
type RecipeMap<V extends VariantMap = VariantMap> = Readonly<
|
|
193
|
+
type RecipeMap<V extends VariantMap = VariantMap> = Readonly<StringMap<VariantSelection<V>>>;
|
|
193
194
|
|
|
194
195
|
type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
|
|
195
196
|
|
|
196
|
-
|
|
197
|
+
/**
|
|
198
|
+
* The framework-neutral descriptor for a single praxis-kit component's contract — every render
|
|
199
|
+
* mechanism (tag resolution, prop merging, classes, ARIA) and every framework adapter's
|
|
200
|
+
* component type is built from this one shape. Deliberately just data: five type parameters and
|
|
201
|
+
* their corresponding properties, with no notion of JSX, call signatures, refs, or any
|
|
202
|
+
* framework-specific rendering concern. Each adapter (React, Vue, Svelte, Solid, Lit, Web) builds
|
|
203
|
+
* its own idiomatic component type on top of a `PolymorphicGenerics<...>` instantiation — see
|
|
204
|
+
* `PolymorphicComponent<G>` (`adapters/react/src/shared/types/polymorphic-props.ts`) for the
|
|
205
|
+
* React example — rather than this interface knowing anything about any of them.
|
|
206
|
+
*
|
|
207
|
+
* Use the `*Of<T>` accessor aliases below (`DefaultOf<G>`, `PropsOf<G>`, etc.) to read a single
|
|
208
|
+
* field back out of an already-resolved `G`, instead of indexing `G['default']` etc. directly at
|
|
209
|
+
* call sites — same rationale as any accessor: the property name stays an implementation detail,
|
|
210
|
+
* and every reader benefits together if it ever needs to change.
|
|
211
|
+
*/
|
|
212
|
+
interface PolymorphicGenerics<
|
|
213
|
+
/**
|
|
214
|
+
* The element/tag this component renders as when the consumer doesn't override it via `as`
|
|
215
|
+
* (`AllowedOf<G>` permitting) — e.g. `'button'`, `'div'`. Defaults to the widest `ElementType`
|
|
216
|
+
* so a generic `PolymorphicGenerics` reference (with nothing else specified) still compiles.
|
|
217
|
+
*/
|
|
218
|
+
TDefault extends ElementType = ElementType,
|
|
219
|
+
/**
|
|
220
|
+
* The props this specific component declares — its own contract, before variants are mixed
|
|
221
|
+
* in. Defaults to `AnyRecord` for the same "still compiles unspecified" reason as `TDefault`.
|
|
222
|
+
*/
|
|
223
|
+
Props extends AnyRecord = AnyRecord,
|
|
224
|
+
/**
|
|
225
|
+
* This component's variant definitions (e.g. `{ intent: { primary: ..., ghost: ... } }`).
|
|
226
|
+
* Constrained to `Readonly<VariantMap>` — not the wider `AnyRecord` — specifically so `TPreset`
|
|
227
|
+
* below can be expressed as `RecipeMap<Variants>` and get real per-variant-key checking,
|
|
228
|
+
* instead of falling back to an unconstrained `RecipeMap<VariantMap>`.
|
|
229
|
+
*/
|
|
230
|
+
Variants extends Readonly<VariantMap> = Readonly<VariantMap>,
|
|
231
|
+
/**
|
|
232
|
+
* Named presets (`RecipeMap<Variants>`) — bundles of variant selections a consumer activates
|
|
233
|
+
* by key instead of repeating the same variant combination at every call site. Tied to
|
|
234
|
+
* `Variants`, not `AnyRecord`, precisely so a preset can only ever select keys/values that
|
|
235
|
+
* `Variants` actually defines — an invalid preset is a type error, not a silent no-op.
|
|
236
|
+
* Defaults to `Readonly<EmptyRecord>` (no presets), which is the common case: a component can
|
|
237
|
+
* have variants without necessarily defining any named presets over them, and most don't.
|
|
238
|
+
*/
|
|
239
|
+
TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>,
|
|
240
|
+
/**
|
|
241
|
+
* The set of elements/tags a consumer is allowed to switch to via `as`. Defaults to the widest
|
|
242
|
+
* `ElementType`, under which `AllowedOf<G>` imposes no restriction at all (see
|
|
243
|
+
* `PolymorphicControlProps.as`'s own comment in the React adapter for the concrete effect this
|
|
244
|
+
* has at a component's actual call site).
|
|
245
|
+
*/
|
|
246
|
+
TAllowed extends ElementType = ElementType> {
|
|
197
247
|
default: TDefault;
|
|
198
248
|
props: Props;
|
|
199
249
|
variants: Variants;
|
|
200
250
|
preset: TPreset;
|
|
201
251
|
allowed: TAllowed;
|
|
202
252
|
}
|
|
253
|
+
/** This component's variant definitions. See `PolymorphicGenerics`'s `Variants` parameter. */
|
|
203
254
|
type VariantsOf<T extends PolymorphicGenerics> = T['variants'];
|
|
255
|
+
/** This component's named presets. See `PolymorphicGenerics`'s `TPreset` parameter. */
|
|
204
256
|
type RecipeOf<T extends PolymorphicGenerics> = T['preset'];
|
|
257
|
+
/** The set of elements/tags this component may render as via `as`. See `PolymorphicGenerics`'s
|
|
258
|
+
* `TAllowed` parameter. */
|
|
205
259
|
type AllowedOf<T extends PolymorphicGenerics> = T['allowed'];
|
|
260
|
+
/** The element/tag this component renders as by default. See `PolymorphicGenerics`'s `TDefault`
|
|
261
|
+
* parameter. */
|
|
206
262
|
type DefaultOf<T extends PolymorphicGenerics> = T['default'];
|
|
263
|
+
/** This component's own declared props, before variants are mixed in. See `PolymorphicGenerics`'s
|
|
264
|
+
* `Props` parameter. */
|
|
207
265
|
type PropsOf<T extends PolymorphicGenerics> = T['props'];
|
|
208
266
|
|
|
209
267
|
type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
|
|
@@ -236,7 +294,7 @@ interface BaseClassOptions {
|
|
|
236
294
|
type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string | undefined;
|
|
237
295
|
|
|
238
296
|
interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
|
|
239
|
-
recipeMap?:
|
|
297
|
+
recipeMap?: StringMap<RecipeTarget<TVariants>>;
|
|
240
298
|
}
|
|
241
299
|
|
|
242
300
|
interface TagMapOptions {
|
|
@@ -405,7 +463,7 @@ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPre
|
|
|
405
463
|
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
406
464
|
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
407
465
|
*/
|
|
408
|
-
readonly precomputedClasses?: Readonly<
|
|
466
|
+
readonly precomputedClasses?: Readonly<StringMap<string>>;
|
|
409
467
|
};
|
|
410
468
|
|
|
411
469
|
type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
@@ -654,14 +712,52 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
|
|
|
654
712
|
* `React.ComponentProps`.
|
|
655
713
|
*/
|
|
656
714
|
(props: PolymorphicProps<G, DefaultOf<G>>): ReactElement;
|
|
715
|
+
/**
|
|
716
|
+
* Type-only; never assigned at runtime. See `HasGenerics<G>` (`@praxis-kit/contract-props`) for
|
|
717
|
+
* the full rationale — kept as an inline field rather than `HasGenerics<G> & {...}` because
|
|
718
|
+
* intersecting it onto this callable type changes how `PolymorphicComponent<any>` (used by
|
|
719
|
+
* test helpers like `box()`) resolves against concrete instantiations; structurally identical
|
|
720
|
+
* to `HasGenerics<G>` either way, which is what lets `ContractProps` constrain against it.
|
|
721
|
+
*/
|
|
722
|
+
readonly __generics?: G;
|
|
657
723
|
displayName?: string;
|
|
658
724
|
};
|
|
725
|
+
/**
|
|
726
|
+
* Recovers a built `PolymorphicComponent<G>`'s prop shape for a specific render mode, from
|
|
727
|
+
* outside the file that built it — the missing piece `React.ComponentProps<typeof Component>`
|
|
728
|
+
* can't provide, since it always resolves against `PolymorphicComponent`'s normal-mode fallback
|
|
729
|
+
* overload (see that type's own doc comment).
|
|
730
|
+
*
|
|
731
|
+
* ```tsx
|
|
732
|
+
* const Container = createContractComponent({ tag: 'div', name: 'Container', /* ... *\/ })
|
|
733
|
+
*
|
|
734
|
+
* // Normal-mode props (equivalent to ComponentProps<typeof Container>, but works for every mode):
|
|
735
|
+
* type ContainerProps = ContractProps<typeof Container>
|
|
736
|
+
*
|
|
737
|
+
* // A wrapper that always renders Container with asChild — ComponentProps<typeof Container>
|
|
738
|
+
* // fails here ("Type 'true' is not assignable to type 'false'"); ContractProps doesn't.
|
|
739
|
+
* type ContainerAsChildProps = ContractProps<typeof Container, 'asChild'>
|
|
740
|
+
* ```
|
|
741
|
+
*
|
|
742
|
+
* `T` accepts any built component value (`PolymorphicComponent<G>` or `CompoundComponent<G, S>` —
|
|
743
|
+
* the latter's sub-component intersection doesn't disturb `__generics`, which lives on the root
|
|
744
|
+
* call signature) via its own `__generics` marker; the `never` branch below only fires for a
|
|
745
|
+
* non-praxis-kit component, which has no `__generics` field to infer from at all.
|
|
746
|
+
*
|
|
747
|
+
* Always resolves against the component's *default* element (`PolymorphicWithAsChild<G,
|
|
748
|
+
* DefaultOf<G>>`, etc.) — the same ceiling `React.ComponentProps<typeof Component>` already has
|
|
749
|
+
* for its one mode, not a new limitation `ContractProps` introduces. `ContractProps<typeof
|
|
750
|
+
* Button>` is "`Button`'s contract for its default element," not a substitute for
|
|
751
|
+
* `PolymorphicProps<G, 'a'>` when a caller needs a specific non-default `as` — those remain two
|
|
752
|
+
* different questions with two different answers.
|
|
753
|
+
*/
|
|
754
|
+
type ContractProps<T extends HasGenerics<PolymorphicGenerics>, M extends Mode = 'normal'> = T extends HasGenerics<infer G extends PolymorphicGenerics> ? PickMode<M, PolymorphicProps<G, DefaultOf<G>>, PolymorphicWithAsChild<G, DefaultOf<G>>, PolymorphicWithRender<G, DefaultOf<G>>> : never;
|
|
659
755
|
|
|
660
756
|
/** Structural subset of `CompiledComponentArtifact` consumed by the React adapter. */
|
|
661
757
|
interface CompiledArtifact {
|
|
662
758
|
readonly definition: ComponentDefinition;
|
|
663
759
|
readonly precomputed?: {
|
|
664
|
-
readonly variantLookup?:
|
|
760
|
+
readonly variantLookup?: StringMap<string>;
|
|
665
761
|
};
|
|
666
762
|
}
|
|
667
763
|
/**
|
|
@@ -682,4 +778,4 @@ type ReactFactoryOptions<TDefault extends ElementType, Props extends UnknownProp
|
|
|
682
778
|
artifact?: CompiledArtifact;
|
|
683
779
|
};
|
|
684
780
|
|
|
685
|
-
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 };
|
|
781
|
+
export { type AnyClassPluginFactory as A, type ContractProps as C, 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
|
@@ -189,20 +189,75 @@ type DefaultVariants<V extends VariantMap> = {
|
|
|
189
189
|
* Presets are named bundles of variant props that callers activate by key,
|
|
190
190
|
* avoiding the need to repeat variant combinations at each call site.
|
|
191
191
|
*/
|
|
192
|
-
type RecipeMap<V extends VariantMap = VariantMap> = Readonly<
|
|
192
|
+
type RecipeMap<V extends VariantMap = VariantMap> = Readonly<StringMap<VariantSelection<V>>>;
|
|
193
193
|
|
|
194
194
|
type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
/**
|
|
197
|
+
* The framework-neutral descriptor for a single praxis-kit component's contract — every render
|
|
198
|
+
* mechanism (tag resolution, prop merging, classes, ARIA) and every framework adapter's
|
|
199
|
+
* component type is built from this one shape. Deliberately just data: five type parameters and
|
|
200
|
+
* their corresponding properties, with no notion of JSX, call signatures, refs, or any
|
|
201
|
+
* framework-specific rendering concern. Each adapter (React, Vue, Svelte, Solid, Lit, Web) builds
|
|
202
|
+
* its own idiomatic component type on top of a `PolymorphicGenerics<...>` instantiation — see
|
|
203
|
+
* `PolymorphicComponent<G>` (`adapters/react/src/shared/types/polymorphic-props.ts`) for the
|
|
204
|
+
* React example — rather than this interface knowing anything about any of them.
|
|
205
|
+
*
|
|
206
|
+
* Use the `*Of<T>` accessor aliases below (`DefaultOf<G>`, `PropsOf<G>`, etc.) to read a single
|
|
207
|
+
* field back out of an already-resolved `G`, instead of indexing `G['default']` etc. directly at
|
|
208
|
+
* call sites — same rationale as any accessor: the property name stays an implementation detail,
|
|
209
|
+
* and every reader benefits together if it ever needs to change.
|
|
210
|
+
*/
|
|
211
|
+
interface PolymorphicGenerics<
|
|
212
|
+
/**
|
|
213
|
+
* The element/tag this component renders as when the consumer doesn't override it via `as`
|
|
214
|
+
* (`AllowedOf<G>` permitting) — e.g. `'button'`, `'div'`. Defaults to the widest `ElementType`
|
|
215
|
+
* so a generic `PolymorphicGenerics` reference (with nothing else specified) still compiles.
|
|
216
|
+
*/
|
|
217
|
+
TDefault extends ElementType = ElementType,
|
|
218
|
+
/**
|
|
219
|
+
* The props this specific component declares — its own contract, before variants are mixed
|
|
220
|
+
* in. Defaults to `AnyRecord` for the same "still compiles unspecified" reason as `TDefault`.
|
|
221
|
+
*/
|
|
222
|
+
Props extends AnyRecord = AnyRecord,
|
|
223
|
+
/**
|
|
224
|
+
* This component's variant definitions (e.g. `{ intent: { primary: ..., ghost: ... } }`).
|
|
225
|
+
* Constrained to `Readonly<VariantMap>` — not the wider `AnyRecord` — specifically so `TPreset`
|
|
226
|
+
* below can be expressed as `RecipeMap<Variants>` and get real per-variant-key checking,
|
|
227
|
+
* instead of falling back to an unconstrained `RecipeMap<VariantMap>`.
|
|
228
|
+
*/
|
|
229
|
+
Variants extends Readonly<VariantMap> = Readonly<VariantMap>,
|
|
230
|
+
/**
|
|
231
|
+
* Named presets (`RecipeMap<Variants>`) — bundles of variant selections a consumer activates
|
|
232
|
+
* by key instead of repeating the same variant combination at every call site. Tied to
|
|
233
|
+
* `Variants`, not `AnyRecord`, precisely so a preset can only ever select keys/values that
|
|
234
|
+
* `Variants` actually defines — an invalid preset is a type error, not a silent no-op.
|
|
235
|
+
* Defaults to `Readonly<EmptyRecord>` (no presets), which is the common case: a component can
|
|
236
|
+
* have variants without necessarily defining any named presets over them, and most don't.
|
|
237
|
+
*/
|
|
238
|
+
TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>,
|
|
239
|
+
/**
|
|
240
|
+
* The set of elements/tags a consumer is allowed to switch to via `as`. Defaults to the widest
|
|
241
|
+
* `ElementType`, under which `AllowedOf<G>` imposes no restriction at all (see
|
|
242
|
+
* `PolymorphicControlProps.as`'s own comment in the React adapter for the concrete effect this
|
|
243
|
+
* has at a component's actual call site).
|
|
244
|
+
*/
|
|
245
|
+
TAllowed extends ElementType = ElementType> {
|
|
197
246
|
default: TDefault;
|
|
198
247
|
props: Props;
|
|
199
248
|
variants: Variants;
|
|
200
249
|
preset: TPreset;
|
|
201
250
|
allowed: TAllowed;
|
|
202
251
|
}
|
|
252
|
+
/** This component's variant definitions. See `PolymorphicGenerics`'s `Variants` parameter. */
|
|
203
253
|
type VariantsOf<T extends PolymorphicGenerics> = T['variants'];
|
|
254
|
+
/** This component's named presets. See `PolymorphicGenerics`'s `TPreset` parameter. */
|
|
204
255
|
type RecipeOf<T extends PolymorphicGenerics> = T['preset'];
|
|
256
|
+
/** The element/tag this component renders as by default. See `PolymorphicGenerics`'s `TDefault`
|
|
257
|
+
* parameter. */
|
|
205
258
|
type DefaultOf<T extends PolymorphicGenerics> = T['default'];
|
|
259
|
+
/** This component's own declared props, before variants are mixed in. See `PolymorphicGenerics`'s
|
|
260
|
+
* `Props` parameter. */
|
|
206
261
|
type PropsOf<T extends PolymorphicGenerics> = T['props'];
|
|
207
262
|
|
|
208
263
|
type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
|
|
@@ -235,7 +290,7 @@ interface BaseClassOptions {
|
|
|
235
290
|
type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string | undefined;
|
|
236
291
|
|
|
237
292
|
interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
|
|
238
|
-
recipeMap?:
|
|
293
|
+
recipeMap?: StringMap<RecipeTarget<TVariants>>;
|
|
239
294
|
}
|
|
240
295
|
|
|
241
296
|
interface TagMapOptions {
|
|
@@ -404,7 +459,7 @@ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPre
|
|
|
404
459
|
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
405
460
|
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
406
461
|
*/
|
|
407
|
-
readonly precomputedClasses?: Readonly<
|
|
462
|
+
readonly precomputedClasses?: Readonly<StringMap<string>>;
|
|
408
463
|
};
|
|
409
464
|
|
|
410
465
|
type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
@@ -473,7 +528,6 @@ declare function defineContractComponent<O extends FactoryOptions>(options: O):
|
|
|
473
528
|
|
|
474
529
|
type UnknownProps = AnyRecord;
|
|
475
530
|
type SolidElement = JSX.Element;
|
|
476
|
-
type SlotRenderFn = (props: UnknownProps) => SolidElement;
|
|
477
531
|
|
|
478
532
|
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> & {
|
|
479
533
|
/**
|
|
@@ -492,10 +546,43 @@ type ControlProps<G extends PolymorphicGenerics, TAs extends ElementType> = Omit
|
|
|
492
546
|
ref?: (el: ElementRef<TAs>) => void;
|
|
493
547
|
};
|
|
494
548
|
type SharedProps<G extends PolymorphicGenerics, TAs extends ElementType> = Omit<IntrinsicJSXProps<TAs>, keyof ControlProps<G, TAs> | 'children' | 'ref'> & ControlProps<G, TAs>;
|
|
549
|
+
/**
|
|
550
|
+
* The exact props object an `asChild` render function receives at runtime, once defaults,
|
|
551
|
+
* variant classes, and ARIA role resolution have all run — see `buildSlotProps` in `render.tsx`.
|
|
552
|
+
* `PropsOf<G>` stays `Partial` for the same reason `AsChildProps` below does: the type system
|
|
553
|
+
* can't prove every prop actually received a default, only that the runtime *tried*. `class` is
|
|
554
|
+
* narrowed to a plain resolved `string` (not the wider `ClassName` a caller may pass in).
|
|
555
|
+
*
|
|
556
|
+
* `ref` is `(el: Element) => void` rather than `AsChildProps.ref`'s bare `unknown` — a render
|
|
557
|
+
* function's own job is spreading this object directly onto a concrete element (`(props) => <a
|
|
558
|
+
* {...props} />`), so it needs a callback-ref shape assignable to that element's own `ref` prop
|
|
559
|
+
* type; contravariance makes an `Element`-typed callback assignable to any more specific one
|
|
560
|
+
* (`(el: HTMLAnchorElement) => void`, etc.) without knowing `TAs` in advance. `AsChildProps.ref`
|
|
561
|
+
* itself stays `unknown` on purpose — that field types what a *caller* hands in before the render
|
|
562
|
+
* function has even run, not what the render function receives back out.
|
|
563
|
+
*
|
|
564
|
+
* `role` (the value `buildSlotProps` adds only when `isKnownAriaRole` narrows it) is deliberately
|
|
565
|
+
* left OFF this type entirely, rather than given any explicit type. Every candidate representation
|
|
566
|
+
* fails the same way `ref` almost did: Solid's own per-element JSX types (`AnchorHTMLAttributes
|
|
567
|
+
* ['role']`, etc.) each narrow `role` to only the ARIA roles valid for *that* element, a strict
|
|
568
|
+
* subset of the full ARIA vocabulary — so a `KnownAriaRole`-typed field fails to spread onto any
|
|
569
|
+
* of them, and unlike `ref`, there's no contravariance trick available for a plain string-literal
|
|
570
|
+
* property (`unknown` fails the same assignability check `KnownAriaRole` does; only `any` would
|
|
571
|
+
* satisfy every per-element union, and this codebase doesn't use `any`). Omitting the key entirely
|
|
572
|
+
* keeps `{...props}` spreads honest and compiling; a render function that specifically needs to
|
|
573
|
+
* read `role` off this object needs an explicit, locally-scoped cast to do so. Previously this
|
|
574
|
+
* whole parameter was bare `UnknownProps`, giving the render function no type checking at all.
|
|
575
|
+
*/
|
|
576
|
+
type ResolvedSlotProps<G extends PolymorphicGenerics> = Partial<OmitIndexSignature<PropsOf<G>>> & OmitIndexSignature<VariantProps<VariantsOf<G>>> & {
|
|
577
|
+
class?: string | undefined;
|
|
578
|
+
ref?: (el: Element) => void;
|
|
579
|
+
};
|
|
580
|
+
/** An `asChild` render function, receiving the fully-resolved `ResolvedSlotProps<G>`. */
|
|
581
|
+
type SlotRenderFn<G extends PolymorphicGenerics> = (props: ResolvedSlotProps<G>) => SolidElement;
|
|
495
582
|
type AsChildProps<G extends PolymorphicGenerics> = Partial<OmitIndexSignature<PropsOf<G>>> & OmitIndexSignature<VariantProps<VariantsOf<G>>> & {
|
|
496
583
|
as?: never;
|
|
497
584
|
asChild: true;
|
|
498
|
-
children: SlotRenderFn
|
|
585
|
+
children: SlotRenderFn<G>;
|
|
499
586
|
class?: ClassName | undefined;
|
|
500
587
|
recipe?: keyof RecipeOf<G>;
|
|
501
588
|
ref?: unknown;
|
|
@@ -517,6 +604,15 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
|
|
|
517
604
|
(props: PolymorphicProps<G, DefaultOf<G>>): JSX.Element;
|
|
518
605
|
displayName?: string;
|
|
519
606
|
};
|
|
607
|
+
/**
|
|
608
|
+
* A component's full prop contract — naming symmetry with React's/Preact's `ContractProps<T,
|
|
609
|
+
* Mode>` (`@praxis-kit/contract-props`), not a fix for a gap: Solid has no version of the
|
|
610
|
+
* overload-resolution ceiling those two adapters need a marker to work around. `PolymorphicProps<G,
|
|
611
|
+
* TAs>` already folds both render modes into one unioned type (rather than two separate types the
|
|
612
|
+
* way React/Preact split them), and `PolymorphicComponent<G>`'s fallback overload already returns
|
|
613
|
+
* that whole union — so this alias is just `PolymorphicProps<G>` under a familiar name.
|
|
614
|
+
*/
|
|
615
|
+
type ContractProps<G extends PolymorphicGenerics> = PolymorphicProps<G>;
|
|
520
616
|
|
|
521
617
|
/**
|
|
522
618
|
* Creates a polymorphic Solid component with praxis-kit contracts applied.
|
|
@@ -542,4 +638,4 @@ declare function createContractComponent<TDefault extends ElementType, Props ext
|
|
|
542
638
|
readonly subComponents?: TSubComponents;
|
|
543
639
|
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>>, TSubComponents>;
|
|
544
640
|
|
|
545
|
-
export { type AnyFactoryOptions, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type SolidFactoryOptions, createContractComponent, defineContractComponent };
|
|
641
|
+
export { type AnyFactoryOptions, type ContractProps, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type ResolvedSlotProps, type SlotRenderFn, type SolidFactoryOptions, createContractComponent, defineContractComponent };
|