praxis-kit 7.0.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/{chunk-35CJAOJW.js → chunk-EIKPSL26.js} +63 -6
- package/dist/codemod/index.js +121 -72
- package/dist/contract/index.d.ts +92 -0
- package/dist/guards/index.d.ts +6 -0
- package/dist/guards/index.js +4 -4
- package/dist/html/index.d.ts +6 -0
- package/dist/lit/index.d.ts +158 -6
- package/dist/lit/index.js +83 -9
- package/dist/preact/index.d.ts +164 -3
- package/dist/preact/index.js +104 -31
- package/dist/react/index.d.ts +26 -3
- package/dist/react/index.js +34 -8
- package/dist/react/legacy.d.ts +25 -3
- package/dist/react/legacy.js +17 -3
- package/dist/{react-options-Cm99IE5J.d.ts → react-options-BnjZpdVh.d.ts} +141 -3
- package/dist/solid/index.d.ts +163 -3
- package/dist/solid/index.js +100 -17
- package/dist/svelte/Polymorphic.svelte +25 -0
- package/dist/svelte/index.d.ts +231 -13
- package/dist/svelte/index.js +16 -8
- package/dist/tailwind/index.d.ts +12 -0
- package/dist/ts-plugin/index.cjs +5 -2
- package/dist/vite-plugin/index.d.ts +6 -0
- package/dist/vue/index.d.ts +166 -3
- package/dist/vue/index.js +119 -37
- package/dist/web/index.d.ts +132 -4
- package/dist/web/index.js +94 -13
- package/package.json +4 -4
|
@@ -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>
|
|
@@ -134,6 +147,18 @@
|
|
|
134
147
|
?.(tag)
|
|
135
148
|
?.evaluate(childArray, { tag, props: normalizedProps })
|
|
136
149
|
})
|
|
150
|
+
|
|
151
|
+
const onElement = $derived(bundle.onElement)
|
|
152
|
+
|
|
153
|
+
// Unlike the effect above, this runs in every environment (not dev-only) — onElement is a
|
|
154
|
+
// real runtime feature, not a diagnostic. Re-runs (cleaning up the previous call first, via
|
|
155
|
+
// the returned teardown) whenever hostEl changes identity, e.g. the resolved tag changes and
|
|
156
|
+
// Svelte mounts a new host element.
|
|
157
|
+
$effect(() => {
|
|
158
|
+
if (!hostEl) return
|
|
159
|
+
const cleanup = onElement?.(hostEl, () => normalizedProps)
|
|
160
|
+
return () => cleanup?.()
|
|
161
|
+
})
|
|
137
162
|
}
|
|
138
163
|
</script>
|
|
139
164
|
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -1,9 +1,72 @@
|
|
|
1
1
|
import { RequireAtLeastOne, Simplify, ReadonlyDeep } from 'type-fest';
|
|
2
2
|
import { Diagnostics, DiagnosticInput, DiagnosticsMode } 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>;
|
|
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>;
|
|
19
|
+
/**
|
|
20
|
+
* A compound component's named sub-components, for example
|
|
21
|
+
* `{ Header, Content, Footer }`.
|
|
22
|
+
*/
|
|
23
|
+
type SubComponentMap = Readonly<AnyRecord>;
|
|
24
|
+
/**
|
|
25
|
+
* Default `Variants` type for components that declare no variants.
|
|
26
|
+
*
|
|
27
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
28
|
+
* editor hovers remain self-descriptive.
|
|
29
|
+
*/
|
|
30
|
+
type NoVariants = Readonly<EmptyRecord>;
|
|
31
|
+
/**
|
|
32
|
+
* Default `TPreset` type for components that declare no named presets.
|
|
33
|
+
*
|
|
34
|
+
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
35
|
+
* editor hovers remain self-descriptive.
|
|
36
|
+
*/
|
|
37
|
+
type NoPreset = Readonly<EmptyRecord>;
|
|
38
|
+
/**
|
|
39
|
+
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
40
|
+
* props, including the no-plugin case.
|
|
41
|
+
*
|
|
42
|
+
* Structurally identical to `EmptyRecord`, but named separately so editor
|
|
43
|
+
* hovers remain self-descriptive.
|
|
44
|
+
*/
|
|
45
|
+
type NoPluginProps = EmptyRecord;
|
|
46
|
+
/**
|
|
47
|
+
* Determines whether an object type should be treated as empty.
|
|
48
|
+
*
|
|
49
|
+
* `keyof T` ignores call and construct signatures...
|
|
50
|
+
*/
|
|
51
|
+
type IsEmptyRecord<T extends object> = T extends (...args: never[]) => unknown ? false : T extends new (...args: never[]) => unknown ? false : keyof T extends never ? true : false;
|
|
52
|
+
/**
|
|
53
|
+
* Merges two object types while eliding empty operands.
|
|
54
|
+
*
|
|
55
|
+
* If either operand is {@link EmptyRecord}, the other operand is returned
|
|
56
|
+
* directly instead of producing intersections such as
|
|
57
|
+
* `Component & EmptyRecord` in editor hovers.
|
|
58
|
+
*
|
|
59
|
+
* Unlike a homomorphic mapped type (for example `Simplify<T>`), this preserves
|
|
60
|
+
* call and construct signatures. Many component types are callable objects,
|
|
61
|
+
* and mapped types silently discard those signatures.
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* Instantiate `MergeRecords` directly. Introducing an intermediate alias for
|
|
65
|
+
* one operand (for example `type C = PolymorphicComponent<G>`) can prevent
|
|
66
|
+
* `IsEmptyRecord` from evaluating eagerly, which breaks assignability under
|
|
67
|
+
* `exactOptionalPropertyTypes`.
|
|
68
|
+
*/
|
|
69
|
+
type MergeRecords<A extends object, B extends object> = IsEmptyRecord<A> extends true ? B : IsEmptyRecord<B> extends true ? A : A & B;
|
|
7
70
|
|
|
8
71
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
9
72
|
|
|
@@ -131,6 +194,7 @@ interface PolymorphicGenerics<TDefault extends ElementType = ElementType, Props
|
|
|
131
194
|
preset: TPreset;
|
|
132
195
|
allowed: TAllowed;
|
|
133
196
|
}
|
|
197
|
+
type PropsOf<T extends PolymorphicGenerics> = T['props'];
|
|
134
198
|
|
|
135
199
|
type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
|
|
136
200
|
type CompoundVariantConditionValue<V extends VariantMap, K extends keyof V> = VariantKey<V, K> | NonEmptyArray<VariantKey<V, K>>;
|
|
@@ -190,7 +254,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
190
254
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
191
255
|
* capability wiring). */
|
|
192
256
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
193
|
-
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ?
|
|
257
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
194
258
|
type PluginInstance<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer TProps> ? ClassPlugin<TProps> : undefined;
|
|
195
259
|
|
|
196
260
|
type AriaContext = {
|
|
@@ -255,6 +319,12 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
255
319
|
* `@praxis-kit/diagnostics`.
|
|
256
320
|
*/
|
|
257
321
|
readonly diagnostics?: Diagnostics | DiagnosticsMode;
|
|
322
|
+
/**
|
|
323
|
+
* ARIA/accessibility rules evaluated against the resolved tag and props on every render.
|
|
324
|
+
* Each rule is a function receiving the current context and returning zero or more
|
|
325
|
+
* violations, some of which can carry an auto-applicable fix (see `createRemoveAttributeRule`
|
|
326
|
+
* and friends in `praxis-kit/contract`).
|
|
327
|
+
*/
|
|
258
328
|
readonly aria?: readonly AriaRule[];
|
|
259
329
|
/**
|
|
260
330
|
* Rules that need `AriaPolicyEngine`'s fix-application/caching machinery
|
|
@@ -266,6 +336,11 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
266
336
|
* misleading `aria` name to get the machinery it needs.
|
|
267
337
|
*/
|
|
268
338
|
readonly rules?: readonly AriaRule[];
|
|
339
|
+
/**
|
|
340
|
+
* Declares which children are valid, by name, match predicate, and cardinality (e.g. "at
|
|
341
|
+
* least 1, at most 4 `Button` children"). Open by default — children matching no rule are
|
|
342
|
+
* still allowed unless `exclusiveChildren` is set.
|
|
343
|
+
*/
|
|
269
344
|
readonly children?: readonly ChildRuleInput[];
|
|
270
345
|
/**
|
|
271
346
|
* When true, only children matching a `children` rule (or text, per `allowText`)
|
|
@@ -278,19 +353,49 @@ type EnforcementOptions<TAllowed extends ElementType = ElementType> = {
|
|
|
278
353
|
* or any listed rule. Default: true.
|
|
279
354
|
*/
|
|
280
355
|
readonly allowText?: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* Prop transforms composed with the component's own `normalize` (from `FactoryOptions`) and
|
|
358
|
+
* run before it. Unlike `normalize`, these live in the enforcement bucket because they
|
|
359
|
+
* typically encode a built-in HTML/ARIA fact rather than component-specific behavior.
|
|
360
|
+
*/
|
|
281
361
|
readonly props?: readonly PropNormalizer[];
|
|
282
362
|
/** Restricts the `as` prop to this set of tags. Violations route through diagnostics. */
|
|
283
363
|
readonly allowedAs?: readonly TAllowed[];
|
|
284
364
|
};
|
|
285
365
|
|
|
286
366
|
type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = {
|
|
367
|
+
/** Class applied to every instance regardless of variant selection. */
|
|
287
368
|
readonly base?: ClassName;
|
|
369
|
+
/**
|
|
370
|
+
* Named variant groups (e.g. `intent`, `size`), each mapping its possible values to a
|
|
371
|
+
* class string. A consumer selects a value per group as a prop (`<Button intent="primary">`).
|
|
372
|
+
*/
|
|
288
373
|
readonly variants?: V;
|
|
374
|
+
/** Value used for a variant group when the consumer doesn't pass one explicitly. */
|
|
289
375
|
readonly defaults?: Partial<DefaultVariants<V>>;
|
|
376
|
+
/**
|
|
377
|
+
* Applies an extra class only when a specific *combination* of variant selections matches —
|
|
378
|
+
* for cases `variants` alone can't express (e.g. `intent: 'primary'` + `size: 'lg'` together
|
|
379
|
+
* need a class neither variant would add on its own).
|
|
380
|
+
*/
|
|
290
381
|
readonly compounds?: readonly CompoundVariant<V>[];
|
|
382
|
+
/**
|
|
383
|
+
* Named bundles of variant values, selectable as a single unit via the `recipe` prop (e.g.
|
|
384
|
+
* `<Button recipe="cta">` instead of setting `intent`/`size` individually).
|
|
385
|
+
*/
|
|
291
386
|
readonly presets?: TPreset;
|
|
387
|
+
/** Maps a resolved tag directly to a raw class string, independent of the variant system. */
|
|
292
388
|
readonly tags?: Readonly<TagMap>;
|
|
389
|
+
/**
|
|
390
|
+
* A `ClassPluginFactory` (e.g. the Tailwind layout pipeline) that extends class resolution
|
|
391
|
+
* with its own owned props, layered on top of `variants`/`presets`/`tags`.
|
|
392
|
+
*/
|
|
293
393
|
readonly plugin?: TPlugin;
|
|
394
|
+
/**
|
|
395
|
+
* A cache-key → resolved-class-string lookup for every statically-known variant
|
|
396
|
+
* combination, skipping runtime class computation entirely when a match is found. Normally
|
|
397
|
+
* generated by a build-time class-extraction plugin rather than hand-authored.
|
|
398
|
+
*/
|
|
294
399
|
readonly precomputedClasses?: Readonly<Record<string, string>>;
|
|
295
400
|
};
|
|
296
401
|
|
|
@@ -299,17 +404,51 @@ type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
|
299
404
|
}['normalize'];
|
|
300
405
|
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
301
406
|
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> = {
|
|
407
|
+
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
302
408
|
readonly tag?: TDefault;
|
|
409
|
+
/** Display name used in diagnostics, dev tools, and generated component naming. */
|
|
303
410
|
readonly name?: string;
|
|
411
|
+
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
304
412
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
413
|
+
/**
|
|
414
|
+
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
415
|
+
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
416
|
+
* that depends on live instance state or the real DOM element belongs in `onElement` instead.
|
|
417
|
+
*/
|
|
305
418
|
readonly normalize?: NormalizeFn<NoInfer<Props>>;
|
|
419
|
+
/** Variant groups, base classes, presets, and the optional class-resolution plugin. */
|
|
306
420
|
readonly styling?: StylingOptions<V, TPreset, TPlugin>;
|
|
421
|
+
/** ARIA rules, child-content contracts, and other runtime validation for this component. */
|
|
307
422
|
readonly enforcement?: EnforcementOptions<TAllowed>;
|
|
308
423
|
/**
|
|
309
424
|
* Adapter-resolved diagnostics default, spread in by `resolveAdapterCommonOptions`. Not meant to
|
|
310
425
|
* be set directly by component authors — use `enforcement.diagnostics` to override per component.
|
|
311
426
|
*/
|
|
312
427
|
readonly diagnostics?: Diagnostics;
|
|
428
|
+
/**
|
|
429
|
+
* Sub-components to attach to the generated root component, producing a
|
|
430
|
+
* compound component API (for example, `Card.Header`, `Card.Content`,
|
|
431
|
+
* and `Card.Footer`). Purely additive — has no effect on
|
|
432
|
+
* `enforcement.children`; author child rules explicitly if the component
|
|
433
|
+
* needs to validate its children.
|
|
434
|
+
*/
|
|
435
|
+
readonly subComponents?: SubComponentMap;
|
|
436
|
+
/**
|
|
437
|
+
* Called once per instance, when the real underlying DOM element first
|
|
438
|
+
* exists, in every adapter — via that adapter's own native mount
|
|
439
|
+
* lifecycle, never through the props/attribute pipeline. Use this for
|
|
440
|
+
* wiring that needs the actual element (native imperative methods like
|
|
441
|
+
* `dialogEl.showModal()`, native events like `close`/`cancel` that have
|
|
442
|
+
* no prop-based equivalent), not for anything expressible as a plain
|
|
443
|
+
* prop.
|
|
444
|
+
*
|
|
445
|
+
* `getProps` returns the instance's *current* resolved props at call
|
|
446
|
+
* time — read it from inside a listener registered once at mount, rather
|
|
447
|
+
* than re-subscribing on every prop change.
|
|
448
|
+
*
|
|
449
|
+
* Return a cleanup function to run when the instance unmounts.
|
|
450
|
+
*/
|
|
451
|
+
readonly onElement?: (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
|
|
313
452
|
};
|
|
314
453
|
|
|
315
454
|
type ResolvedFactoryOptions<TDefault extends ElementType = ElementType, Props extends AnyRecord = EmptyRecord, V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPreset extends RecipeMap<V> = Readonly<EmptyRecord>> = {
|
|
@@ -392,6 +531,57 @@ declare class ChildrenEvaluator extends InvariantBase {
|
|
|
392
531
|
|
|
393
532
|
declare function createPolymorphic2<TDefault extends ElementType, Props extends AnyRecord, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory>(options?: FactoryOptions<TDefault, Props, Variants, TPreset, TPlugin>): PolymorphicRuntime<TDefault, Props, Variants, Extract<keyof TPreset, string>, TPreset, PluginInstance<TPlugin>>;
|
|
394
533
|
|
|
534
|
+
/**
|
|
535
|
+
* Matches option types that declare child enforcement rules.
|
|
536
|
+
*
|
|
537
|
+
* This type is used to determine whether a
|
|
538
|
+
* {@link ChildrenEvaluator} should be included in a built bundle.
|
|
539
|
+
*/
|
|
540
|
+
type WithChildrenEnforcement = {
|
|
541
|
+
enforcement: {
|
|
542
|
+
children: readonly unknown[];
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
/**
|
|
546
|
+
* The bundle of child evaluation services produced when
|
|
547
|
+
* child enforcement rules are configured.
|
|
548
|
+
*/
|
|
549
|
+
type ChildrenEvaluatorBundle = {
|
|
550
|
+
childrenEvaluator: ChildrenEvaluator;
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* Conditionally includes a {@link ChildrenEvaluator} in the
|
|
554
|
+
* built bundle when child enforcement rules are present.
|
|
555
|
+
*
|
|
556
|
+
* When no child enforcement rules are configured, this type
|
|
557
|
+
* resolves to {@link EmptyRecord}, omitting the property
|
|
558
|
+
* entirely rather than making it optional. Consumers can
|
|
559
|
+
* safely narrow using:
|
|
560
|
+
*
|
|
561
|
+
* ```ts
|
|
562
|
+
* if ('childrenEvaluator' in bundle) {
|
|
563
|
+
* // bundle.childrenEvaluator is available
|
|
564
|
+
* }
|
|
565
|
+
* ```
|
|
566
|
+
*
|
|
567
|
+
* @typeParam TOptions - The component configuration options.
|
|
568
|
+
*/
|
|
569
|
+
type BuiltChildrenEvaluator<TOptions extends WithChildRules> = TOptions extends WithChildrenEnforcement ? ChildrenEvaluatorBundle : EmptyRecord;
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Determines whether a prop should be stripped before forwarding to the
|
|
573
|
+
* rendered element.
|
|
574
|
+
*
|
|
575
|
+
* Returning `true` excludes the prop from the output; returning `false`
|
|
576
|
+
* keeps it. This is the inverse polarity of `shouldForwardProp`-style
|
|
577
|
+
* predicates (Emotion/styled-components), where `true` means include.
|
|
578
|
+
*
|
|
579
|
+
* @param key - The prop name being evaluated.
|
|
580
|
+
* @param variantKeys - The set of configured variant prop names.
|
|
581
|
+
* @returns `true` to strip the prop; `false` to forward it.
|
|
582
|
+
*/
|
|
583
|
+
type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
584
|
+
|
|
395
585
|
declare class SlotValidator extends InvariantBase {
|
|
396
586
|
#private;
|
|
397
587
|
constructor(name: string, diagnostics: Diagnostics, elementTerm: string);
|
|
@@ -400,21 +590,11 @@ declare class SlotValidator extends InvariantBase {
|
|
|
400
590
|
assertSingleChild(count: number): void;
|
|
401
591
|
}
|
|
402
592
|
|
|
403
|
-
type FilterPredicate = (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
404
|
-
|
|
405
|
-
type BuiltChildrenEvaluator<TOptions extends WithChildRules> = TOptions extends {
|
|
406
|
-
enforcement: {
|
|
407
|
-
children: readonly unknown[];
|
|
408
|
-
};
|
|
409
|
-
} ? {
|
|
410
|
-
childrenEvaluator: ChildrenEvaluator;
|
|
411
|
-
} : EmptyRecord;
|
|
412
|
-
|
|
413
593
|
declare function defineContractComponent<O extends FactoryOptions>(options: O): <R>(factory: (options: O) => R) => R;
|
|
414
594
|
|
|
415
595
|
type UnknownProps = AnyRecord;
|
|
416
596
|
|
|
417
|
-
type SvelteFactoryOptions<TDefault extends ElementType, Props extends UnknownProps, Variants extends Readonly<VariantMap>, TPreset extends RecipeMap<Variants> =
|
|
597
|
+
type SvelteFactoryOptions<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> & {
|
|
418
598
|
/**
|
|
419
599
|
* Return true for any prop key that should be consumed but not forwarded to the DOM.
|
|
420
600
|
* Receives `runtime.options.variantKeys` as a convenience if needed.
|
|
@@ -424,12 +604,50 @@ type SvelteFactoryOptions<TDefault extends ElementType, Props extends UnknownPro
|
|
|
424
604
|
|
|
425
605
|
type TypedRuntime<G extends PolymorphicGenerics> = ReturnType<typeof createPolymorphic2<DefaultOf<G>, PropsOf<G>, VariantsOf<G>, RecipeOf<G>>>;
|
|
426
606
|
|
|
607
|
+
type OnElementFn<Props = unknown> = (element: Element, getProps: () => Readonly<Props>) => void | (() => void);
|
|
427
608
|
type BuiltRuntime<G extends PolymorphicGenerics = PolymorphicGenerics, TOptions extends WithChildRules = WithChildRules> = BuiltChildrenEvaluator<TOptions> & {
|
|
428
609
|
runtime: TypedRuntime<G>;
|
|
429
610
|
filterProps: FilterPredicate;
|
|
430
611
|
slotValidator: SlotValidator;
|
|
612
|
+
onElement?: OnElementFn<PropsOf<G>>;
|
|
431
613
|
};
|
|
432
614
|
|
|
433
|
-
|
|
615
|
+
/**
|
|
616
|
+
* Creates a praxis-kit contract bundle for use with Svelte's `<Polymorphic>` component.
|
|
617
|
+
*
|
|
618
|
+
* Unlike the other adapters, this returns a plain bundle object rather than a component —
|
|
619
|
+
* Svelte components must come from `.svelte` files, a compile-time constraint — so the bundle
|
|
620
|
+
* is passed as the `bundle` prop:
|
|
621
|
+
*
|
|
622
|
+
* ```ts
|
|
623
|
+
* // button.ts
|
|
624
|
+
* export const buttonBundle = createContractComponent({
|
|
625
|
+
* tag: 'button',
|
|
626
|
+
* name: 'Button',
|
|
627
|
+
* styling: {
|
|
628
|
+
* base: 'btn',
|
|
629
|
+
* variants: { intent: { primary: 'btn--primary', ghost: 'btn--ghost' } },
|
|
630
|
+
* defaults: { intent: 'primary' },
|
|
631
|
+
* },
|
|
632
|
+
* })
|
|
633
|
+
* ```
|
|
634
|
+
*
|
|
635
|
+
* ```svelte
|
|
636
|
+
* <!-- Button.svelte -->
|
|
637
|
+
* <script lang="ts">
|
|
638
|
+
* import Polymorphic from 'praxis-kit/svelte/Polymorphic.svelte'
|
|
639
|
+
* import { buttonBundle } from './button'
|
|
640
|
+
* </script>
|
|
641
|
+
* <Polymorphic bundle={buttonBundle} intent="ghost" as="a" href="/home">Home</Polymorphic>
|
|
642
|
+
* ```
|
|
643
|
+
*
|
|
644
|
+
* Pass `subComponents` to attach named sub-components (`Card.Header`) — `Object.assign` works
|
|
645
|
+
* the same way on a plain bundle as on a component function/class, so `Card.Header` is itself
|
|
646
|
+
* just another bundle, passed to its own `<Polymorphic bundle={Card.Header}>`. Pass `onElement`
|
|
647
|
+
* to run setup once the real DOM element exists.
|
|
648
|
+
*/
|
|
649
|
+
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, TOptions extends WithChildRules = SvelteFactoryOptions<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>>(options: SvelteFactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & TOptions & {
|
|
650
|
+
readonly subComponents?: TSubComponents;
|
|
651
|
+
}): MergeRecords<BuiltRuntime<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>, TOptions>, TSubComponents>;
|
|
434
652
|
|
|
435
653
|
export { type AnyFactoryOptions, type BuiltRuntime, type ElementType, type EmptyRecord, type FilterPredicate, type PolymorphicGenerics, type SvelteFactoryOptions, type UnknownProps, type WithChildRules, createContractComponent, defineContractComponent };
|
package/dist/svelte/index.js
CHANGED
|
@@ -3,6 +3,12 @@ function defineContractComponent(options) {
|
|
|
3
3
|
return (factory) => factory(options);
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
// ../../lib/adapter-utils/src/runtime/assemble-compound-component.ts
|
|
7
|
+
function assembleCompoundComponent(root, subComponents) {
|
|
8
|
+
if (!subComponents) return root;
|
|
9
|
+
return Object.assign(root, subComponents);
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
// ../../lib/primitive/src/tag/resolve-tag.ts
|
|
7
13
|
function makeResolveTag(defaultTag) {
|
|
8
14
|
return function tag(as) {
|
|
@@ -48,7 +54,7 @@ function isNumber(value) {
|
|
|
48
54
|
|
|
49
55
|
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
50
56
|
function isDynamicRule(rule) {
|
|
51
|
-
return isObject(rule, true) && rule
|
|
57
|
+
return isObject(rule, true) && Reflect.get(rule, RULE_BRAND) === true;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
@@ -587,17 +593,17 @@ var COMPONENT_DEFAULT_TAG = /* @__PURE__ */ Symbol.for("praxis.component-default
|
|
|
587
593
|
// ../../lib/primitive/src/guards/children/is-tag.ts
|
|
588
594
|
function getAsProp(child) {
|
|
589
595
|
if (!isObject(child) || !("props" in child)) return void 0;
|
|
590
|
-
const props = child
|
|
596
|
+
const { props } = child;
|
|
591
597
|
if (!isObject(props)) return void 0;
|
|
592
|
-
const as = props
|
|
598
|
+
const as = Reflect.get(props, "as");
|
|
593
599
|
return isString(as) && as !== "" ? as : void 0;
|
|
594
600
|
}
|
|
595
601
|
function getTag(child) {
|
|
596
602
|
if (!isObject(child) || !("type" in child)) return void 0;
|
|
597
|
-
const t = child
|
|
603
|
+
const { type: t } = child;
|
|
598
604
|
if (isString(t)) return t;
|
|
599
605
|
if (typeof t === "function" || isObject(t)) {
|
|
600
|
-
const defaultTag = t
|
|
606
|
+
const defaultTag = Reflect.get(t, COMPONENT_DEFAULT_TAG);
|
|
601
607
|
if (!isString(defaultTag)) return void 0;
|
|
602
608
|
return getAsProp(child) ?? defaultTag;
|
|
603
609
|
}
|
|
@@ -2767,7 +2773,7 @@ function getChildProp(child, key) {
|
|
|
2767
2773
|
if (!isVNodeLike(child)) return void 0;
|
|
2768
2774
|
const { props } = child;
|
|
2769
2775
|
if (!isObject(props)) return void 0;
|
|
2770
|
-
return props
|
|
2776
|
+
return Reflect.get(props, key);
|
|
2771
2777
|
}
|
|
2772
2778
|
|
|
2773
2779
|
// ../core/src/html/contracts/aria/landmarks.ts
|
|
@@ -3440,15 +3446,17 @@ function buildRuntime(options) {
|
|
|
3440
3446
|
runtime,
|
|
3441
3447
|
filterProps,
|
|
3442
3448
|
slotValidator,
|
|
3443
|
-
...childrenEvaluator !== void 0 && { childrenEvaluator }
|
|
3449
|
+
...childrenEvaluator !== void 0 && { childrenEvaluator },
|
|
3450
|
+
...options.onElement !== void 0 && { onElement: options.onElement }
|
|
3444
3451
|
};
|
|
3445
3452
|
}
|
|
3446
3453
|
|
|
3447
3454
|
// ../../adapters/svelte/src/create-contract-component.ts
|
|
3448
3455
|
function createContractComponent(options) {
|
|
3449
|
-
|
|
3456
|
+
const bundle = buildRuntime(
|
|
3450
3457
|
options
|
|
3451
3458
|
);
|
|
3459
|
+
return assembleCompoundComponent(bundle, options.subComponents);
|
|
3452
3460
|
}
|
|
3453
3461
|
export {
|
|
3454
3462
|
createContractComponent,
|
package/dist/tailwind/index.d.ts
CHANGED
|
@@ -17,8 +17,20 @@ import { RequireAtLeastOne, Simplify, ValueOf } from 'type-fest';
|
|
|
17
17
|
*/
|
|
18
18
|
declare const layoutKeys: readonly ["flex", "inline-flex", "grid", "inline-grid", "block", "inline-block", "inline", "hidden", "contents", "flow-root", "list-item", "table", "inline-table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row-group", "table-row"];
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* A string-keyed object whose values are of type `T`.
|
|
22
|
+
*/
|
|
20
23
|
type StringMap<T = unknown> = Record<string, T>;
|
|
24
|
+
/**
|
|
25
|
+
* A string-keyed object with values of unknown type.
|
|
26
|
+
*/
|
|
21
27
|
type AnyRecord = StringMap<unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* An object type with no named properties.
|
|
30
|
+
*
|
|
31
|
+
* Unlike `{}`, this excludes arbitrary properties during type operations while
|
|
32
|
+
* still satisfying `extends object`.
|
|
33
|
+
*/
|
|
22
34
|
type EmptyRecord = Record<never, never>;
|
|
23
35
|
|
|
24
36
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
package/dist/ts-plugin/index.cjs
CHANGED
|
@@ -167,10 +167,13 @@ function init(modules) {
|
|
|
167
167
|
info.config.calleeNames ?? DEFAULT_CALLEE_NAMES
|
|
168
168
|
);
|
|
169
169
|
const proxy = /* @__PURE__ */ Object.create(null);
|
|
170
|
-
const proxyRecord = proxy;
|
|
171
170
|
for (const k of Object.keys(info.languageService)) {
|
|
172
171
|
const x = info.languageService[k];
|
|
173
|
-
|
|
172
|
+
Reflect.set(
|
|
173
|
+
proxy,
|
|
174
|
+
k,
|
|
175
|
+
typeof x === "function" ? x.bind(info.languageService) : x
|
|
176
|
+
);
|
|
174
177
|
}
|
|
175
178
|
proxy.getSemanticDiagnostics = (fileName) => {
|
|
176
179
|
const existing = info.languageService.getSemanticDiagnostics(fileName);
|
|
@@ -2,7 +2,13 @@ import { Plugin } from 'vite';
|
|
|
2
2
|
import { Except, Simplify } from 'type-fest';
|
|
3
3
|
import ts from 'typescript';
|
|
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>;
|
|
7
13
|
|
|
8
14
|
declare enum DiagnosticCategory {
|