praxis-kit 4.0.0 → 4.0.3

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.
@@ -1,7 +1,313 @@
1
- import { ElementType, VariantMap, RecipeMap, EmptyRecord, ClassPluginFactory, AnyRecord, FactoryOptions, PolymorphicGenerics, createPolymorphic, ExtractPluginProps } from '@praxis-kit/core';
2
- export { AnyFactoryOptions, ElementType, EmptyRecord, PolymorphicGenerics } from '@praxis-kit/core';
3
- import { WithChildRules, BuiltChildrenEvaluator, FilterPredicate, SlotValidator } from '@praxis-kit/adapter-utils';
4
- export { FilterPredicate, WithChildRules, defineContractComponent } from '@praxis-kit/adapter-utils';
1
+ import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
2
+ import { Diagnostics, DiagnosticInput } from '../_shared/diagnostics.js';
3
+
4
+ type StringMap<T = unknown> = Record<string, T>;
5
+ type AnyRecord = StringMap<unknown>;
6
+
7
+ type IntrinsicTag = keyof HTMLElementTagNameMap;
8
+
9
+ type ElementType = IntrinsicTag | (string & {});
10
+
11
+ 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"];
12
+ type KnownAriaRole = (typeof KNOWN_ARIA_ROLES)[number];
13
+
14
+ type Booleanish = boolean | 'true' | 'false';
15
+ type ClassName = string | string[];
16
+ type EmptyRecord = Record<never, never>;
17
+ type NonEmptyArray<T> = [T, ...T[]];
18
+ type Numberish = number | `${number}`;
19
+ type Primitive = string | number | boolean;
20
+ type AriaRole = KnownAriaRole | (string & {});
21
+ type IntrinsicProps = AnyRecord & {
22
+ role?: AriaRole;
23
+ };
24
+ type TagMap = Partial<Record<IntrinsicTag | (string & {}), ClassName>>;
25
+
26
+ type MinMax = {
27
+ min: number;
28
+ max: number;
29
+ };
30
+ type CardinalityInput = Partial<MinMax>;
31
+
32
+ type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
33
+
34
+ type ChildRulePosition = 'first' | 'last' | 'any';
35
+
36
+ type ChildRuleInput<T = unknown, U extends T = T> = {
37
+ name: string;
38
+ match: ChildRuleMatch<T, U>;
39
+ cardinality?: CardinalityInput;
40
+ position?: ChildRulePosition;
41
+ /**
42
+ * Optional component-type reference for O(1) dispatch index.
43
+ * When provided for every rule, the matcher reads child.type instead of
44
+ * calling every match function on every child (O(n×m) → O(n+m)).
45
+ */
46
+ type?: unknown;
47
+ };
48
+
49
+ type WithChildRules = {
50
+ enforcement?: {
51
+ children?: readonly unknown[];
52
+ };
53
+ };
54
+
55
+ type ValidResult = {
56
+ valid: true;
57
+ };
58
+
59
+ type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
60
+ type CompoundVariantConditionValue<V extends VariantMap, K extends keyof V> = VariantKey<V, K> | NonEmptyArray<VariantKey<V, K>>;
61
+ type CompoundVariantConditions<V extends VariantMap> = Simplify<{
62
+ [K in keyof V]: CompoundVariantConditionValue<V, K>;
63
+ }>;
64
+ type CompoundVariantRequiredConditions<V extends VariantMap> = RequireAtLeastOneIfNotEmpty<CompoundVariantConditions<V>>;
65
+ type CompoundVariantBase<V extends VariantMap> = keyof V extends never ? EmptyRecord : CompoundVariantRequiredConditions<V>;
66
+ type CompoundVariant<V extends VariantMap> = CompoundVariantBase<V> & {
67
+ class: VariantValue;
68
+ };
69
+
70
+ interface CVACompounds<V extends VariantMap> {
71
+ compoundVariants?: readonly CompoundVariant<V>[];
72
+ }
73
+
74
+ interface CVADefaults<V extends VariantMap> {
75
+ defaultVariants?: DefaultVariants<V>;
76
+ }
77
+
78
+ interface CVAVariants<V extends VariantMap> {
79
+ variants?: V;
80
+ }
81
+
82
+ type StringToBoolean<T> = T extends 'true' | 'false' ? boolean : T;
83
+ type VariantValue = string | string[];
84
+ type VariantStates<K extends string = string> = Record<K, VariantValue>;
85
+ type VariantMap<V extends string = string, K extends string = string> = Record<V, VariantStates<K>>;
86
+ type VariantKey<V extends VariantMap, K extends keyof V> = StringToBoolean<keyof V[K] & string>;
87
+ /**
88
+ * A partial selection of variant states authored at factory definition time.
89
+ *
90
+ * Uses `keyof V[K]` directly (not `VariantKey`) so TypeScript can eagerly
91
+ * resolve the union at constraint-check time without deferred conditional types.
92
+ */
93
+ type VariantSelection<V extends VariantMap> = {
94
+ [K in keyof V]?: keyof V[K];
95
+ };
96
+ type NormalizedVariantValue<K extends string> = string extends K ? Primitive : K extends 'true' | 'false' ? Booleanish : K extends `${number}` ? Numberish : K;
97
+ type DefaultVariants<V extends VariantMap> = {
98
+ [K in keyof V]?: NormalizedVariantValue<keyof V[K] & string>;
99
+ };
100
+ /**
101
+ * A static, immutable map of named presets to partial variant selections.
102
+ *
103
+ * Presets are named bundles of variant props that callers activate by key,
104
+ * avoiding the need to repeat variant combinations at each call site.
105
+ */
106
+ type RecipeMap<V extends VariantMap = VariantMap> = Readonly<Record<string, VariantSelection<V>>>;
107
+ type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
108
+ interface PolymorphicGenerics<TDefault extends ElementType = ElementType, Props extends AnyRecord = AnyRecord, Variants extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TAllowed extends ElementType = ElementType> {
109
+ default: TDefault;
110
+ props: Props;
111
+ variants: Variants;
112
+ preset: TPreset;
113
+ allowed: TAllowed;
114
+ }
115
+
116
+ interface BaseClassOptions {
117
+ baseClassName?: ClassName;
118
+ }
119
+
120
+ type ClassPipelineFn = (tag: unknown, props: AnyRecord, className?: ClassName, recipe?: string) => string;
121
+
122
+ interface RecipeOptions<TVariants extends VariantMap = VariantMap> {
123
+ recipeMap?: Record<string, RecipeTarget<TVariants>>;
124
+ }
125
+
126
+ interface TagMapOptions {
127
+ tagMap?: TagMap;
128
+ }
129
+
130
+ type CompositionOptions<TVariants extends VariantMap = VariantMap> = Simplify<TagMapOptions & RecipeOptions<TVariants>>;
131
+
132
+ type CVASystemOptions<TVariants extends VariantMap = VariantMap> = Simplify<CVAVariants<TVariants> & CVADefaults<TVariants> & CVACompounds<TVariants>>;
133
+
134
+ type StyleOptions<TVariants extends VariantMap = VariantMap> = Simplify<BaseClassOptions & CVASystemOptions<TVariants>>;
135
+
136
+ type ClassPipelineOptions<TVariants extends VariantMap = VariantMap> = Simplify<StyleOptions<TVariants> & CompositionOptions<TVariants>>;
137
+
138
+ type OwnedPropKeys = ReadonlySet<string>;
139
+
140
+ type ClassPlugin<TProps extends AnyRecord = EmptyRecord> = Readonly<{
141
+ pipeline: ClassPipelineFn;
142
+ ownedKeys?: OwnedPropKeys;
143
+ readonly _pluginProps?: TProps;
144
+ }>;
145
+
146
+ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends VariantMap>(options: ClassPipelineOptions<V>, diagnostics: Diagnostics) => ClassPlugin<TProps>;
147
+ type ExtractPluginProps<TPlugin extends ClassPluginFactory<AnyRecord> | undefined> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? EmptyRecord : T : EmptyRecord;
148
+ type PluginInstance<TPlugin extends ClassPluginFactory<AnyRecord> | undefined> = TPlugin extends ClassPluginFactory<infer TProps> ? ClassPlugin<TProps> : undefined;
149
+
150
+ type AriaContext = {
151
+ readonly tag: IntrinsicTag;
152
+ readonly implicitRole: AriaRole | undefined;
153
+ readonly effectiveRole: string | undefined;
154
+ readonly props: ReadonlyDeep<IntrinsicProps>;
155
+ };
156
+
157
+ type RemoveAttributeFixKind = `removeAttribute:${string}`;
158
+ type InjectLiveFixKind = `injectLive:${string}`;
159
+ type FixKind = 'removeRole' | 'setRole' | 'normalizeRelevantAll' | RemoveAttributeFixKind | InjectLiveFixKind;
160
+
161
+ type AriaFixResult = {
162
+ applied: false;
163
+ next: ReadonlyDeep<IntrinsicProps>;
164
+ } | {
165
+ applied: true;
166
+ next: ReadonlyDeep<IntrinsicProps>;
167
+ previous: ReadonlyDeep<IntrinsicProps>;
168
+ };
169
+ type AriaFix = {
170
+ readonly kind: FixKind;
171
+ readonly priority?: number;
172
+ readonly source?: string;
173
+ readonly apply: (context: AriaContext) => AriaFixResult;
174
+ };
175
+
176
+ type Severity = 'error' | 'warning' | (string & {});
177
+
178
+ type AriaInvalidBase<M extends string = string> = {
179
+ valid: false;
180
+ severity: Severity;
181
+ message?: M;
182
+ attribute?: string;
183
+ diagnostic?: DiagnosticInput;
184
+ };
185
+ type AriaInvalidWithFix<M extends string = string> = AriaInvalidBase<M> & {
186
+ fixable: true;
187
+ fix: AriaFix;
188
+ };
189
+ type AriaInvalidWithoutFix<M extends string = string> = AriaInvalidBase<M> & {
190
+ fixable: false;
191
+ };
192
+ type AriaInvalidResult<M extends string = string> = AriaInvalidWithFix<M> | AriaInvalidWithoutFix<M>;
193
+ type AriaResult = ValidResult | AriaInvalidResult;
194
+
195
+ type AriaRule<C extends AriaContext = AriaContext> = (context: C) => readonly AriaResult[];
196
+
197
+ type PropNormalizer = (props: Readonly<AnyRecord & IntrinsicProps>) => Partial<AnyRecord & IntrinsicProps>;
198
+
199
+ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
200
+ readonly diagnostics?: Diagnostics;
201
+ readonly aria?: readonly AriaRule[];
202
+ readonly children?: readonly ChildRuleInput[];
203
+ readonly props?: readonly PropNormalizer[];
204
+ /** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
205
+ readonly allowedAs?: readonly TAllowed[];
206
+ };
207
+
208
+ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends ClassPluginFactory<AnyRecord> | undefined = ClassPluginFactory<AnyRecord> | undefined> = {
209
+ readonly base?: ClassName;
210
+ readonly variants?: V;
211
+ readonly defaults?: Partial<DefaultVariants<V>>;
212
+ readonly compounds?: readonly CompoundVariant<V>[];
213
+ readonly presets?: TPreset;
214
+ readonly tags?: Readonly<TagMap>;
215
+ readonly plugin?: TPlugin;
216
+ readonly precomputedClasses?: Readonly<Record<string, string>>;
217
+ };
218
+
219
+ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
220
+ normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
221
+ }['normalize'];
222
+ type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, ClassPluginFactory<AnyRecord> | undefined>;
223
+ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends ClassPluginFactory<AnyRecord> | undefined = ClassPluginFactory<AnyRecord> | undefined, TAllowed extends ElementType = ElementType> = {
224
+ readonly tag?: TDefault;
225
+ readonly name?: string;
226
+ readonly defaults?: Partial<NoInfer<Props>>;
227
+ readonly normalize?: NormalizeFn<NoInfer<Props>>;
228
+ readonly styling?: StylingOptions<V, TPreset, TPlugin>;
229
+ readonly enforcement?: EnforcementOptions<TAllowed>;
230
+ };
231
+
232
+ type ResolvedFactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>> = {
233
+ readonly defaultTag: TDefault;
234
+ readonly baseClassName?: ClassName;
235
+ readonly defaultProps?: Partial<Props>;
236
+ readonly tagMap?: Readonly<TagMap>;
237
+ readonly recipeMap?: TPreset;
238
+ readonly variants?: V;
239
+ readonly defaultVariants?: Partial<DefaultVariants<V>>;
240
+ readonly compoundVariants?: readonly CompoundVariant<V>[];
241
+ readonly displayName?: string;
242
+ readonly diagnostics: Diagnostics;
243
+ readonly variantKeys: ReadonlySet<string>;
244
+ readonly normalizeFn?: NormalizeFn<Props>;
245
+ readonly htmlPropNormalizersFn?: (tag: unknown) => readonly PropNormalizer[] | undefined;
246
+ readonly childRules?: readonly ChildRuleInput[];
247
+ readonly ariaRules?: readonly AriaRule[];
248
+ readonly allowedAs?: readonly ElementType[];
249
+ readonly precomputedClasses?: Readonly<Record<string, string>>;
250
+ };
251
+
252
+ type ResolveAriaFn = <P extends IntrinsicProps>(tag: ElementType, props: P) => {
253
+ props: P;
254
+ };
255
+
256
+ type ResolveClassNameFn<Props extends AnyRecord, TSlot extends string = never> = (tag: ElementType, props: Props, className?: ClassName, recipe?: TSlot) => string;
257
+
258
+ type ResolvePropsFn<Props extends AnyRecord> = <P extends Partial<Props>>(props: P) => Simplify<Omit<Props, keyof P> & P>;
259
+
260
+ type ResolveTagFn<TDefault extends ElementType> = <T extends ElementType | undefined = undefined>(as?: T) => T extends ElementType ? T : TDefault;
261
+
262
+ type RuntimePluginField<TPlugin extends ClassPlugin | undefined> = TPlugin extends ClassPlugin ? {
263
+ readonly classPlugin: TPlugin;
264
+ readonly hasStyling: true;
265
+ } : EmptyRecord;
266
+
267
+ type PolymorphicRuntime<TDefault extends ElementType, Props extends AnyRecord, Variants extends VariantMap, TSlot extends string = never, TPreset extends RecipeMap<Variants> = Readonly<Record<string, VariantSelection<Variants>>>, TPlugin extends ClassPlugin | undefined = ClassPlugin | undefined> = RuntimePluginField<TPlugin> & {
268
+ readonly options: Readonly<ResolvedFactoryOptions<TDefault, Props, Variants, TPreset>>;
269
+ readonly resolveTag: ResolveTagFn<TDefault>;
270
+ readonly resolveProps: ResolvePropsFn<Props>;
271
+ readonly resolveClasses: ResolveClassNameFn<Props, TSlot>;
272
+ readonly resolveAria: ResolveAriaFn;
273
+ };
274
+
275
+ declare abstract class InvariantBase {
276
+ private readonly diagnostics;
277
+ constructor(diagnostics: Diagnostics);
278
+ protected get active(): boolean;
279
+ protected violate(input: DiagnosticInput): void;
280
+ protected warn(input: DiagnosticInput): void;
281
+ protected invariant(condition: unknown, input: DiagnosticInput): void;
282
+ }
283
+
284
+ declare class ChildrenEvaluator extends InvariantBase {
285
+ #private;
286
+ constructor(rules: readonly ChildRuleInput[], diagnostics: Diagnostics, context?: string);
287
+ evaluate(children: unknown[]): void;
288
+ }
289
+
290
+ declare function createPolymorphic<TDefault extends ElementType, Props extends AnyRecord, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends ClassPluginFactory<AnyRecord> | undefined = ClassPluginFactory<AnyRecord> | undefined>(options?: FactoryOptions<TDefault, Props, Variants, TPreset, TPlugin>): PolymorphicRuntime<TDefault, Props, Variants, Extract<keyof TPreset, string>, TPreset, PluginInstance<TPlugin>>;
291
+
292
+ declare class SlotValidator extends InvariantBase {
293
+ #private;
294
+ constructor(name: string, diagnostics: Diagnostics, elementTerm: string);
295
+ assertExclusive(): void;
296
+ warnDiscardedChildren(count: number): void;
297
+ assertSingleChild(count: number): void;
298
+ }
299
+
300
+ type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
301
+
302
+ type BuiltChildrenEvaluator<TOptions extends WithChildRules> = TOptions extends {
303
+ enforcement: {
304
+ children: readonly unknown[];
305
+ };
306
+ } ? {
307
+ childrenEvaluator: ChildrenEvaluator;
308
+ } : EmptyRecord;
309
+
310
+ declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
5
311
 
6
312
  type UnknownProps = Record<string, unknown>;
7
313
 
@@ -23,4 +329,4 @@ type BuiltRuntime<G extends PolymorphicGenerics = PolymorphicGenerics, TOptions
23
329
 
24
330
  declare function createContractComponent<TDefault extends ElementType, Props extends UnknownProps = EmptyRecord, Variants extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends ClassPluginFactory<AnyRecord> | undefined = ClassPluginFactory<AnyRecord> | undefined, TOptions extends WithChildRules = SvelteFactoryOptions<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>>(options: SvelteFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & TOptions): BuiltRuntime<PolymorphicGenerics<TDefault, Props & ExtractPluginProps<TPlugin>, Variants, TPreset>, TOptions>;
25
331
 
26
- export { type BuiltRuntime, type SvelteFactoryOptions, type UnknownProps, createContractComponent };
332
+ export { type AnyFactoryOptions, type BuiltRuntime, type ElementType, type EmptyRecord, type FilterPredicate, type PolymorphicGenerics, type SvelteFactoryOptions, type UnknownProps, type WithChildRules, createContractComponent, defineContractComponent };