@use-pico/cls
Version:
Type-safe, composable styling system for React, Vue, Svelte, and vanilla JS
73 lines (65 loc) • 2.74 kB
text/typescript
import type { Contract } from "./Contract";
import type { Utils } from "./Utils";
/**
* Namespace for variant-related types and utilities
*/
export namespace Variant {
/**
* Base variant contract type that defines the structure of variant names and their allowed values
*/
export type Type = Record<string, readonly string[]>;
/**
* Extracts all variants from inheritance chain and builds merged result of the chain,
* providing variant name as property and values are all available variants.
* This is raw input (no value translation done).
*
* This utility type recursively traverses the inheritance chain (via the "~use" property)
* and merges all variant contracts into a single, flattened variant contract. The result
* contains the raw variant definitions as they were declared, without any value type
* transformations.
*
* @template TContract - The contract type to extract variants from
* @returns A merged variant contract containing all variants from the inheritance chain
*/
export type Raw<TContract extends Contract.Any> = TContract extends {
variant: infer V extends Type;
"~use"?: infer U;
}
? U extends Contract.Any
? Utils.Merge<Raw<U>, V>
: V
: Record<string, never>;
/**
* Check if any variants are present in the contract only
*/
export type Has<TContract extends Contract.Any> =
keyof TContract["variant"] extends never ? false : true;
/**
* Check if any variants are present in the inheritance chain
*/
export type With<TContract extends Contract.Any> =
keyof Raw<TContract> extends never ? false : true;
/**
* Extracts all variants from inheritance chain and builds an object with "bool" variants
* translated to literal booleans and values mapped to individual object properties.
*
* This utility type recursively traverses the inheritance chain to collect all variant
* definitions, then creates a type-safe object where each variant name becomes a property
* with its corresponding value type. Boolean variants (defined with "bool") are mapped
* to the `boolean` type, while other variants are mapped to their string literal union types.
*
* @template TContract - The contract type to extract variant value mappings from
* @returns A mapping of variant names to their resolved value types
*/
export type VariantOf<TContract extends Contract.Any> = {
[K in keyof Raw<TContract>]: Utils.Value<Raw<TContract>[K][number]>;
};
export type Required<TContract extends Contract.Any> =
With<TContract> extends false
? Record<string, never>
: VariantOf<TContract>;
export type Optional<TContract extends Contract.Any> =
With<TContract> extends false
? Record<string, never>
: Partial<VariantOf<TContract>>;
}