@mincho-js/css
Version:
Natural CSS in the Typescript
110 lines (109 loc) • 6.43 kB
TypeScript
import { PureCSSVarKey, ComplexCSSRule, CSSRule, ResolvedProperties, NonNullableString } from '@mincho-js/transform-to-vanilla';
type Resolve<T> = {
[Key in keyof T]: T[Key];
} & {};
export type ResolveComplex<T> = T extends Array<infer U> ? Array<Resolve<U>> : Resolve<T>;
type RemoveUndefined<T> = T extends undefined ? never : T;
export type RemoveUndefinedFromIntersection<T> = {
[K in keyof T]: RemoveUndefined<T[K]>;
}[keyof T];
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type Primitive = string | number | boolean | null | undefined;
export type Serializable = {
[Key in string | number]: Primitive | Serializable;
} | ReadonlyArray<Primitive | Serializable>;
type RecipeStyleRule = ComplexCSSRule | string;
export type VariantDefinitions = Record<string, RecipeStyleRule>;
type BooleanMap<T> = T extends "true" | "false" ? boolean : T;
export type ToggleVariantMap<ToggleVariants extends VariantDefinitions> = {
[VariantGroup in keyof ToggleVariants]: {
true: ToggleVariants[VariantGroup];
};
};
export type VariantGroups = Record<string, VariantDefinitions>;
export type VariantObjectSelection<Variants extends VariantGroups> = {
[VariantGroup in keyof Variants]?: BooleanMap<keyof Variants[VariantGroup]> | undefined;
};
export type VariantToggleSelection<Variants extends VariantGroups> = {
[VariantGroup in keyof Variants]: keyof Variants[VariantGroup] extends "true" | "false" ? VariantGroup : never;
}[keyof Variants];
export type VariantSelection<Variants extends VariantGroups> = VariantObjectSelection<Variants> | Array<VariantToggleSelection<Variants> | VariantObjectSelection<Variants>>;
export type VariantsClassNames<Variants extends VariantGroups> = {
[P in keyof Variants]: {
[PP in keyof Variants[P]]: string;
};
};
export type PropTarget = keyof ResolvedProperties;
export type ComplexPropDefinitions<PropKeys extends PropTarget | undefined> = PropDefinition<PropKeys> | Array<PropKeys | PropDefinition<PropKeys>>;
export type PropDefinition<PropKeys extends PropTarget | undefined> = {
[Key in NonNullableString | PropTarget]?: {
base?: ResolvedProperties[Exclude<PropKeys, undefined>];
targets: PropKeys[];
};
};
export type PropDefinitionOutput<T extends ComplexPropDefinitions<PropTarget | undefined>> = UnionToIntersection<T extends unknown[] ? PropDefinitionOutputElement<T[number]> : PropDefinitionOutputElement<T>>;
type PropDefinitionOutputElement<DefinitionElement> = DefinitionElement extends string ? HandlePropTarget<DefinitionElement> : DefinitionElement extends {
[key: string]: unknown;
} ? HandlePropDefinition<DefinitionElement> : never;
type HandlePropTarget<PropKeys extends string> = PropKeys extends PropTarget ? {
[Key in PropKeys]?: ResolvedProperties[Key];
} : never;
type HandlePropDefinition<PropObject extends {
[key: string]: unknown;
}> = UnionToIntersection<{
[Key in keyof PropObject & string]: HandlePropDefinitionEntry<Key, PropObject[Key]>;
}[keyof PropObject & string]>;
type HandlePropDefinitionEntry<Key extends string, PropValue> = PropValue extends {
targets: infer T;
} ? T extends unknown[] ? {
[P in Key]?: ResolvedProperties[Extract<T[number], PropTarget>];
} : never : never;
export type PropVars<Props extends ComplexPropDefinitions<PropTarget | undefined>> = Record<keyof PropDefinitionOutput<Props>, PureCSSVarKey>;
export type PatternResult<Variants extends VariantGroups, Props extends ComplexPropDefinitions<PropTarget | undefined>> = {
defaultClassName: string;
variantClassNames: VariantsClassNames<Variants>;
defaultVariants: VariantObjectSelection<Variants>;
compoundVariants: Array<[VariantObjectSelection<Variants>, string]>;
propVars: PropVars<Props>;
};
export interface CompoundVariant<Variants extends VariantGroups> {
variants: VariantSelection<Variants>;
style: RecipeStyleRule;
}
export type Brand<K, T> = K & {
__brand: T;
};
export type VariantStringMap<Variants extends VariantGroups> = {
[VariantKey in keyof Variants]: {
[VariantTarget in keyof Variants[VariantKey]]: Brand<Record<VariantKey, VariantTarget>, `${VariantKey & string}_${VariantTarget & string}`>;
};
};
export type BrandValue<Variants extends VariantGroups> = {
[VariantKey in keyof Variants]: VariantStringMap<Variants>[VariantKey][keyof Variants[VariantKey]];
}[keyof Variants];
export type CompoundVariantFn<Variants extends VariantGroups> = (variants: VariantStringMap<Variants>) => Array<{
condition: Array<BrandValue<Variants>>;
style: RecipeStyleRule;
}>;
export type CompoundVariants<Variants extends VariantGroups> = Array<CompoundVariant<Variants>> | CompoundVariantFn<Variants>;
export type ConditionalVariants<Variants extends VariantGroups | undefined, ToggleVariants extends VariantDefinitions | undefined> = Variants extends undefined ? ToggleVariants extends undefined ? never : ToggleVariantMap<Exclude<ToggleVariants, undefined>> : ToggleVariants extends undefined ? Variants : Resolve<Variants & ToggleVariantMap<Exclude<ToggleVariants, undefined>>>;
export type PatternOptions<Variants extends VariantGroups | undefined, ToggleVariants extends VariantDefinitions | undefined, Props extends ComplexPropDefinitions<PropTarget> | undefined> = CSSRule & {
base?: RecipeStyleRule;
props?: Props;
toggles?: ToggleVariants;
variants?: Variants;
defaultVariants?: VariantSelection<ConditionalVariants<Variants, ToggleVariants>>;
compoundVariants?: CompoundVariants<ConditionalVariants<Variants, ToggleVariants>>;
};
export type RecipeClassNames<Variants extends VariantGroups> = {
base: string;
variants: VariantsClassNames<Variants>;
};
export type RuntimeFn<Variants extends VariantGroups, Props extends ComplexPropDefinitions<PropTarget | undefined>> = ((options?: ResolveComplex<VariantSelection<Variants>>) => string) & {
props: (options: Resolve<PropDefinitionOutput<Props>>) => CSSRule;
variants: () => (keyof Variants)[];
classNames: RecipeClassNames<Variants>;
};
export type RulesVariants<RuleFn extends RuntimeFn<VariantGroups, ComplexPropDefinitions<PropTarget | undefined>>> = ResolveComplex<Parameters<RuleFn>[0]>;
export type RecipeVariants<RecipeFn extends RuntimeFn<VariantGroups, ComplexPropDefinitions<PropTarget | undefined>>> = RulesVariants<RecipeFn>;
export {};