praxis-kit 0.1.1 → 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-DiPzmjWW.d.ts → index-zJDSXTxL.d.ts} +342 -66
- package/dist/lit/index.d.ts +251 -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 +271 -53
- package/dist/web/index.js +275 -215
- package/package.json +5 -5
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "clsx";
|
|
2
2
|
import { Diagnostic, DiagnosticInput, Diagnostics as Diagnostics$1, DiagnosticsMode } from "../_shared/diagnostics.js";
|
|
3
|
-
import { ReadonlyDeep, RequireAtLeastOne, Simplify } from "type-fest";
|
|
3
|
+
import { Except, ReadonlyDeep, RequireAtLeastOne, SetRequired, Simplify } from "type-fest";
|
|
4
4
|
//#region ../../lib/foundation/src/string-map.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* A string-keyed object whose values are of type `T`.
|
|
@@ -24,6 +24,38 @@ type EmptyRecord = Record<never, never>;
|
|
|
24
24
|
* `{ Header, Content, Footer }`.
|
|
25
25
|
*/
|
|
26
26
|
type SubComponentMap = Readonly<AnyRecord>;
|
|
27
|
+
/**
|
|
28
|
+
* Fallback for `ExtractPluginProps<TPlugin>` when a plugin contributes no
|
|
29
|
+
* props, including the no-plugin case.
|
|
30
|
+
*
|
|
31
|
+
* Structurally identical to `EmptyRecord`, but named separately so editor
|
|
32
|
+
* hovers remain self-descriptive.
|
|
33
|
+
*/
|
|
34
|
+
type NoPluginProps = EmptyRecord;
|
|
35
|
+
/**
|
|
36
|
+
* Determines whether an object type should be treated as empty.
|
|
37
|
+
*
|
|
38
|
+
* `keyof T` ignores call and construct signatures...
|
|
39
|
+
*/
|
|
40
|
+
type IsEmptyRecord<T extends object> = T extends ((...args: never[]) => unknown) ? false : T extends (new (...args: never[]) => unknown) ? false : keyof T extends never ? true : false;
|
|
41
|
+
/**
|
|
42
|
+
* Merges two object types while eliding empty operands.
|
|
43
|
+
*
|
|
44
|
+
* If either operand is {@link EmptyRecord}, the other operand is returned
|
|
45
|
+
* directly instead of producing intersections such as
|
|
46
|
+
* `Component & EmptyRecord` in editor hovers.
|
|
47
|
+
*
|
|
48
|
+
* Unlike a homomorphic mapped type (for example `Simplify<T>`), this preserves
|
|
49
|
+
* call and construct signatures. Many component types are callable objects,
|
|
50
|
+
* and mapped types silently discard those signatures.
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* Instantiate `MergeRecords` directly. Introducing an intermediate alias for
|
|
54
|
+
* one operand (for example `type C = PolymorphicComponent<G>`) can prevent
|
|
55
|
+
* `IsEmptyRecord` from evaluating eagerly, which breaks assignability under
|
|
56
|
+
* `exactOptionalPropertyTypes`.
|
|
57
|
+
*/
|
|
58
|
+
type MergeRecords<A extends object, B extends object> = IsEmptyRecord<A> extends true ? B : IsEmptyRecord<B> extends true ? A : A & B;
|
|
27
59
|
//#endregion
|
|
28
60
|
//#region ../../lib/primitive/src/types/intrinsic-tag.d.ts
|
|
29
61
|
type IntrinsicTag = keyof HTMLElementTagNameMap;
|
|
@@ -171,6 +203,64 @@ type RecipeMap<V extends VariantMap = VariantMap> = Readonly<StringMap<VariantSe
|
|
|
171
203
|
//#region ../../lib/primitive/src/types/variants/recipe-target.d.ts
|
|
172
204
|
type RecipeTarget<TVariants extends VariantMap = VariantMap> = VariantSelection<TVariants>;
|
|
173
205
|
//#endregion
|
|
206
|
+
//#region ../../lib/primitive/src/types/variants/polymorphic-generics.d.ts
|
|
207
|
+
/**
|
|
208
|
+
* The framework-neutral descriptor for a single praxis-kit component's contract — every render
|
|
209
|
+
* mechanism (tag resolution, prop merging, classes, ARIA) and every framework adapter's
|
|
210
|
+
* component type is built from this one shape. Deliberately just data: five type parameters and
|
|
211
|
+
* their corresponding properties, with no notion of JSX, call signatures, refs, or any
|
|
212
|
+
* framework-specific rendering concern. Each adapter (React, Vue, Svelte, Solid, Lit, Web) builds
|
|
213
|
+
* its own idiomatic component type on top of a `PolymorphicGenerics<...>` instantiation — see
|
|
214
|
+
* `PolymorphicComponent<G>` (`adapters/react/src/shared/types/polymorphic-props.ts`) for the
|
|
215
|
+
* React example — rather than this interface knowing anything about any of them.
|
|
216
|
+
*
|
|
217
|
+
* Use the `*Of<T>` accessor aliases below (`DefaultOf<G>`, `PropsOf<G>`, etc.) to read a single
|
|
218
|
+
* field back out of an already-resolved `G`, instead of indexing `G['default']` etc. directly at
|
|
219
|
+
* call sites — same rationale as any accessor: the property name stays an implementation detail,
|
|
220
|
+
* and every reader benefits together if it ever needs to change.
|
|
221
|
+
*/
|
|
222
|
+
interface PolymorphicGenerics<
|
|
223
|
+
/**
|
|
224
|
+
* The element/tag this component renders as when the consumer doesn't override it via `as`
|
|
225
|
+
* (`AllowedOf<G>` permitting) — e.g. `'button'`, `'div'`. Defaults to the widest `ElementType`
|
|
226
|
+
* so a generic `PolymorphicGenerics` reference (with nothing else specified) still compiles.
|
|
227
|
+
*/
|
|
228
|
+
TDefault extends ElementType = ElementType,
|
|
229
|
+
/**
|
|
230
|
+
* The props this specific component declares — its own contract, before variants are mixed
|
|
231
|
+
* in. Defaults to `AnyRecord` for the same "still compiles unspecified" reason as `TDefault`.
|
|
232
|
+
*/
|
|
233
|
+
Props extends AnyRecord = AnyRecord,
|
|
234
|
+
/**
|
|
235
|
+
* This component's variant definitions (e.g. `{ intent: { primary: ..., ghost: ... } }`).
|
|
236
|
+
* Constrained to `Readonly<VariantMap>` — not the wider `AnyRecord` — specifically so `TPreset`
|
|
237
|
+
* below can be expressed as `RecipeMap<Variants>` and get real per-variant-key checking,
|
|
238
|
+
* instead of falling back to an unconstrained `RecipeMap<VariantMap>`.
|
|
239
|
+
*/
|
|
240
|
+
Variants extends Readonly<VariantMap> = Readonly<VariantMap>,
|
|
241
|
+
/**
|
|
242
|
+
* Named presets (`RecipeMap<Variants>`) — bundles of variant selections a consumer activates
|
|
243
|
+
* by key instead of repeating the same variant combination at every call site. Tied to
|
|
244
|
+
* `Variants`, not `AnyRecord`, precisely so a preset can only ever select keys/values that
|
|
245
|
+
* `Variants` actually defines — an invalid preset is a type error, not a silent no-op.
|
|
246
|
+
* Defaults to `Readonly<EmptyRecord>` (no presets), which is the common case: a component can
|
|
247
|
+
* have variants without necessarily defining any named presets over them, and most don't.
|
|
248
|
+
*/
|
|
249
|
+
TPreset extends RecipeMap<Variants> = Readonly<EmptyRecord>,
|
|
250
|
+
/**
|
|
251
|
+
* The set of elements/tags a consumer is allowed to switch to via `as`. Defaults to the widest
|
|
252
|
+
* `ElementType`, under which `AllowedOf<G>` imposes no restriction at all (see
|
|
253
|
+
* `PolymorphicControlProps.as`'s own comment in the React adapter for the concrete effect this
|
|
254
|
+
* has at a component's actual call site).
|
|
255
|
+
*/
|
|
256
|
+
TAllowed extends ElementType = ElementType> {
|
|
257
|
+
default: TDefault;
|
|
258
|
+
props: Props;
|
|
259
|
+
variants: Variants;
|
|
260
|
+
preset: TPreset;
|
|
261
|
+
allowed: TAllowed;
|
|
262
|
+
}
|
|
263
|
+
//#endregion
|
|
174
264
|
//#region ../../lib/primitive/src/types/variants/compound/compound-variant.d.ts
|
|
175
265
|
type RequireAtLeastOneIfNotEmpty<T> = keyof T extends never ? EmptyRecord : RequireAtLeastOne<T>;
|
|
176
266
|
type CompoundVariantConditionValue<V extends VariantMap, K extends keyof V> = VariantKey<V, K> | NonEmptyArray<VariantKey<V, K>>;
|
|
@@ -242,6 +332,7 @@ type ClassPluginFactory<TProps extends AnyRecord = EmptyRecord> = <V extends Var
|
|
|
242
332
|
* wherever a factory's concrete plugin-props shape isn't tracked (factory generics,
|
|
243
333
|
* capability wiring). */
|
|
244
334
|
type AnyClassPluginFactory = ClassPluginFactory<AnyRecord> | undefined;
|
|
335
|
+
type ExtractPluginProps<TPlugin extends AnyClassPluginFactory> = TPlugin extends ClassPluginFactory<infer T> ? string extends keyof T ? NoPluginProps : T : NoPluginProps;
|
|
245
336
|
//#endregion
|
|
246
337
|
//#region ../../lib/primitive/src/types/aria-rule/aria-context.d.ts
|
|
247
338
|
type AriaContext = {
|
|
@@ -427,16 +518,6 @@ type StylingOptions<V extends Readonly<VariantMap> = Readonly<EmptyRecord>, TPre
|
|
|
427
518
|
type NormalizeFn<Props extends AnyRecord = AnyRecord> = {
|
|
428
519
|
normalize(props: Readonly<Props & IntrinsicProps>): Props & IntrinsicProps;
|
|
429
520
|
}['normalize'];
|
|
430
|
-
/**
|
|
431
|
-
* The type-erased shape of {@link FactoryOptions} — every generic parameter widened to its bound.
|
|
432
|
-
*
|
|
433
|
-
* Use it for a value that must hold *any* factory config (a registry, a generic wrapper). It
|
|
434
|
-
* cannot check `styling.compounds` conditions against the real variant keys/values, because it
|
|
435
|
-
* has forgotten what they are — for that, annotate against `FactoryOptions<...>` with the concrete
|
|
436
|
-
* generics (or `satisfies FactoryOptions<'button', Props, typeof variants>`), which keeps an
|
|
437
|
-
* invalid compound condition a type error rather than a silent no-op.
|
|
438
|
-
*/
|
|
439
|
-
type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, RecipeMap<VariantMap>, AnyClassPluginFactory>;
|
|
440
521
|
/**
|
|
441
522
|
* The framework-neutral component-authoring config passed to `createContractComponent` in every
|
|
442
523
|
* adapter: default tag + name, own-prop defaults, a `normalize` transform, `styling` (variants,
|
|
@@ -446,7 +527,9 @@ type AnyFactoryOptions = FactoryOptions<ElementType, AnyRecord, VariantMap, Reci
|
|
|
446
527
|
* `satisfies FactoryOptions<TDefault, Props, typeof variants, ...>` on a config object narrows
|
|
447
528
|
* `styling.compounds` conditions to the real per-variant-key shape — including resolving a
|
|
448
529
|
* boolean-shaped axis (`{ true, false }`) to a real `boolean` — so a condition naming a variant or
|
|
449
|
-
* value that does not exist is a compile error. `
|
|
530
|
+
* value that does not exist is a compile error. Leaving `V` at the bare `VariantMap` instead
|
|
531
|
+
* (whether via `FactoryOptions`'s own default or an explicit erased instantiation) forgets that
|
|
532
|
+
* shape entirely, so the same invalid condition becomes a silent no-op instead.
|
|
450
533
|
*/
|
|
451
534
|
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> = {
|
|
452
535
|
/** The intrinsic tag the component renders by default. Overridable per instance via `as`. */
|
|
@@ -455,6 +538,33 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
455
538
|
readonly name?: string;
|
|
456
539
|
/** Values used for the component's own (non-variant) props when the consumer omits them. */
|
|
457
540
|
readonly defaults?: Partial<NoInfer<Props>>;
|
|
541
|
+
/**
|
|
542
|
+
* Optional, type-only declaration of this component's complete own-prop shape — present purely
|
|
543
|
+
* for type recovery, never read at runtime (see `declareProps` in `@praxis-kit/adapter-utils`).
|
|
544
|
+
*
|
|
545
|
+
* `defaults` alone can only prove a prop *has a default*, not that it's the complete prop model
|
|
546
|
+
* a component accepts — a `defaults: { size: 'md' }` component may still take `onClick`,
|
|
547
|
+
* `disabled`, and other props with no default at all, none of which a `defaults`-only recovery
|
|
548
|
+
* can see (see `ContractPropsFrom`'s own doc comment for the general shape of this problem).
|
|
549
|
+
* `props` closes that gap: when present, `ContractPropsOf<C>` / `ContractProps<typeof Component>`
|
|
550
|
+
* recover this declared type directly and exactly, in place of the necessarily-partial,
|
|
551
|
+
* literal-widened recovery `defaults` alone allows.
|
|
552
|
+
*
|
|
553
|
+
* Typed as `object | undefined`, not `NoInfer<Props> | undefined` like `defaults`/`onElement` —
|
|
554
|
+
* deliberately decoupled from this interface's own `Props` generic, unlike those two fields.
|
|
555
|
+
* `defaults`/`onElement` are tied to `Props` because real runtime code reads them against a
|
|
556
|
+
* concretely-resolved `Props` for a real call; `props` is never read at runtime at all (see
|
|
557
|
+
* above), so it has no such need, and tying it to `Props extends AnyRecord` would force every
|
|
558
|
+
* hand-declared prop `interface`/`type` an author passes through `declareProps<Props>()` to
|
|
559
|
+
* structurally satisfy `Record<string, unknown>` — a real TypeScript limitation (a named type
|
|
560
|
+
* without an index signature never satisfies that, even via plain assignment, only a fresh
|
|
561
|
+
* object literal does) that would make this field far more awkward to use for its one real job:
|
|
562
|
+
* carrying an author's own already-precise prop type through untouched. `ContractPropsFrom`
|
|
563
|
+
* (`contract-model.ts`) recovers the real value here structurally, straight off `O`'s own
|
|
564
|
+
* literal type — independent of this field's declared type, same as every other `Contract*From`
|
|
565
|
+
* derivation in that file.
|
|
566
|
+
*/
|
|
567
|
+
readonly props?: object | undefined;
|
|
458
568
|
/**
|
|
459
569
|
* A pure `(props) => props` transform run on every render, after `enforcement.props`'s
|
|
460
570
|
* normalizers see the same input. Use this for component-specific prop shaping — anything
|
|
@@ -509,7 +619,9 @@ type FactoryOptions<TDefault extends ElementType = ElementType, Props extends An
|
|
|
509
619
|
*
|
|
510
620
|
* Return a cleanup function to run when the instance unmounts.
|
|
511
621
|
*/
|
|
512
|
-
readonly onElement?:
|
|
622
|
+
readonly onElement?: {
|
|
623
|
+
onElement(element: ElementForTag<TDefault | TAllowed>, getProps: () => Readonly<Props>): void | (() => void);
|
|
624
|
+
}['onElement'];
|
|
513
625
|
};
|
|
514
626
|
//#endregion
|
|
515
627
|
//#region ../../lib/primitive/src/types/factory/resolved-factory-options.d.ts
|
|
@@ -546,6 +658,210 @@ type ResolvedFactoryOptions<TDefault extends ElementType = ElementType, Props ex
|
|
|
546
658
|
readonly precomputedClasses?: Readonly<StringMap<string>>;
|
|
547
659
|
};
|
|
548
660
|
//#endregion
|
|
661
|
+
//#region ../../lib/primitive/src/types/factory/contract-input.d.ts
|
|
662
|
+
/**
|
|
663
|
+
* The author-facing input constraint for `defineContract` (`@praxis-kit/adapter-utils`) —
|
|
664
|
+
* `FactoryOptions` with `tag` and `name` promoted from optional to required, and `diagnostics`
|
|
665
|
+
* removed entirely.
|
|
666
|
+
*
|
|
667
|
+
* `tag`/`name` are required here, not just conventionally recommended, because nothing in
|
|
668
|
+
* `FactoryOptions` itself enforces either: today `{}` satisfies `FactoryOptions`, and an absent
|
|
669
|
+
* `tag` silently resolves to `'div'` inside `resolveFactoryOptions` — a contract author who forgets
|
|
670
|
+
* `tag` gets no signal at all. Requiring both here, at the one boundary every contract passes
|
|
671
|
+
* through before construction, closes that gap without touching `FactoryOptions` itself (which
|
|
672
|
+
* stays permissive, since it's also the type any type-erased context still needs to describe).
|
|
673
|
+
*
|
|
674
|
+
* `diagnostics` is omitted, not just left optional: per `FactoryOptions.diagnostics`'s own doc
|
|
675
|
+
* comment, it's adapter-resolved only ("spread in by `resolveAdapterCommonOptions`") — a contract
|
|
676
|
+
* author overrides diagnostics behavior through `enforcement.diagnostics` instead, never this
|
|
677
|
+
* field directly, so there's nothing for an author to supply here in the first place.
|
|
678
|
+
*
|
|
679
|
+
* `Props` is `ContractInput`'s first type parameter (matching `FactoryOptions`'s own field-order
|
|
680
|
+
* intuition, even though `FactoryOptions` itself puts `TDefault` first) purely for readability as a
|
|
681
|
+
* standalone type annotation — `defineContract` itself constrains its own `const O` against the
|
|
682
|
+
* bare, all-defaulted `ContractInput` (see that function's own doc comment), never
|
|
683
|
+
* `ContractInput<Props>` with `Props` given explicitly.
|
|
684
|
+
*
|
|
685
|
+
* Every other parameter's default widens to that parameter's own *bound* (`Readonly<VariantMap>`,
|
|
686
|
+
* `RecipeMap<V>`, `AnyClassPluginFactory`, `ElementType`), not `FactoryOptions`'s narrower
|
|
687
|
+
* `EmptyRecord`-style defaults — deliberate and load-bearing: a real author's contract (real
|
|
688
|
+
* variants, a real preset, a real plugin) must structurally satisfy whatever bound this type
|
|
689
|
+
* presents, and a narrow bound would only accept an empty-variants, no-preset, no-plugin contract.
|
|
690
|
+
* See `DECISIONS.md`'s `defineContract` entry for the concrete bug this bound choice fixes.
|
|
691
|
+
*/
|
|
692
|
+
type ContractInput<Props extends AnyRecord = AnyRecord, TDefault extends ElementType = ElementType, V extends Readonly<VariantMap> = Readonly<VariantMap>, TPreset extends RecipeMap<V> = RecipeMap<V>, TPlugin extends AnyClassPluginFactory = AnyClassPluginFactory, TAllowed extends ElementType = ElementType> = SetRequired<Except<FactoryOptions<TDefault, Props, V, TPreset, TPlugin, TAllowed>, 'diagnostics'>, 'tag' | 'name'>;
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region ../../lib/primitive/src/types/factory/contract-model.d.ts
|
|
695
|
+
/**
|
|
696
|
+
* The pipeline this file implements:
|
|
697
|
+
*
|
|
698
|
+
* ```text
|
|
699
|
+
* O (a raw contract literal)
|
|
700
|
+
* → Contract*From<O> one derivation per dimension, straight off O's own shape
|
|
701
|
+
* → ContractDimensions<O> the six derivations, assembled
|
|
702
|
+
* → ContractModel<...> the same six values, as a required-field carrier
|
|
703
|
+
* → ContractModelOf<C> resolves an already-`defineContract`-ed C's real model,
|
|
704
|
+
* or reconstructs one from a raw C via ContractModelFrom
|
|
705
|
+
* ```
|
|
706
|
+
*
|
|
707
|
+
* See `DECISIONS.md`'s `defineContract` entry for the TypeScript limitations that shaped the
|
|
708
|
+
* derivations below.
|
|
709
|
+
*/
|
|
710
|
+
/**
|
|
711
|
+
* Canonical type-level representation of a contract's dimensions — the contract-level counterpart
|
|
712
|
+
* to `PolymorphicGenerics`. Every field is required, so a field's presence is never ambiguous the
|
|
713
|
+
* way it is on an optional `FactoryOptions` field.
|
|
714
|
+
*/
|
|
715
|
+
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> {
|
|
716
|
+
readonly tag: TDefault;
|
|
717
|
+
readonly props: Props;
|
|
718
|
+
readonly variants: V;
|
|
719
|
+
readonly preset: TPreset;
|
|
720
|
+
readonly plugin: TPlugin;
|
|
721
|
+
readonly allowed: TAllowed;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* The phantom-marker shape read back via `T extends HasContractModel<infer M> ? M : ...` — the
|
|
725
|
+
* contract-level counterpart to `lib/contract-props`'s `HasGenerics<G>`. Type-only: never assigned
|
|
726
|
+
* at runtime.
|
|
727
|
+
*
|
|
728
|
+
* `__model` is **required**, not optional like `HasGenerics<G>`'s `__generics?` — an optional field
|
|
729
|
+
* would make `C extends HasContractModel<infer M>` trivially succeed for any `C`, defeating the
|
|
730
|
+
* one thing this marker exists to answer: did `C` really go through `defineContract`?
|
|
731
|
+
*/
|
|
732
|
+
interface HasContractModel<M extends ContractModel = ContractModel> {
|
|
733
|
+
readonly __model: M;
|
|
734
|
+
}
|
|
735
|
+
type ContractTagFrom<O> = O extends {
|
|
736
|
+
tag: infer TDefault extends ElementType;
|
|
737
|
+
} ? TDefault : ElementType;
|
|
738
|
+
/** `'img'` → `string`, `1` → `number`, `true` → `boolean` — undoes `defineContract`'s `const O`
|
|
739
|
+
* literal narrowing so a `defaults` value doesn't become the only value a caller may pass. */
|
|
740
|
+
type WidenLiteral<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T;
|
|
741
|
+
type WidenShallow<T> = { [K in keyof T]: WidenLiteral<T[K]>; };
|
|
742
|
+
/** What the author explicitly declared, via `props: declareProps<Props>()`
|
|
743
|
+
* (`@praxis-kit/adapter-utils`) — used exactly as declared, no `Partial`/widening/`data-*`
|
|
744
|
+
* stripping (see `DefaultPropsFrom` for why those exist there but not here). */
|
|
745
|
+
type DeclaredPropsFrom<O> = O extends {
|
|
746
|
+
props: infer Props extends object | undefined;
|
|
747
|
+
} ? [NonNullable<Props>] extends [never] ? never : NonNullable<Props> & AnyRecord : never;
|
|
748
|
+
/** What can be inferred from `defaults` — partial at best, since a default only proves a prop
|
|
749
|
+
* *has* one, not that it's the complete prop set. `Partial`: a defaulted prop is optional to the
|
|
750
|
+
* caller by definition. `data-*` keys are dropped — every adapter has its own passthrough for
|
|
751
|
+
* those already (finding #43). */
|
|
752
|
+
type DefaultPropsFrom<O> = O extends {
|
|
753
|
+
defaults: infer Props extends AnyRecord;
|
|
754
|
+
} ? Partial<WidenShallow<Omit<Props, Extract<keyof Props, `data-${string}`>>>> : never;
|
|
755
|
+
/** Declared beats defaulted beats nothing. `[X] extends [never]`, not bare `X extends never` —
|
|
756
|
+
* tuple-wrapped so the check doesn't distribute if `X` is ever a union containing `never`. */
|
|
757
|
+
type ContractPropsFrom<O> = [DeclaredPropsFrom<O>] extends [never] ? [DefaultPropsFrom<O>] extends [never] ? EmptyRecord : DefaultPropsFrom<O> : DeclaredPropsFrom<O>;
|
|
758
|
+
type ContractVariantsFrom<O> = O extends {
|
|
759
|
+
styling: {
|
|
760
|
+
variants: infer V extends Readonly<VariantMap>;
|
|
761
|
+
};
|
|
762
|
+
} ? V : Readonly<EmptyRecord>;
|
|
763
|
+
type ContractPresetFrom<O> = O extends {
|
|
764
|
+
styling: {
|
|
765
|
+
presets: infer TPreset extends RecipeMap<VariantMap>;
|
|
766
|
+
};
|
|
767
|
+
} ? TPreset : Readonly<EmptyRecord>;
|
|
768
|
+
type ContractPluginFrom<O> = O extends {
|
|
769
|
+
styling: {
|
|
770
|
+
plugin: infer TPlugin extends AnyClassPluginFactory;
|
|
771
|
+
};
|
|
772
|
+
} ? TPlugin : AnyClassPluginFactory;
|
|
773
|
+
type ContractAllowedFrom<O> = O extends {
|
|
774
|
+
enforcement: {
|
|
775
|
+
allowedAs: readonly (infer TAllowed extends ElementType)[];
|
|
776
|
+
};
|
|
777
|
+
} ? TAllowed : ElementType;
|
|
778
|
+
/** The six derivations above, assembled — the direct input to `ContractModel`. */
|
|
779
|
+
type ContractDimensions<O> = {
|
|
780
|
+
readonly tag: ContractTagFrom<O>;
|
|
781
|
+
readonly props: ContractPropsFrom<O>;
|
|
782
|
+
readonly variants: ContractVariantsFrom<O>;
|
|
783
|
+
readonly preset: ContractPresetFrom<O>;
|
|
784
|
+
readonly plugin: ContractPluginFrom<O>;
|
|
785
|
+
readonly allowed: ContractAllowedFrom<O>;
|
|
786
|
+
};
|
|
787
|
+
/**
|
|
788
|
+
* Builds a `ContractModel` from a raw literal `O` — the fallback path `ContractModelOf<C>` uses
|
|
789
|
+
* when `C` never went through `defineContract` (no `__model` marker to read directly), and what
|
|
790
|
+
* `defineContract` itself attaches as that marker for a `C` that did.
|
|
791
|
+
*/
|
|
792
|
+
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;
|
|
793
|
+
/**
|
|
794
|
+
* Resolves "does `C` carry a real `ContractModel` already, or do we need to build one from its raw
|
|
795
|
+
* shape" — every `Contract*Of` accessor (`contract-of.ts`) is a one-line projection off this.
|
|
796
|
+
*/
|
|
797
|
+
type ContractModelOf<C> = C extends HasContractModel<infer M> ? M : ContractModelFrom<C>;
|
|
798
|
+
//#endregion
|
|
799
|
+
//#region ../../lib/primitive/src/types/factory/defined-contract.d.ts
|
|
800
|
+
/**
|
|
801
|
+
* `defineContract`'s return type — `O` itself (the pure-identity return value, see that function's
|
|
802
|
+
* own doc comment for why no defaults are injected), intersected with the `ContractModel` phantom
|
|
803
|
+
* marker `defineContract` established from `O` at its own call site. Per the `defineContract`
|
|
804
|
+
* proposal (`DECISIONS.md`): "the semantic distinction that matters is `FactoryOptions` describes
|
|
805
|
+
* *acceptable* structure, `DefinedContract<O>` represents a *concrete, established* contract" —
|
|
806
|
+
* `M` is exactly that establishment, made concrete and inspectable rather than left implicit in
|
|
807
|
+
* `O`'s own nested optional fields.
|
|
808
|
+
*/
|
|
809
|
+
type DefinedContract<O extends ContractInput, M extends ContractModel = ContractModel> = O & HasContractModel<M>;
|
|
810
|
+
//#endregion
|
|
811
|
+
//#region ../../lib/primitive/src/types/factory/contract-of.d.ts
|
|
812
|
+
/**
|
|
813
|
+
* `FactoryOptions`-level accessor family, mirroring `polymorphic-generics.ts`'s `*Of<T>`
|
|
814
|
+
* convention (`DefaultOf<G>`, `PropsOf<G>`, etc.) but applied one layer up, to a contract itself
|
|
815
|
+
* rather than to the `PolymorphicGenerics` an adapter derives from it.
|
|
816
|
+
*
|
|
817
|
+
* Named with a `Contract` prefix specifically to avoid colliding with `polymorphic-generics.ts`'s
|
|
818
|
+
* own `PropsOf`/`VariantsOf`/`RecipeOf`/`AllowedOf`/`DefaultOf` — both families are re-exported
|
|
819
|
+
* from `@praxis-kit/core`, so a name clash would be a real conflict, not a style nit.
|
|
820
|
+
*
|
|
821
|
+
* Each accessor is a trivial projection off `ContractModelOf<C>` (`contract-model.ts`) — the one
|
|
822
|
+
* place that resolves "does `C` carry a real `ContractModel` (via `defineContract`) or does one
|
|
823
|
+
* need reconstructing from `C`'s raw shape," so every accessor shares one implementation of that
|
|
824
|
+
* resolution rather than repeating it. See `contract-model.ts`'s own doc comments for the
|
|
825
|
+
* `ContractXFrom<O>` derivation each of these ultimately reads through, and `DECISIONS.md`'s
|
|
826
|
+
* `defineContract` entry for the design history behind the required-pattern-match technique.
|
|
827
|
+
*/
|
|
828
|
+
type ContractTagOf<C extends FactoryOptions> = ContractModelOf<C>['tag'];
|
|
829
|
+
/** See this file's own doc comment. Best-effort when `C` has no `ContractModel` marker — see
|
|
830
|
+
* `ContractPropsFrom`'s own doc comment for why. */
|
|
831
|
+
type ContractPropsOf<C extends FactoryOptions> = ContractModelOf<C>['props'];
|
|
832
|
+
/** See this file's own doc comment. */
|
|
833
|
+
type ContractVariantsOf<C extends FactoryOptions> = ContractModelOf<C>['variants'];
|
|
834
|
+
/** See this file's own doc comment. */
|
|
835
|
+
type ContractPresetOf<C extends FactoryOptions> = ContractModelOf<C>['preset'];
|
|
836
|
+
/** See this file's own doc comment. */
|
|
837
|
+
type ContractPluginOf<C extends FactoryOptions> = ContractModelOf<C>['plugin'];
|
|
838
|
+
/** See this file's own doc comment. */
|
|
839
|
+
type ContractAllowedOf<C extends FactoryOptions> = ContractModelOf<C>['allowed'];
|
|
840
|
+
//#endregion
|
|
841
|
+
//#region ../../lib/primitive/src/types/factory/contract-generics.d.ts
|
|
842
|
+
/**
|
|
843
|
+
* The canonical projection from a defined contract `C` to the `PolymorphicGenerics` shape every
|
|
844
|
+
* adapter's prop types are built from — the one place "G" gets computed, so it can no longer
|
|
845
|
+
* silently drift per adapter the way today's hand-assembled `PolymorphicGenerics<...>` instantiation
|
|
846
|
+
* at each `createContractComponent` call site can (see `ContractGenericsWithAllowedOf` below for
|
|
847
|
+
* the one confirmed instance of that drift).
|
|
848
|
+
*
|
|
849
|
+
* Folds the class-resolution plugin's own contributed props (`ExtractPluginProps<TPlugin>`) into
|
|
850
|
+
* `props` here, once, rather than leaving each adapter's `ContractProps` to re-derive that merge
|
|
851
|
+
* via its own distributive conditional type on every read — the root cause of the ~22-member
|
|
852
|
+
* layout-union bug PR #95 patched per-adapter (see `DECISIONS.md`'s `defineContract` entry).
|
|
853
|
+
*/
|
|
854
|
+
type ContractGenericsOf<C extends FactoryOptions> = PolymorphicGenerics<ContractTagOf<C>, MergeRecords<ContractPropsOf<C>, ExtractPluginProps<ContractPluginOf<C>>>, ContractVariantsOf<C>, ContractPresetOf<C>>;
|
|
855
|
+
/**
|
|
856
|
+
* Same projection as `ContractGenericsOf`, additionally threading `TAllowed` through to
|
|
857
|
+
* `PolymorphicGenerics`'s own `TAllowed` parameter. Only React's `createContractComponent`
|
|
858
|
+
* currently uses this variant — every other adapter uses the plain `ContractGenericsOf` above,
|
|
859
|
+
* matching their current behavior of not narrowing `as` via `enforcement.allowedAs` at the type
|
|
860
|
+
* level (the ARIA/tag-resolution engine still enforces `allowedAs` identically at runtime for all
|
|
861
|
+
* adapters regardless of which projection their types use).
|
|
862
|
+
*/
|
|
863
|
+
type ContractGenericsWithAllowedOf<C extends FactoryOptions> = PolymorphicGenerics<ContractTagOf<C>, MergeRecords<ContractPropsOf<C>, ExtractPluginProps<ContractPluginOf<C>>>, ContractVariantsOf<C>, ContractPresetOf<C>, ContractAllowedOf<C>>;
|
|
864
|
+
//#endregion
|
|
549
865
|
//#region ../../lib/contract/src/types/aria/invalid-result-input.d.ts
|
|
550
866
|
/** Shared input shape for `invalidWithFix`/`invalidWithoutFix`. */
|
|
551
867
|
type InvalidResultInput = {
|
|
@@ -674,4 +990,70 @@ interface Diagnostics {
|
|
|
674
990
|
report(diagnostic: Diagnostic): Diagnostic;
|
|
675
991
|
}
|
|
676
992
|
//#endregion
|
|
677
|
-
|
|
993
|
+
//#region ../../lib/adapter-utils/src/runtime/define-contract.d.ts
|
|
994
|
+
/**
|
|
995
|
+
* Takes a concrete contract input and establishes its canonical `ContractModel` from it — the
|
|
996
|
+
* contract-definition boundary every adapter's `createContractComponent` builds on.
|
|
997
|
+
*
|
|
998
|
+
* Deliberately a typed identity function at runtime, not a normalizer — no defaults are injected,
|
|
999
|
+
* no fields are added or removed. `O` is inferred once, from the literal argument, and
|
|
1000
|
+
* `ContractModelFrom<O>` (`contract-model.ts`) does the rest — the model's six dimensions are its
|
|
1001
|
+
* properties, not something this function's own signature has to think about individually.
|
|
1002
|
+
* `ContractInput`'s bound requires `tag` and `name`, each a non-empty string; `tag`/`name`
|
|
1003
|
+
* additionally reject the empty-string literal specifically, via a self-referential constraint on
|
|
1004
|
+
* `O` itself, since a field type alone can't express "reject this one specific literal."
|
|
1005
|
+
*
|
|
1006
|
+
* ```ts
|
|
1007
|
+
* export const boxContract = defineContract({ tag: 'div', name: 'Box' })
|
|
1008
|
+
* export const buttonContract = defineContract({
|
|
1009
|
+
* tag: 'button',
|
|
1010
|
+
* name: 'Button',
|
|
1011
|
+
* styling: { variants: { intent: { primary: 'btn--primary' } } },
|
|
1012
|
+
* })
|
|
1013
|
+
* ```
|
|
1014
|
+
*/
|
|
1015
|
+
export declare function defineContract<const O extends ContractInput & {
|
|
1016
|
+
readonly tag: O['tag'] extends '' ? never : ElementType;
|
|
1017
|
+
readonly name: O['name'] extends '' ? never : string;
|
|
1018
|
+
}>(options: O): DefinedContract<O, ContractModelFrom<O>>;
|
|
1019
|
+
//#endregion
|
|
1020
|
+
//#region ../../lib/adapter-utils/src/runtime/declare-props.d.ts
|
|
1021
|
+
/**
|
|
1022
|
+
* Type-only prop declaration helper for a `defineContract` config's `props` field
|
|
1023
|
+
* (`FactoryOptions.props`, `lib/primitive`) — never called for its return value (always
|
|
1024
|
+
* `undefined` at runtime), only for its type. Exists so an author can declare a component's
|
|
1025
|
+
* complete prop shape inline, in the same object literal `defineContract`'s single `const O`
|
|
1026
|
+
* parameter already infers from, without a separate generic argument at the
|
|
1027
|
+
* `defineContract`/`createContractComponent` call site itself — the fix for the gap
|
|
1028
|
+
* `ContractPropsFrom` (`lib/primitive`) documents: `defaults` alone can only prove a prop *has
|
|
1029
|
+
* a default*, not that it's the complete prop model.
|
|
1030
|
+
*
|
|
1031
|
+
* ```ts
|
|
1032
|
+
* interface ButtonProps {
|
|
1033
|
+
* onClick?: () => void
|
|
1034
|
+
* disabled?: boolean
|
|
1035
|
+
* }
|
|
1036
|
+
*
|
|
1037
|
+
* const buttonContract = defineContract({
|
|
1038
|
+
* tag: 'button',
|
|
1039
|
+
* name: 'Button',
|
|
1040
|
+
* props: declareProps<ButtonProps>(),
|
|
1041
|
+
* defaults: { type: 'button' },
|
|
1042
|
+
* })
|
|
1043
|
+
* ```
|
|
1044
|
+
*
|
|
1045
|
+
* Optional — most contracts still don't need this. Only reach for it when `defaults` doesn't
|
|
1046
|
+
* already capture every prop the component accepts.
|
|
1047
|
+
*
|
|
1048
|
+
* Bounded by `object`, not `AnyRecord` (`Record<string, unknown>`) like `Props` is everywhere else
|
|
1049
|
+
* in this pipeline — deliberately. A hand-declared `interface`/`type` prop shape (the overwhelmingly
|
|
1050
|
+
* common case an author reaches for here) has no index signature, and TypeScript's generic
|
|
1051
|
+
* *constraint* satisfaction (unlike plain value assignment) requires one to satisfy
|
|
1052
|
+
* `Record<string, unknown>` — a real, well-known TypeScript limitation, not a design choice this
|
|
1053
|
+
* file is working around loosely. `object` has no such requirement and accepts the same real
|
|
1054
|
+
* interfaces plain assignment already does; `ContractPropsFrom` (`lib/primitive`) matches this
|
|
1055
|
+
* field back out with the identical `object`-bounded pattern for the same reason.
|
|
1056
|
+
*/
|
|
1057
|
+
export declare function declareProps<Props extends object>(): Props | undefined;
|
|
1058
|
+
//#endregion
|
|
1059
|
+
export type { AriaContext, AriaFix, AriaFixResult, AriaPhase, AriaResult, AriaRule, ContractAllowedOf, ContractDimensions, ContractGenericsOf, ContractGenericsWithAllowedOf, ContractInput, ContractModel, ContractModelFrom, ContractModelOf, ContractPluginOf, ContractPresetOf, ContractPropsOf, ContractTagOf, ContractVariantsOf, DefinedContract, Diagnostics, EnforcementOptions, FactoryOptions, FixKind, HasContractModel, IntrinsicProps, AriaInvalidResult as InvalidResult, AriaInvalidWithFix as InvalidWithFix, AriaInvalidWithoutFix as InvalidWithoutFix, NormalizeFn, PropNormalizer, RemoveAttributeFixKind, ResolvedFactoryOptions, Severity, StateNormalizerConfig, StylingOptions, ValidResult };
|
package/dist/contract/index.js
CHANGED
|
@@ -208,6 +208,71 @@ const selectedProps = makeStateNormalizer({
|
|
|
208
208
|
falseState: "synthesize"
|
|
209
209
|
});
|
|
210
210
|
//#endregion
|
|
211
|
+
//#region ../../lib/adapter-utils/src/runtime/define-contract.ts
|
|
212
|
+
/**
|
|
213
|
+
* Takes a concrete contract input and establishes its canonical `ContractModel` from it — the
|
|
214
|
+
* contract-definition boundary every adapter's `createContractComponent` builds on.
|
|
215
|
+
*
|
|
216
|
+
* Deliberately a typed identity function at runtime, not a normalizer — no defaults are injected,
|
|
217
|
+
* no fields are added or removed. `O` is inferred once, from the literal argument, and
|
|
218
|
+
* `ContractModelFrom<O>` (`contract-model.ts`) does the rest — the model's six dimensions are its
|
|
219
|
+
* properties, not something this function's own signature has to think about individually.
|
|
220
|
+
* `ContractInput`'s bound requires `tag` and `name`, each a non-empty string; `tag`/`name`
|
|
221
|
+
* additionally reject the empty-string literal specifically, via a self-referential constraint on
|
|
222
|
+
* `O` itself, since a field type alone can't express "reject this one specific literal."
|
|
223
|
+
*
|
|
224
|
+
* ```ts
|
|
225
|
+
* export const boxContract = defineContract({ tag: 'div', name: 'Box' })
|
|
226
|
+
* export const buttonContract = defineContract({
|
|
227
|
+
* tag: 'button',
|
|
228
|
+
* name: 'Button',
|
|
229
|
+
* styling: { variants: { intent: { primary: 'btn--primary' } } },
|
|
230
|
+
* })
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
function defineContract(options) {
|
|
234
|
+
return options;
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region ../../lib/adapter-utils/src/runtime/declare-props.ts
|
|
238
|
+
/**
|
|
239
|
+
* Type-only prop declaration helper for a `defineContract` config's `props` field
|
|
240
|
+
* (`FactoryOptions.props`, `lib/primitive`) — never called for its return value (always
|
|
241
|
+
* `undefined` at runtime), only for its type. Exists so an author can declare a component's
|
|
242
|
+
* complete prop shape inline, in the same object literal `defineContract`'s single `const O`
|
|
243
|
+
* parameter already infers from, without a separate generic argument at the
|
|
244
|
+
* `defineContract`/`createContractComponent` call site itself — the fix for the gap
|
|
245
|
+
* `ContractPropsFrom` (`lib/primitive`) documents: `defaults` alone can only prove a prop *has
|
|
246
|
+
* a default*, not that it's the complete prop model.
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* interface ButtonProps {
|
|
250
|
+
* onClick?: () => void
|
|
251
|
+
* disabled?: boolean
|
|
252
|
+
* }
|
|
253
|
+
*
|
|
254
|
+
* const buttonContract = defineContract({
|
|
255
|
+
* tag: 'button',
|
|
256
|
+
* name: 'Button',
|
|
257
|
+
* props: declareProps<ButtonProps>(),
|
|
258
|
+
* defaults: { type: 'button' },
|
|
259
|
+
* })
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* Optional — most contracts still don't need this. Only reach for it when `defaults` doesn't
|
|
263
|
+
* already capture every prop the component accepts.
|
|
264
|
+
*
|
|
265
|
+
* Bounded by `object`, not `AnyRecord` (`Record<string, unknown>`) like `Props` is everywhere else
|
|
266
|
+
* in this pipeline — deliberately. A hand-declared `interface`/`type` prop shape (the overwhelmingly
|
|
267
|
+
* common case an author reaches for here) has no index signature, and TypeScript's generic
|
|
268
|
+
* *constraint* satisfaction (unlike plain value assignment) requires one to satisfy
|
|
269
|
+
* `Record<string, unknown>` — a real, well-known TypeScript limitation, not a design choice this
|
|
270
|
+
* file is working around loosely. `object` has no such requirement and accepts the same real
|
|
271
|
+
* interfaces plain assignment already does; `ContractPropsFrom` (`lib/primitive`) matches this
|
|
272
|
+
* field back out with the identical `object`-bounded pattern for the same reason.
|
|
273
|
+
*/
|
|
274
|
+
function declareProps() {}
|
|
275
|
+
//#endregion
|
|
211
276
|
//#region ../../lib/contract/src/aria/factories.ts
|
|
212
277
|
/**
|
|
213
278
|
* Builds a correctly-literal-typed `fixable: false` `AriaResult`. Exists so a rule author can
|
|
@@ -338,4 +403,4 @@ function mergeContracts(...contracts) {
|
|
|
338
403
|
};
|
|
339
404
|
}
|
|
340
405
|
//#endregion
|
|
341
|
-
export { activeContract, activeProps, createRemoveAttributeRule, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, invalidWithFix, invalidWithoutFix, loadingContract, loadingProps, makeStateNormalizer, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, removeAttributeFix, selectedContract, selectedProps };
|
|
406
|
+
export { activeContract, activeProps, createRemoveAttributeRule, declareProps, defineContract, disabledContract, disabledProps, expandedContract, expandedProps, invalidContract, invalidProps, invalidWithFix, invalidWithoutFix, loadingContract, loadingProps, makeStateNormalizer, mergeContracts, pressedContract, pressedProps, readonlyContract, readonlyProps, removeAttributeFix, selectedContract, selectedProps };
|
package/dist/eslint/index.js
CHANGED
|
@@ -138,10 +138,16 @@ const iterate = Object.freeze({
|
|
|
138
138
|
function isString(value) {
|
|
139
139
|
return typeof value === "string";
|
|
140
140
|
}
|
|
141
|
+
function isNumber(value) {
|
|
142
|
+
return typeof value === "number";
|
|
143
|
+
}
|
|
141
144
|
function isObject(value, excludeArrays = false) {
|
|
142
145
|
if (value === null || typeof value !== "object") return false;
|
|
143
146
|
return excludeArrays ? !Array.isArray(value) : true;
|
|
144
147
|
}
|
|
148
|
+
function isUndefined(value) {
|
|
149
|
+
return value === void 0;
|
|
150
|
+
}
|
|
145
151
|
//#endregion
|
|
146
152
|
//#region ../../plugins/eslint/src/utils/ast.ts
|
|
147
153
|
/** Narrows any node-shaped value to one whose `value` property is a string — the common check
|
|
@@ -158,7 +164,7 @@ function asArrayExpression(node) {
|
|
|
158
164
|
function asNumericLiteral(node) {
|
|
159
165
|
if (node?.type === "Literal") {
|
|
160
166
|
const { value } = node;
|
|
161
|
-
if (
|
|
167
|
+
if (isNumber(value)) return value;
|
|
162
168
|
}
|
|
163
169
|
if (node?.type === "UnaryExpression") {
|
|
164
170
|
const { operator, argument } = node;
|
|
@@ -195,7 +201,7 @@ function isFactoryCall(node, calleeNames) {
|
|
|
195
201
|
}
|
|
196
202
|
function extractVariantValues(node) {
|
|
197
203
|
const valuesObj = asObjectExpression(node);
|
|
198
|
-
if (
|
|
204
|
+
if (isUndefined(valuesObj)) return void 0;
|
|
199
205
|
const values = /* @__PURE__ */ new Set();
|
|
200
206
|
iterate.forEach(valuesObj.properties, (prop) => {
|
|
201
207
|
if (prop.type !== "Property") return;
|
|
@@ -206,14 +212,14 @@ function extractVariantValues(node) {
|
|
|
206
212
|
}
|
|
207
213
|
function extractVariantMap(variantsNode) {
|
|
208
214
|
const variantsObj = asObjectExpression(variantsNode);
|
|
209
|
-
if (
|
|
215
|
+
if (isUndefined(variantsObj)) return void 0;
|
|
210
216
|
const map = /* @__PURE__ */ new Map();
|
|
211
217
|
iterate.forEach(variantsObj.properties, (prop) => {
|
|
212
218
|
if (prop.type !== "Property") return;
|
|
213
219
|
const key = getPropertyKey(prop);
|
|
214
|
-
if (
|
|
220
|
+
if (isUndefined(key)) return;
|
|
215
221
|
const values = extractVariantValues(prop.value);
|
|
216
|
-
if (
|
|
222
|
+
if (isUndefined(values)) return;
|
|
217
223
|
map.set(key, values);
|
|
218
224
|
});
|
|
219
225
|
return map;
|