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
|
@@ -98,7 +98,13 @@ declare enum DiagnosticCode {
|
|
|
98
98
|
InternalError = "INTERNAL9000"
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* A string-keyed object whose values are of type `T`.
|
|
103
|
+
*/
|
|
101
104
|
type StringMap<T = unknown> = Record<string, T>;
|
|
105
|
+
/**
|
|
106
|
+
* A string-keyed object with values of unknown type.
|
|
107
|
+
*/
|
|
102
108
|
type AnyRecord = StringMap<unknown>;
|
|
103
109
|
|
|
104
110
|
declare enum Severity {
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import { Diagnostics as Diagnostics$1, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
2
2
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A string-keyed object whose values are of type `T`.
|
|
6
|
+
*/
|
|
4
7
|
type StringMap<T = unknown> = Record<string, T>;
|
|
8
|
+
/**
|
|
9
|
+
* A string-keyed object with values of unknown type.
|
|
10
|
+
*/
|
|
5
11
|
type AnyRecord = StringMap<unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* An object type with no named properties.
|
|
14
|
+
*
|
|
15
|
+
* Unlike `{}`, this excludes arbitrary properties during type operations while
|
|
16
|
+
* still satisfying `extends object`.
|
|
17
|
+
*/
|
|
6
18
|
type EmptyRecord = Record<never, never>;
|
|
7
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* A compound component's named sub-components, for example
|
|
21
|
+
* `{ Header, Content, Footer }`.
|
|
22
|
+
*/
|
|
8
23
|
type SubComponentMap = Readonly<AnyRecord>;
|
|
9
24
|
|
|
10
25
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
@@ -235,6 +250,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
235
250
|
* `@praxis-kit/diagnostics`.
|
|
236
251
|
*/
|
|
237
252
|
readonly diagnostics?: Diagnostics$1 | DiagnosticsMode;
|
|
253
|
+
/**
|
|
254
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
255
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
256
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
257
|
+
* and friends in `praxis-kit/contract`).
|
|
258
|
+
*/
|
|
238
259
|
readonly aria?: readonly AriaRule[];
|
|
239
260
|
/**
|
|
240
261
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -246,6 +267,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
246
267
|
* misleading `aria` name to get the machinery it needs.
|
|
247
268
|
*/
|
|
248
269
|
readonly rules?: readonly AriaRule[];
|
|
270
|
+
/**
|
|
271
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
272
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
273
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
274
|
+
*/
|
|
249
275
|
readonly children?: readonly ChildRuleInput[];
|
|
250
276
|
/**
|
|
251
277
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -258,19 +284,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
258
284
|
* or any listed rule. Default: true.
|
|
259
285
|
*/
|
|
260
286
|
readonly allowText?: boolean;
|
|
287
|
+
/**
|
|
288
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
289
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
290
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
291
|
+
*/
|
|
261
292
|
readonly props?: readonly PropNormalizer[];
|
|
262
293
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
263
294
|
readonly allowedAs?: readonly TAllowed[];
|
|
264
295
|
};
|
|
265
296
|
|
|
266
297
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
298
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
267
299
|
readonly base?: ClassName;
|
|
300
|
+
/**
|
|
301
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
302
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
303
|
+
*/
|
|
268
304
|
readonly variants?: V;
|
|
305
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
269
306
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
307
|
+
/**
|
|
308
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
309
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
310
|
+
* need a class neither variant would add on its own).
|
|
311
|
+
*/
|
|
270
312
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
313
|
+
/**
|
|
314
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
315
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
316
|
+
*/
|
|
271
317
|
readonly presets?: TPreset;
|
|
318
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
272
319
|
readonly tags?: Readonly<TagMap>;
|
|
320
|
+
/**
|
|
321
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
322
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
323
|
+
*/
|
|
273
324
|
readonly plugin?: TPlugin;
|
|
325
|
+
/**
|
|
326
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
327
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
328
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
329
|
+
*/
|
|
274
330
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
275
331
|
};
|
|
276
332
|
|
|
@@ -279,11 +335,21 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
279
335
|
}['normalize'];
|
|
280
336
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
281
337
|
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> = {
|
|
338
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
282
339
|
readonly tag?: TDefault;
|
|
340
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
283
341
|
readonly name?: string;
|
|
342
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
284
343
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
344
|
+
/**
|
|
345
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
346
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
347
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
348
|
+
*/
|
|
285
349
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
350
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
286
351
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
352
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
287
353
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
288
354
|
/**
|
|
289
355
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
package/dist/guards/index.d.ts
CHANGED
package/dist/html/index.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { ReadonlyDeep } from 'type-fest';
|
|
2
2
|
import { DiagnosticInput } from '../_shared/diagnostics.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A string-keyed object whose values are of type `T`.
|
|
6
|
+
*/
|
|
4
7
|
type StringMap<T = unknown> = Record<string, T>;
|
|
8
|
+
/**
|
|
9
|
+
* A string-keyed object with values of unknown type.
|
|
10
|
+
*/
|
|
5
11
|
type AnyRecord = StringMap<unknown>;
|
|
6
12
|
|
|
7
13
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
package/dist/lit/index.d.ts
CHANGED
|
@@ -2,11 +2,72 @@ import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
|
|
|
2
2
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } from '../_shared/diagnostics.js';
|
|
3
3
|
import { LitElement } from 'lit';
|
|
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
|
|
|
@@ -172,7 +233,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
172
233
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
173
234
|
* capability wiring). */
|
|
174
235
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
175
|
-
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ?
|
|
236
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
176
237
|
|
|
177
238
|
type AriaContext = {
|
|
178
239
|
readonly tag: IntrinsicTag;
|
|
@@ -236,6 +297,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
236
297
|
* `@praxis-kit/diagnostics`.
|
|
237
298
|
*/
|
|
238
299
|
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
300
|
+
/**
|
|
301
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
302
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
303
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
304
|
+
* and friends in `praxis-kit/contract`).
|
|
305
|
+
*/
|
|
239
306
|
readonly aria?: readonly AriaRule[];
|
|
240
307
|
/**
|
|
241
308
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -247,6 +314,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
247
314
|
* misleading `aria` name to get the machinery it needs.
|
|
248
315
|
*/
|
|
249
316
|
readonly rules?: readonly AriaRule[];
|
|
317
|
+
/**
|
|
318
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
319
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
320
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
321
|
+
*/
|
|
250
322
|
readonly children?: readonly ChildRuleInput[];
|
|
251
323
|
/**
|
|
252
324
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -259,19 +331,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
259
331
|
* or any listed rule. Default: true.
|
|
260
332
|
*/
|
|
261
333
|
readonly allowText?: boolean;
|
|
334
|
+
/**
|
|
335
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
336
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
337
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
338
|
+
*/
|
|
262
339
|
readonly props?: readonly PropNormalizer[];
|
|
263
340
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
264
341
|
readonly allowedAs?: readonly TAllowed[];
|
|
265
342
|
};
|
|
266
343
|
|
|
267
344
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
345
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
268
346
|
readonly base?: ClassName;
|
|
347
|
+
/**
|
|
348
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
349
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
350
|
+
*/
|
|
269
351
|
readonly variants?: V;
|
|
352
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
270
353
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
354
|
+
/**
|
|
355
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
356
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
357
|
+
* need a class neither variant would add on its own).
|
|
358
|
+
*/
|
|
271
359
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
360
|
+
/**
|
|
361
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
362
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
363
|
+
*/
|
|
272
364
|
readonly presets?: TPreset;
|
|
365
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
273
366
|
readonly tags?: Readonly<TagMap>;
|
|
367
|
+
/**
|
|
368
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
369
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
370
|
+
*/
|
|
274
371
|
readonly plugin?: TPlugin;
|
|
372
|
+
/**
|
|
373
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
374
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
375
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
376
|
+
*/
|
|
275
377
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
276
378
|
};
|
|
277
379
|
|
|
@@ -280,11 +382,21 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
280
382
|
}['normalize'];
|
|
281
383
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
282
384
|
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> = {
|
|
385
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
283
386
|
readonly tag?: TDefault;
|
|
387
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
284
388
|
readonly name?: string;
|
|
389
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
285
390
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
391
|
+
/**
|
|
392
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
393
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
394
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
395
|
+
*/
|
|
286
396
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
397
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
287
398
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
399
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
288
400
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
289
401
|
/**
|
|
290
402
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
|
@@ -317,6 +429,18 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
317
429
|
readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
|
|
318
430
|
};
|
|
319
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Determines whether a prop should be stripped before forwarding to the
|
|
434
|
+
* rendered element.
|
|
435
|
+
*
|
|
436
|
+
* Returning `true` excludes the prop from the output; returning `false`
|
|
437
|
+
* keeps it. This is the inverse polarity of `shouldForwardProp`-style
|
|
438
|
+
* predicates (Emotion/styled-components), where `true` means include.
|
|
439
|
+
*
|
|
440
|
+
* @param key - The prop name being evaluated.
|
|
441
|
+
* @param variantKeys - The set of configured variant prop names.
|
|
442
|
+
* @returns `true` to strip the prop; `false` to forward it.
|
|
443
|
+
*/
|
|
320
444
|
type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
321
445
|
|
|
322
446
|
declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
|
|
@@ -332,7 +456,7 @@ declare function defineContractComponent<O extends FactoryOptions>(options: O):
|
|
|
332
456
|
* Note: this adapter targets Light DOM composition only. Shadow DOM slot
|
|
333
457
|
* protocol is intentionally out of scope.
|
|
334
458
|
*/
|
|
335
|
-
type LitFactoryOptions<TDefault extends ElementType = ElementType, TProps extends AnyRecord = EmptyRecord, TVariants extends Readonly<VariantMap> =
|
|
459
|
+
type LitFactoryOptions<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> & {
|
|
336
460
|
readonly filterProps?: FilterPredicate;
|
|
337
461
|
};
|
|
338
462
|
|
|
@@ -344,14 +468,14 @@ type UnknownProps = AnyRecord;
|
|
|
344
468
|
* (which would trigger TS4094 in declaration emit). Variant key instance
|
|
345
469
|
* properties are typed via the TVariants parameter.
|
|
346
470
|
*/
|
|
347
|
-
type LitContractComponent<TVariants extends Readonly<VariantMap> =
|
|
348
|
-
new (): LitElement & {
|
|
471
|
+
type LitContractComponent<TVariants extends Readonly<VariantMap> = NoVariants, TPluginProps extends AnyRecord = EmptyRecord> = {
|
|
472
|
+
new (): MergeRecords<LitElement & {
|
|
349
473
|
as: string | undefined;
|
|
350
474
|
recipe: string | undefined;
|
|
351
475
|
praxisClass: string | undefined;
|
|
352
476
|
} & {
|
|
353
477
|
[K in Extract<keyof TVariants, string>]?: string | null;
|
|
354
|
-
}
|
|
478
|
+
}, TPluginProps>;
|
|
355
479
|
};
|
|
356
480
|
|
|
357
481
|
/**
|
|
@@ -374,9 +498,9 @@ type LitContractComponent<TVariants extends Readonly<VariantMap> = Readonly<Empt
|
|
|
374
498
|
* customElements.define('praxis-button', Button)
|
|
375
499
|
* ```
|
|
376
500
|
*/
|
|
377
|
-
declare function createContractComponent<TDefault extends ElementType, TProps extends UnknownProps = EmptyRecord, TVariants extends Readonly<VariantMap> =
|
|
501
|
+
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: LitFactoryOptions<TDefault, TProps, TVariants, TPreset, TPlugin> & {
|
|
378
502
|
readonly subComponents?: TSubComponents;
|
|
379
|
-
}): LitContractComponent<TVariants, ExtractPluginProps<TPlugin
|
|
503
|
+
}): MergeRecords<LitContractComponent<TVariants, ExtractPluginProps<TPlugin>>, TSubComponents>;
|
|
380
504
|
|
|
381
505
|
/**
|
|
382
506
|
* Renders a praxis-kit Lit component to an HTML string without requiring a DOM.
|
package/dist/preact/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 { ComponentChildren, VNode, ComponentType, JSX, Ref } from 'preact';
|
|
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
|
|
@@ -345,7 +457,7 @@ type UnknownProps = AnyRecord;
|
|
|
345
457
|
type SlotComponent = ComponentType<UnknownProps>;
|
|
346
458
|
type AnyVNode = VNode<any>;
|
|
347
459
|
|
|
348
|
-
type PreactFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> =
|
|
460
|
+
type PreactFactoryOptions<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> & {
|
|
349
461
|
/** Component used to render the asChild slot. Defaults to the built-in Slot. */
|
|
350
462
|
slotComponent?: SlotComponent;
|
|
351
463
|
/**
|
|
@@ -388,8 +500,29 @@ type PolymorphicComponent<G extends PolymorphicGenerics> = {
|
|
|
388
500
|
displayName?: string;
|
|
389
501
|
};
|
|
390
502
|
|
|
391
|
-
|
|
503
|
+
/**
|
|
504
|
+
* Creates a polymorphic Preact component with praxis-kit contracts applied.
|
|
505
|
+
*
|
|
506
|
+
* ```tsx
|
|
507
|
+
* const Button = createContractComponent({
|
|
508
|
+
* tag: 'button',
|
|
509
|
+
* name: 'Button',
|
|
510
|
+
* styling: {
|
|
511
|
+
* base: 'btn',
|
|
512
|
+
* variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
|
|
513
|
+
* defaults: { intent: 'primary' },
|
|
514
|
+
* },
|
|
515
|
+
* })
|
|
516
|
+
*
|
|
517
|
+
* <Button intent="ghost" as="a" href="/home">Home</Button>
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* Returns a `forwardRef` component — `ref` is forwarded to the rendered host element. Pass
|
|
521
|
+
* `subComponents` to attach named sub-components (`Card.Header`) and `onElement` to run setup
|
|
522
|
+
* once the real DOM element exists.
|
|
523
|
+
*/
|
|
524
|
+
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: PreactFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
|
|
392
525
|
readonly subComponents?: TSubComponents;
|
|
393
|
-
}): PolymorphicComponent<PolymorphicGenerics<TDefault, Props
|
|
526
|
+
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>>, TSubComponents>;
|
|
394
527
|
|
|
395
528
|
export { type AnyFactoryOptions, type ElementRef, type ElementType, type EmptyRecord, type PolymorphicComponent, type PolymorphicGenerics, type PolymorphicProps, type PolymorphicWithAsChild, type PreactFactoryOptions, Slottable, createContractComponent, defineContractComponent };
|