praxis-kit 0.1.0 → 1.0.2
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/{build-runtime-CJ_nQEaZ.js → build-runtime-cNkW-D62.js} +331 -207
- package/dist/contract/index.d.ts +396 -14
- package/dist/contract/index.js +66 -1
- package/dist/eslint/index.js +11 -5
- package/dist/{index-BIBd_iPD.d.ts → index-zJDSXTxL.d.ts} +366 -67
- package/dist/lit/index.d.ts +267 -55
- package/dist/lit/index.js +275 -215
- package/dist/preact/index.d.ts +296 -52
- package/dist/preact/index.js +277 -210
- package/dist/react/index.d.ts +13 -4
- package/dist/react/index.js +22 -72
- package/dist/react/legacy.d.ts +9 -4
- package/dist/react/legacy.js +14 -2
- package/dist/solid/index.d.ts +253 -40
- package/dist/solid/index.js +271 -210
- package/dist/svelte/index.d.ts +203 -33
- package/dist/svelte/index.js +270 -207
- package/dist/tailwind/index.d.ts +12 -1
- package/dist/vite-plugin/index.js +289 -199
- package/dist/vue/index.d.ts +252 -41
- package/dist/vue/index.js +277 -210
- package/dist/web/index.d.ts +287 -53
- package/dist/web/index.js +275 -215
- package/package.json +5 -5
package/dist/vue/index.d.ts
CHANGED
|
@@ -25,20 +25,6 @@ type EmptyRecord = Record<never, never>;
|
|
|
25
25
|
* `{ Header, Content, Footer }`.
|
|
26
26
|
*/
|
|
27
27
|
type SubComponentMap = Readonly<AnyRecord>;
|
|
28
|
-
/**
|
|
29
|
-
* Default `Variants` type for components that declare no variants.
|
|
30
|
-
*
|
|
31
|
-
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
32
|
-
* editor hovers remain self-descriptive.
|
|
33
|
-
*/
|
|
34
|
-
type NoVariants = Readonly<EmptyRecord>;
|
|
35
|
-
/**
|
|
36
|
-
* Default `TPreset` type for components that declare no named presets.
|
|
37
|
-
*
|
|
38
|
-
* Structurally identical to `Readonly<EmptyRecord>`, but named separately so
|
|
39
|
-
* editor hovers remain self-descriptive.
|
|
40
|
-
*/
|
|
41
|
-
type NoPreset = Readonly<EmptyRecord>;
|
|
42
28
|
/**
|
|
43
29
|
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
44
30
|
* props, including the no-plugin case.
|
|
@@ -537,16 +523,6 @@ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPre
|
|
|
537
523
|
type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
538
524
|
normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
|
|
539
525
|
}['normalize'];
|
|
540
|
-
/**
|
|
541
|
-
* The type-erased shape of {@link FactoryOptions} — every generic parameter widened to its bound.
|
|
542
|
-
*
|
|
543
|
-
* Use it for a value that must hold *any* factory config (a registry, a generic wrapper). It
|
|
544
|
-
* cannot check `styling.compounds` conditions against the real variant keys/values, because it
|
|
545
|
-
* has forgotten what they are — for that, annotate against `FactoryOptions<...>` with the concrete
|
|
546
|
-
* generics (or `satisfies FactoryOptions<'button', Props, typeof variants>`), which keeps an
|
|
547
|
-
* invalid compound condition a type error rather than a silent no-op.
|
|
548
|
-
*/
|
|
549
|
-
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
550
526
|
/**
|
|
551
527
|
* The framework-neutral component-authoring config passed to `createContractComponent` in every
|
|
552
528
|
* adapter: default tag + name, own-prop defaults, a `normalize` transform, `styling` (variants,
|
|
@@ -556,7 +532,9 @@ type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, Reci
|
|
|
556
532
|
* `satisfies FactoryOptions<TDefault, Props, typeof variants, ...>` on a config object narrows
|
|
557
533
|
* `styling.compounds` conditions to the real per-variant-key shape — including resolving a
|
|
558
534
|
* boolean-shaped axis (`{ true, false }`) to a real `boolean` — so a condition naming a variant or
|
|
559
|
-
* value that does not exist is a compile error. `
|
|
535
|
+
* value that does not exist is a compile error. Leaving `V` at the bare `VariantMap` instead
|
|
536
|
+
* (whether via `FactoryOptions`'s own default or an explicit erased instantiation) forgets that
|
|
537
|
+
* shape entirely, so the same invalid condition becomes a silent no-op instead.
|
|
560
538
|
*/
|
|
561
539
|
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> = {
|
|
562
540
|
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
@@ -565,6 +543,33 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
565
543
|
readonly name?: string;
|
|
566
544
|
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
567
545
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
546
|
+
/**
|
|
547
|
+
* Optional, type-only declaration of this component's complete own-prop shape — present purely
|
|
548
|
+
* for type recovery, never read at runtime (see `declareProps` in `@praxis-kit/adapter-utils`).
|
|
549
|
+
*
|
|
550
|
+
* `defaults` alone can only prove a prop *has a default*, not that it's the complete prop model
|
|
551
|
+
* a component accepts — a `defaults: { size: 'md' }` component may still take `onClick`,
|
|
552
|
+
* `disabled`, and other props with no default at all, none of which a `defaults`-only recovery
|
|
553
|
+
* can see (see `ContractPropsFrom`'s own doc comment for the general shape of this problem).
|
|
554
|
+
* `props` closes that gap: when present, `ContractPropsOf<C>` / `ContractProps<typeof Component>`
|
|
555
|
+
* recover this declared type directly and exactly, in place of the necessarily-partial,
|
|
556
|
+
* literal-widened recovery `defaults` alone allows.
|
|
557
|
+
*
|
|
558
|
+
* Typed as `object | undefined`, not `NoInfer<Props> | undefined` like `defaults`/`onElement` —
|
|
559
|
+
* deliberately decoupled from this interface's own `Props` generic, unlike those two fields.
|
|
560
|
+
* `defaults`/`onElement` are tied to `Props` because real runtime code reads them against a
|
|
561
|
+
* concretely-resolved `Props` for a real call; `props` is never read at runtime at all (see
|
|
562
|
+
* above), so it has no such need, and tying it to `Props extends AnyRecord` would force every
|
|
563
|
+
* hand-declared prop `interface`/`type` an author passes through `declareProps<Props>()` to
|
|
564
|
+
* structurally satisfy `Record<string, unknown>` — a real TypeScript limitation (a named type
|
|
565
|
+
* without an index signature never satisfies that, even via plain assignment, only a fresh
|
|
566
|
+
* object literal does) that would make this field far more awkward to use for its one real job:
|
|
567
|
+
* carrying an author's own already-precise prop type through untouched. `ContractPropsFrom`
|
|
568
|
+
* (`contract-model.ts`) recovers the real value here structurally, straight off `O`'s own
|
|
569
|
+
* literal type — independent of this field's declared type, same as every other `Contract*From`
|
|
570
|
+
* derivation in that file.
|
|
571
|
+
*/
|
|
572
|
+
readonly props?: object | undefined;
|
|
568
573
|
/**
|
|
569
574
|
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
570
575
|
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
@@ -619,11 +624,158 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
619
624
|
*
|
|
620
625
|
* Return a cleanup function to run when the instance unmounts.
|
|
621
626
|
*/
|
|
622
|
-
readonly onElement?:
|
|
627
|
+
readonly onElement?: {
|
|
628
|
+
onElement(element: ElementForTag<TDefault | TAllowed>, getProps: () => Readonly<Props>): void | (() => void);
|
|
629
|
+
}['onElement'];
|
|
623
630
|
};
|
|
624
631
|
//#endregion
|
|
625
|
-
//#region ../../lib/
|
|
626
|
-
|
|
632
|
+
//#region ../../lib/primitive/src/types/factory/contract-model.d.ts
|
|
633
|
+
/**
|
|
634
|
+
* The pipeline this file implements:
|
|
635
|
+
*
|
|
636
|
+
* ```text
|
|
637
|
+
* O (a raw contract literal)
|
|
638
|
+
* → Contract*From<O> one derivation per dimension, straight off O's own shape
|
|
639
|
+
* → ContractDimensions<O> the six derivations, assembled
|
|
640
|
+
* → ContractModel<...> the same six values, as a required-field carrier
|
|
641
|
+
* → ContractModelOf<C> resolves an already-`defineContract`-ed C's real model,
|
|
642
|
+
* or reconstructs one from a raw C via ContractModelFrom
|
|
643
|
+
* ```
|
|
644
|
+
*
|
|
645
|
+
* See `DECISIONS.md`'s `defineContract` entry for the TypeScript limitations that shaped the
|
|
646
|
+
* derivations below.
|
|
647
|
+
*/
|
|
648
|
+
/**
|
|
649
|
+
* Canonical type-level representation of a contract's dimensions — the contract-level counterpart
|
|
650
|
+
* to `PolymorphicGenerics`. Every field is required, so a field's presence is never ambiguous the
|
|
651
|
+
* way it is on an optional `FactoryOptions` field.
|
|
652
|
+
*/
|
|
653
|
+
interface ContractModel<TDefault extends ElementType = ElementType, Props extends AnyRecord = AnyRecord, V extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends RecipeMap<VariantMap> = RecipeMap<VariantMap>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType> {
|
|
654
|
+
readonly tag: TDefault;
|
|
655
|
+
readonly props: Props;
|
|
656
|
+
readonly variants: V;
|
|
657
|
+
readonly preset: TPreset;
|
|
658
|
+
readonly plugin: TPlugin;
|
|
659
|
+
readonly allowed: TAllowed;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* The phantom-marker shape read back via `T extends HasContractModel<infer M> ? M : ...` — the
|
|
663
|
+
* contract-level counterpart to `lib/contract-props`'s `HasGenerics<G>`. Type-only: never assigned
|
|
664
|
+
* at runtime.
|
|
665
|
+
*
|
|
666
|
+
* `__model` is **required**, not optional like `HasGenerics<G>`'s `__generics?` — an optional field
|
|
667
|
+
* would make `C extends HasContractModel<infer M>` trivially succeed for any `C`, defeating the
|
|
668
|
+
* one thing this marker exists to answer: did `C` really go through `defineContract`?
|
|
669
|
+
*/
|
|
670
|
+
interface HasContractModel<M extends ContractModel = ContractModel> {
|
|
671
|
+
readonly __model: M;
|
|
672
|
+
}
|
|
673
|
+
type ContractTagFrom<O> = O extends {
|
|
674
|
+
tag: infer TDefault extends ElementType;
|
|
675
|
+
} ? TDefault : ElementType;
|
|
676
|
+
/** `'img'` → `string`, `1` → `number`, `true` → `boolean` — undoes `defineContract`'s `const O`
|
|
677
|
+
* literal narrowing so a `defaults` value doesn't become the only value a caller may pass. */
|
|
678
|
+
type WidenLiteral<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
679
|
+
type WidenShallow<T> = { [K in keyof T]: WidenLiteral<T[K]>; };
|
|
680
|
+
/** What the author explicitly declared, via `props: declareProps<Props>()`
|
|
681
|
+
* (`@praxis-kit/adapter-utils`) — used exactly as declared, no `Partial`/widening/`data-*`
|
|
682
|
+
* stripping (see `DefaultPropsFrom` for why those exist there but not here). */
|
|
683
|
+
type DeclaredPropsFrom<O> = O extends {
|
|
684
|
+
props: infer Props extends object | undefined;
|
|
685
|
+
} ? [NonNullable<Props>] extends [never] ? never : NonNullable<Props> & AnyRecord : never;
|
|
686
|
+
/** What can be inferred from `defaults` — partial at best, since a default only proves a prop
|
|
687
|
+
* *has* one, not that it's the complete prop set. `Partial`: a defaulted prop is optional to the
|
|
688
|
+
* caller by definition. `data-*` keys are dropped — every adapter has its own passthrough for
|
|
689
|
+
* those already (finding #43). */
|
|
690
|
+
type DefaultPropsFrom<O> = O extends {
|
|
691
|
+
defaults: infer Props extends AnyRecord;
|
|
692
|
+
} ? Partial<WidenShallow<Omit<Props, Extract<keyof Props, `data-${string}`>>>> : never;
|
|
693
|
+
/** Declared beats defaulted beats nothing. `[X] extends [never]`, not bare `X extends never` —
|
|
694
|
+
* tuple-wrapped so the check doesn't distribute if `X` is ever a union containing `never`. */
|
|
695
|
+
type ContractPropsFrom<O> = [DeclaredPropsFrom<O>] extends [never] ? [DefaultPropsFrom<O>] extends [never] ? EmptyRecord : DefaultPropsFrom<O> : DeclaredPropsFrom<O>;
|
|
696
|
+
type ContractVariantsFrom<O> = O extends {
|
|
697
|
+
styling: {
|
|
698
|
+
variants: infer V extends Readonly<VariantMap>;
|
|
699
|
+
};
|
|
700
|
+
} ? V : Readonly<EmptyRecord>;
|
|
701
|
+
type ContractPresetFrom<O> = O extends {
|
|
702
|
+
styling: {
|
|
703
|
+
presets: infer TPreset extends RecipeMap<VariantMap>;
|
|
704
|
+
};
|
|
705
|
+
} ? TPreset : Readonly<EmptyRecord>;
|
|
706
|
+
type ContractPluginFrom<O> = O extends {
|
|
707
|
+
styling: {
|
|
708
|
+
plugin: infer TPlugin extends AnyClassPluginFactory;
|
|
709
|
+
};
|
|
710
|
+
} ? TPlugin : AnyClassPluginFactory;
|
|
711
|
+
type ContractAllowedFrom<O> = O extends {
|
|
712
|
+
enforcement: {
|
|
713
|
+
allowedAs: readonly (infer TAllowed extends ElementType)[];
|
|
714
|
+
};
|
|
715
|
+
} ? TAllowed : ElementType;
|
|
716
|
+
/** The six derivations above, assembled — the direct input to `ContractModel`. */
|
|
717
|
+
type ContractDimensions<O> = {
|
|
718
|
+
readonly tag: ContractTagFrom<O>;
|
|
719
|
+
readonly props: ContractPropsFrom<O>;
|
|
720
|
+
readonly variants: ContractVariantsFrom<O>;
|
|
721
|
+
readonly preset: ContractPresetFrom<O>;
|
|
722
|
+
readonly plugin: ContractPluginFrom<O>;
|
|
723
|
+
readonly allowed: ContractAllowedFrom<O>;
|
|
724
|
+
};
|
|
725
|
+
/**
|
|
726
|
+
* Builds a `ContractModel` from a raw literal `O` — the fallback path `ContractModelOf<C>` uses
|
|
727
|
+
* when `C` never went through `defineContract` (no `__model` marker to read directly), and what
|
|
728
|
+
* `defineContract` itself attaches as that marker for a `C` that did.
|
|
729
|
+
*/
|
|
730
|
+
type ContractModelFrom<O> = ContractDimensions<O> extends (infer D extends ContractDimensions<O>) ? ContractModel<D['tag'], D['props'], D['variants'], D['preset'], D['plugin'], D['allowed']> : never;
|
|
731
|
+
/**
|
|
732
|
+
* Resolves "does `C` carry a real `ContractModel` already, or do we need to build one from its raw
|
|
733
|
+
* shape" — every `Contract*Of` accessor (`contract-of.ts`) is a one-line projection off this.
|
|
734
|
+
*/
|
|
735
|
+
type ContractModelOf<C> = C extends HasContractModel<infer M> ? M : ContractModelFrom<C>;
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region ../../lib/primitive/src/types/factory/contract-of.d.ts
|
|
738
|
+
/**
|
|
739
|
+
* `FactoryOptions`-level accessor family, mirroring `polymorphic-generics.ts`'s `*Of<T>`
|
|
740
|
+
* convention (`DefaultOf<G>`, `PropsOf<G>`, etc.) but applied one layer up, to a contract itself
|
|
741
|
+
* rather than to the `PolymorphicGenerics` an adapter derives from it.
|
|
742
|
+
*
|
|
743
|
+
* Named with a `Contract` prefix specifically to avoid colliding with `polymorphic-generics.ts`'s
|
|
744
|
+
* own `PropsOf`/`VariantsOf`/`RecipeOf`/`AllowedOf`/`DefaultOf` — both families are re-exported
|
|
745
|
+
* from `@praxis-kit/core`, so a name clash would be a real conflict, not a style nit.
|
|
746
|
+
*
|
|
747
|
+
* Each accessor is a trivial projection off `ContractModelOf<C>` (`contract-model.ts`) — the one
|
|
748
|
+
* place that resolves "does `C` carry a real `ContractModel` (via `defineContract`) or does one
|
|
749
|
+
* need reconstructing from `C`'s raw shape," so every accessor shares one implementation of that
|
|
750
|
+
* resolution rather than repeating it. See `contract-model.ts`'s own doc comments for the
|
|
751
|
+
* `ContractXFrom<O>` derivation each of these ultimately reads through, and `DECISIONS.md`'s
|
|
752
|
+
* `defineContract` entry for the design history behind the required-pattern-match technique.
|
|
753
|
+
*/
|
|
754
|
+
type ContractTagOf<C extends FactoryOptions> = ContractModelOf<C>['tag'];
|
|
755
|
+
/** See this file's own doc comment. Best-effort when `C` has no `ContractModel` marker — see
|
|
756
|
+
* `ContractPropsFrom`'s own doc comment for why. */
|
|
757
|
+
type ContractPropsOf<C extends FactoryOptions> = ContractModelOf<C>['props'];
|
|
758
|
+
/** See this file's own doc comment. */
|
|
759
|
+
type ContractVariantsOf<C extends FactoryOptions> = ContractModelOf<C>['variants'];
|
|
760
|
+
/** See this file's own doc comment. */
|
|
761
|
+
type ContractPresetOf<C extends FactoryOptions> = ContractModelOf<C>['preset'];
|
|
762
|
+
/** See this file's own doc comment. */
|
|
763
|
+
type ContractPluginOf<C extends FactoryOptions> = ContractModelOf<C>['plugin'];
|
|
764
|
+
//#endregion
|
|
765
|
+
//#region ../../lib/primitive/src/types/factory/contract-generics.d.ts
|
|
766
|
+
/**
|
|
767
|
+
* The canonical projection from a defined contract `C` to the `PolymorphicGenerics` shape every
|
|
768
|
+
* adapter's prop types are built from — the one place "G" gets computed, so it can no longer
|
|
769
|
+
* silently drift per adapter the way today's hand-assembled `PolymorphicGenerics<...>` instantiation
|
|
770
|
+
* at each `createContractComponent` call site can (see `ContractGenericsWithAllowedOf` below for
|
|
771
|
+
* the one confirmed instance of that drift).
|
|
772
|
+
*
|
|
773
|
+
* Folds the class-resolution plugin's own contributed props (`ExtractPluginProps<TPlugin>`) into
|
|
774
|
+
* `props` here, once, rather than leaving each adapter's `ContractProps` to re-derive that merge
|
|
775
|
+
* via its own distributive conditional type on every read — the root cause of the ~22-member
|
|
776
|
+
* layout-union bug PR #95 patched per-adapter (see `DECISIONS.md`'s `defineContract` entry).
|
|
777
|
+
*/
|
|
778
|
+
type ContractGenericsOf<C extends FactoryOptions> = PolymorphicGenerics<ContractTagOf<C>, MergeRecords<ContractPropsOf<C>, ExtractPluginProps<ContractPluginOf<C>>>, ContractVariantsOf<C>, ContractPresetOf<C>>;
|
|
627
779
|
//#endregion
|
|
628
780
|
//#region ../../adapters/vue/src/slot/Slottable.d.ts
|
|
629
781
|
type SlottableProps = {
|
|
@@ -641,7 +793,14 @@ export declare const Slottable: import("vue").DefineComponent<{}, () => import("
|
|
|
641
793
|
type UnknownProps = AnyRecord;
|
|
642
794
|
//#endregion
|
|
643
795
|
//#region ../../adapters/vue/src/vue-options.d.ts
|
|
644
|
-
|
|
796
|
+
/**
|
|
797
|
+
* Every generic parameter has a default (widened to that parameter's own *bound*, matching
|
|
798
|
+
* a wide-bound, type-erased philosophy, not `FactoryOptions`'s own narrower `EmptyRecord`-style
|
|
799
|
+
* defaults) so `VueFactoryOptions` can be used bare, as `createContractComponent`'s single
|
|
800
|
+
* `C extends VueFactoryOptions` constraint — see `ReactFactoryOptions`'s identical fix for the
|
|
801
|
+
* same reason.
|
|
802
|
+
*/
|
|
803
|
+
type VueFactoryOptions<TDefault extends ElementType = ElementType, Props extends UnknownProps = UnknownProps, Variants extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends RecipeMap<Variants> = RecipeMap<Variants>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory> = FactoryOptions<TDefault, Props, Variants, TPreset, TPlugin> & {
|
|
645
804
|
/**
|
|
646
805
|
* Return true for any prop key that should be consumed but not forwarded to
|
|
647
806
|
* the DOM. Variant keys are always stripped automatically.
|
|
@@ -649,6 +808,34 @@ type VueFactoryOptions<TDefault extends ElementType, Props extends UnknownProps,
|
|
|
649
808
|
filterProps?: (key: string, variantKeys: ReadonlySet<string>) => boolean;
|
|
650
809
|
};
|
|
651
810
|
//#endregion
|
|
811
|
+
//#region ../../lib/contract-props/src/has-contract.d.ts
|
|
812
|
+
/**
|
|
813
|
+
* The phantom-marker shape read back via `T extends HasContract<infer C> ? C : never` — the
|
|
814
|
+
* contract-retention counterpart to `HasGenerics<G>` in this same package. Where `HasGenerics<G>`
|
|
815
|
+
* lets a built component recover the `PolymorphicGenerics` an adapter derived for it,
|
|
816
|
+
* `HasContract<C>` lets it recover the *complete, authoritative contract* (`C`, the argument
|
|
817
|
+
* `createContractComponent<C extends XFactoryOptions>` was actually called with) it was derived
|
|
818
|
+
* from — the two are deliberately separate markers, not one broadened to do both jobs: `G` is
|
|
819
|
+
* "what the adapter needs to implement the component," `C` is "what the component was configured
|
|
820
|
+
* with" (see `DECISIONS.md`'s `defineContract` entry). A component carries both.
|
|
821
|
+
*
|
|
822
|
+
* Type-only: never assigned at runtime, same rationale as `HasGenerics<G>` (see that type's own
|
|
823
|
+
* doc comment) — a `createContractComponent` return value gets this shape via a type assertion,
|
|
824
|
+
* not a real property write.
|
|
825
|
+
*
|
|
826
|
+
* Unconstrained (no `C extends FactoryOptions` bound), matching `HasGenerics<G>`'s own choice —
|
|
827
|
+
* this package has no dependency on `@praxis-kit/core`/`@praxis-kit/primitive`, and adding one
|
|
828
|
+
* just to write a bound here isn't worth it: the accessor types that actually consume `C`
|
|
829
|
+
* (`ContractTagOf<C>`, etc., in `@praxis-kit/primitive`) already declare their own constraint.
|
|
830
|
+
*
|
|
831
|
+
* Do **not** "harden" this with a `unique symbol` or other nominal brand, for the same reason
|
|
832
|
+
* `HasGenerics<G>` doesn't: a real component's callable type needs to structurally satisfy this
|
|
833
|
+
* shape by declaring the same inline optional field, not by importing a nominal brand.
|
|
834
|
+
*/
|
|
835
|
+
interface HasContract<C> {
|
|
836
|
+
readonly __contract?: C;
|
|
837
|
+
}
|
|
838
|
+
//#endregion
|
|
652
839
|
//#region ../../adapters/vue/src/types/polymorphic-props.d.ts
|
|
653
840
|
type ControlProps<G extends PolymorphicGenerics, TAs extends ElementType> = PropsOf<G> & VariantProps<VariantsOf<G>> & {
|
|
654
841
|
as?: TAs;
|
|
@@ -681,22 +868,40 @@ type PolymorphicWithAsChild<G extends PolymorphicGenerics, TAs extends ElementTy
|
|
|
681
868
|
* inference for `as`, so HTML attribute narrowing based on the `as` value is
|
|
682
869
|
* not available — `UnknownProps` captures the open-ended attribute surface instead.
|
|
683
870
|
*/
|
|
684
|
-
type PolymorphicComponent<G extends PolymorphicGenerics> = {
|
|
871
|
+
type PolymorphicComponent<G extends PolymorphicGenerics, C extends FactoryOptions = FactoryOptions> = {
|
|
685
872
|
new (): {
|
|
686
873
|
$props: PolymorphicProps<G> | PolymorphicWithAsChild<G>;
|
|
687
874
|
};
|
|
875
|
+
/**
|
|
876
|
+
* Type-only; never assigned at runtime — same rationale as React's/Preact's `__contract` (see
|
|
877
|
+
* `HasContract<C>`, `@praxis-kit/contract-props`). Carries the *complete* contract this
|
|
878
|
+
* component was built from (`C`, the argument `createContractComponent<C extends
|
|
879
|
+
* VueFactoryOptions>` was actually called with). Unlike `G` (which was already an ordinary,
|
|
880
|
+
* directly-visible type parameter here — Vue's `new()` construct signature has no
|
|
881
|
+
* overload-resolution ceiling forcing a marker the way React's/Preact's overloaded callables
|
|
882
|
+
* do), `C` still needs one: nothing else on this type exposes the *complete* contract, only its
|
|
883
|
+
* `PolymorphicGenerics` projection. Defaults to the widest `FactoryOptions` so every existing
|
|
884
|
+
* one-argument `PolymorphicComponent<G>` reference keeps resolving exactly as before.
|
|
885
|
+
*/
|
|
886
|
+
readonly __contract?: C;
|
|
688
887
|
displayName?: string;
|
|
689
888
|
};
|
|
690
889
|
/**
|
|
691
|
-
* A component's full prop contract, both render modes at once —
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
*
|
|
890
|
+
* A component's full prop contract, both render modes at once — `PolymorphicComponent<G>`'s
|
|
891
|
+
* single `new()` construct signature already exposes both modes unioned together (`$props:
|
|
892
|
+
* PolymorphicProps<G> | PolymorphicWithAsChild<G>`), so this is that same union, projected from
|
|
893
|
+
* the component's retained `__contract` rather than a bare `G` the caller must already have in
|
|
894
|
+
* hand — `ContractProps<typeof Box>`, matching every other adapter, not `ContractProps<SomeG>`.
|
|
895
|
+
*
|
|
896
|
+
* An earlier version of this type took `G` directly (`ContractProps<G extends
|
|
897
|
+
* PolymorphicGenerics>`) — a genuinely different public shape, not a bug fix here: Vue's `new()`
|
|
898
|
+
* construct signature never had React's/Preact's overload-resolution ceiling, so there was no
|
|
899
|
+
* *forced* reason for a marker. Unified to `ContractProps<typeof Component>` now that `__contract`
|
|
900
|
+
* exists anyway (Phase 3 retention, needed regardless of this decision) and to match what this
|
|
901
|
+
* adapter's own README already documented — closing that doc/implementation mismatch rather than
|
|
902
|
+
* leaving it as a documentation-only fix.
|
|
698
903
|
*/
|
|
699
|
-
type ContractProps<G extends PolymorphicGenerics
|
|
904
|
+
type ContractProps<T extends HasContract<FactoryOptions>> = T extends HasContract<infer C extends FactoryOptions> ? ContractGenericsOf<C> extends (infer G extends PolymorphicGenerics) ? PolymorphicProps<G> | PolymorphicWithAsChild<G> : never : never;
|
|
700
905
|
//#endregion
|
|
701
906
|
//#region ../../adapters/vue/src/create-contract-component.d.ts
|
|
702
907
|
/**
|
|
@@ -721,9 +926,15 @@ type ContractProps<G extends PolymorphicGenerics> = PolymorphicProps<G> | Polymo
|
|
|
721
926
|
* Pass `subComponents` to attach named sub-components (`Card.Header`) and `onElement` to run
|
|
722
927
|
* setup once the real DOM element exists — both purely additive on top of the generated
|
|
723
928
|
* component.
|
|
929
|
+
*
|
|
930
|
+
* `TDefault`/`Props`/`Variants`/`TPreset`/`TPlugin` are each `ContractXOf<C>`-derived *defaults*
|
|
931
|
+
* on this function's own type parameter list, mirroring `@praxis-kit/react`'s identical fix — see
|
|
932
|
+
* that adapter's own doc comment for why (computed as function type-parameter defaults, not inline
|
|
933
|
+
* body computations, which doesn't resolve for a still-abstract `C`). No `TAllowed` here, matching
|
|
934
|
+
* this adapter's pre-refactor behavior — Vue never threaded it as its own generic.
|
|
724
935
|
*/
|
|
725
|
-
export declare function createContractComponent<TDefault extends ElementType
|
|
936
|
+
export declare function createContractComponent<C extends VueFactoryOptions, TDefault extends ElementType = ContractTagOf<C>, Props extends UnknownProps = ContractPropsOf<C>, Variants extends Readonly<VariantMap> = ContractVariantsOf<C>, TPreset extends RecipeMap<VariantMap> = ContractPresetOf<C>, TPlugin extends AnyClassPluginFactory = ContractPluginOf<C>, TSubComponents extends Readonly<AnyRecord> = EmptyRecord>(options: C & {
|
|
726
937
|
readonly subComponents?: TSubComponents;
|
|
727
|
-
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset
|
|
938
|
+
}): MergeRecords<PolymorphicComponent<PolymorphicGenerics<TDefault, MergeRecords<Props, ExtractPluginProps<TPlugin>>, Variants, TPreset>, C>, TSubComponents>;
|
|
728
939
|
//#endregion
|
|
729
|
-
export type {
|
|
940
|
+
export type { ContractProps, ElementType, EmptyRecord, FactoryOptions, PolymorphicComponent, PolymorphicGenerics, PolymorphicProps, PolymorphicWithAsChild, SlottableProps, VueFactoryOptions };
|