effcss
Version:
Self-confident CSS-in-JS
104 lines (103 loc) • 3.48 kB
TypeScript
type Paths<T> = T extends object ? {
[K in keyof T]: `${Exclude<K, symbol>}${'' | Paths<T[K]> extends '' ? '' : `.${Paths<T[K]>}`}`;
}[keyof T] : T extends string ? T : never;
type TDeepPartial<T> = T extends object ? {
[P in keyof T]?: TDeepPartial<T[P]>;
} : T;
type TBlocks<T> = Exclude<keyof T, symbol | number>;
type TElems<T> = T extends object ? {
[K in keyof T]: `${Exclude<K, symbol>}${T[K] extends object ? `.${Exclude<keyof T[K], symbol | ''>}` : never}`;
}[keyof T] : never;
type TLeaves<T> = T extends object ? {
[K in keyof T]: `${Exclude<K, symbol>}${TLeaves<T[K]> extends never ? "" : `.${TLeaves<T[K]>}`}`;
}[keyof T] : never;
type TMods<T> = T extends object ? {
[K in keyof T]: `${Exclude<K, symbol>}${'' | Paths<T[K]> extends '' ? '' : `.${Paths<T[K]>}`}`;
}[keyof T] : T extends string ? T : never;
type TStringBEM<T> = TBlocks<T> | TMods<T> | TElems<T>;
type TBEM<T> = TDeepPartial<T> | TStringBEM<T> | TStringBEM<T>[];
type TStyleSheet = Record<string, Record<string, Record<string, string | number>>>;
export type Leaves<T> = T extends object ? {
[K in keyof T]: `${Exclude<K, symbol>}${Leaves<T[K]> extends never ? '' : `.${Leaves<T[K]>}`}`;
}[keyof T] : never;
export type TMonoResolver<T extends TStyleSheet, B extends keyof T, E extends keyof T[B]> = {
/**
* Specify block
* @param val - block name
*/
b<BL extends Exclude<keyof T, Symbol | number>>(val: BL): TMonoResolver<T, BL, ''>;
/**
* Specify element
* @param val - element name
*/
e<EL extends Exclude<keyof T[B], Symbol | number>>(val: EL): TMonoResolver<T, B, EL>;
/**
* Specify modifiers
* @param val - modifiers object
*/
m(val?: Partial<T[B][E]>): TMonoResolver<T, B, E>;
/**
* Result style attributes
*/
get $(): {
[key in string]: string;
};
};
type TResolveSelector = <T extends TStyleSheet>(params: TStringBEM<T>) => string;
type TResolveAttr = {
<T extends TStyleSheet>(params: TBEM<T>): Record<string, string>;
<T extends TStyleSheet>(): TMonoResolver<T, "", "">;
};
type TParts = (string | number)[];
export type TDefaultTheme = {
angle: number;
size: number;
time: number;
coef: Record<number, number>;
hue: Record<'pri' | 'sec' | 'suc' | 'inf' | 'war' | 'dan', number>;
lightness: Record<'bg' | 'fg', Record<'xs' | 's' | 'm' | 'l' | 'xl', number>>;
chroma: Record<'bg' | 'fg', Record<'pale' | 'base' | 'rich' | 'gray', number>>;
};
export type TScope = {
/**
* BEM selector resolver
*/
selector: TResolveSelector;
/**
* BEM attribute resolver
*/
attr: TResolveAttr;
/**
* Name resolver
*/
name: (parts: TParts | string) => string;
/**
* Var name
*/
varName: (name: TParts | string) => string;
/**
* Var expression
*/
varExp: <T extends Record<string, object | number | string | boolean> = TDefaultTheme>(name: TLeaves<T>, fallback?: string | number) => string;
};
/**
* Style scope resolver
*/
export type TScopeResolver = {
(key: string): TScope;
dict?: Record<string, Record<string, string>>;
};
/**
* Create stylesheet scope
*/
export type TCreateScope = (params?: {
mode?: string | null;
min?: boolean;
dict?: Record<string, Record<string, string>>;
}) => TScopeResolver;
/**
* Create BEM resolver
* @param params - BEM resolver params
*/
export declare const createScope: TCreateScope;
export {};