react-classnaming
Version:
Tools to establish CSS classes as an explicit abstraction layer and to handle it as an interface between React and CSSStyleDeclaration
72 lines (71 loc) • 3.75 kB
TypeScript
import type { ClassNamed, ClassHash } from "./main.types";
import type { CssModule, ActionsOf, Action, Act4Used } from "./definitions.types";
import type { GetProps } from "./react-swiss.types";
import type { BoolDict, RequiredKeys, AnyObject, Falsy, Ever, OmitIndexed } from "./ts-swiss.types";
export declare type ClassNamingFn<Source extends CssModule, Used extends BoolDict, WithClassName extends boolean> =
/**
* Makes `string`-className from conditioned CSS classes as keys.
* Destructed to singleton `{className: string}`, stringifyable object, re-callable with propagation of previously stacked
* @example
* ```typescript
* classes(true); // `${props.className}`
* classes({App}); // "App"
* classes(true && {App: true, "App--bad": false}); // `${props.className} App`
* classes(); // `== classes`
*
* const btn = classes({btn}) // "btn"
* btn(true, {"btn--disabled": true}); // `${props.className} btn btn--disabled`
* ```
* @example
* ```tsx
* <div {...classes} />;
* <div {...classes(...)} />;
* <div data-block={`${classes}`} />
* <Component {...{
* ...classes(...)(...)(...)},
* ...classnames
* }/>
* ```
*/
<Actions0 extends {
[K in keyof Source]?: Action;
}, Actions1 extends {
[K in keyof Source]?: Action;
}, ApplyClassName extends WithClassName | false>(arg0?: ApplyClassName | Falsy | StrictSub<Used, Source, Actions0>, arg1?: ApplyClassName extends true ? Falsy | StrictSub<Used, Source, Actions1> : never) => ClassNaming<ApplyClassName extends true ? false : WithClassName, {
[K in keyof Used | RequiredKeys<Actions0 | Actions1>]: K extends keyof Used ? Used[K] : Act4Used<Actions0[K]> & Act4Used<Actions1[K]>;
}, Source>;
export declare type ClassNaming<WithClassName extends boolean, Used extends BoolDict, Source extends CssModule> = ClassNamingFn<{
[K in Exclude<keyof Source, RequiredKeys<Used>>]: Source[K];
}, Used, WithClassName> & ClassNamed;
declare type StrictSub<Used extends BoolDict, Source extends CssModule, Actions extends ActionsOf<Source>> = {
[K in keyof Actions]: K extends keyof Source ? K extends keyof Used ? never : Actions[K] extends boolean ? Actions[K] : Actions[K] extends ClassHash ? Ever<Extract<Actions[K], string>, Extract<Actions[K], string> extends "" ? never : Actions[K], Actions[K]> : boolean : never;
};
export declare type ClassNamesMapping<Source extends CssModule> = (
/** Function to map `classnames` to certain properties of target Component
* @example
* ```tsx
* <ThirdPartyComponent {...mapping({} as typeof ThirdPartyComponent, {
* ContainerClassName: { Root, "Theme--dark": true },
* Checked___true: classes({"Item--active": true}),
* Checked___false: {}
* })}/>
*```
*/
<Target extends AnyObject, Mapping extends ClassNamesMap<OmitIndexed<GetProps<Target>>, Source>>(target: Target, map: StrictActions<Mapping>) => Omit<{
[M in keyof Mapping]: string;
}, {
[M in keyof Mapping]: Mapping[M] extends undefined ? M : never;
}[keyof Mapping]>);
export declare type ClassNamesMap<TargetProps extends AnyObject, Source extends CssModule> = Pick<{
[K in keyof TargetProps]?: ClassNaming<boolean, {}, Source> | {
[S in keyof Source]?: Action;
};
}, {
[T in keyof TargetProps]: string extends TargetProps[T] ? T : never;
}[keyof TargetProps]>;
declare type StrictActions<MapActs extends ClassNamesMap<any, any>> = {
[T in keyof MapActs]: MapActs[T] extends Record<string, Action> ? {
[S in keyof MapActs[T]]: MapActs[T][S] extends boolean ? MapActs[T][S] : MapActs[T][S] extends ClassHash ? Ever<Extract<MapActs[T][S], string>, Extract<MapActs[T][S], string> extends "" ? never : MapActs[T][S], MapActs[T][S]> : boolean;
} : MapActs[T];
};
export {};