UNPKG

@vitus-labs/rocketstyle

Version:

Rocketstyle is ultra powerful and extensible styling system for building React components blazingly fast, easily and make them easily extensible and reusable.

616 lines (536 loc) 21.8 kB
import { ComponentType } from 'react'; import { config } from '@vitus-labs/core'; import { context } from '@vitus-labs/core'; import { FC } from 'react'; import type { FocusEventHandler } from 'react'; import type { ForwardedRef } from 'react'; import type { ForwardRefExoticComponent } from 'react'; import type { MouseEventHandler } from 'react'; import type { ReactElement } from 'react'; import { ReactNode } from 'react'; import { render } from '@vitus-labs/core'; declare type ArrayOfKeys<T> = Array<keyof T>; declare type ArrayOfValues<T> = Array<T[keyof T]>; export declare type AttrsCb<A, T> = (props: Partial<A>, theme: T, helpers: { mode?: ThemeModeKeys; isDark?: boolean; isLight?: boolean; createElement: typeof render; }) => Partial<A>; declare type CallBackParam = TObj | TFn; export declare type ComposeParam = Record<string, GenericHoc | null | undefined | false>; export declare type ConfigAttrs<C extends ElementType | unknown, D extends Dimensions, DKP extends TDKP, UB extends boolean> = Partial<{ name: string; component: C; provider: boolean; consumer: ConsumerCb<D, DKP>; DEBUG: boolean; inversed: boolean; passProps: UB extends true ? keyof DimensionBooleanAttrs<DKP>[] : never; styled: boolean; }>; declare type Configuration<C = ElementType | unknown, D extends Dimensions = Dimensions> = InitConfiguration<C, D> & { provider?: boolean; consumer?: ConsumerCb<D>; DEBUG?: boolean; inversed?: boolean; passProps?: Array<string>; styled?: boolean; attrs: OptionFunc[]; priorityAttrs: OptionFunc[]; filterAttrs: string[]; theme: OptionFunc[]; styles: StylesCbArray; compose: Record<string, TFn | null | undefined | false>; statics: Record<string, any>; } & Record<string, any>; export declare type ConsumerCb<D extends Dimensions, DKP extends TDKP = TDKP> = (ctx: ConsumerCtxCb<D, DKP>) => ReturnType<ConsumerCtxCb<D, DKP>>; export declare type ConsumerCtxCb<D extends Dimensions, DKP extends TDKP = TDKP> = <T extends RocketComponentType>(attrs: ConsumerCtxCBValue<T, D, DKP>) => ReturnType<ConsumerCtxCBValue<T, D, DKP>>; export declare type ConsumerCtxCBValue<T extends RocketComponentType, D extends Dimensions, DKP extends TDKP> = (attrs: RocketProviderState<T>) => DKP extends TDKP ? Partial<ExtractDimensions<D, DKP> & { pseudo: PseudoState; }> : TObj; export { context } declare type Css = typeof config.css; declare const DEFAULT_DIMENSIONS: { readonly states: "state"; readonly sizes: "size"; readonly variants: "variant"; readonly multiple: { readonly propName: "multiple"; readonly multi: true; }; }; declare type DefaultDimensions = typeof DEFAULT_DIMENSIONS; export declare type DefaultProps = Partial<PseudoProps>; declare type DimensionBooleanAttrs<DKP extends TDKP> = Partial<Record<ValueOf<DimensionTypesHelper<DKP>>, boolean>>; export declare type DimensionCallbackParam<T, CT> = DimensionObj<CT> | DimensionCb<T, CT>; declare type DimensionCb<T, CT> = (theme: T, mode: ThemeModeCallback, css: Css) => DimensionResult<CT>; declare type DimensionObj<CT> = DimensionResult<CT>; declare type DimensionObjAttrs<D extends Dimensions, DKP extends TDKP> = { [I in keyof DKP]: ExtractDimensionMulti<D[I]> extends true ? Array<keyof DKP[I]> : keyof DKP[I]; }; export declare type DimensionProps<K extends DimensionValue, D extends Dimensions, P extends CallBackParam, DKP extends TDKP> = { [I in ExtractDimensionKey<D[keyof D]>]: I extends ExtractDimensionKey<K> ? ExtractNullableDimensionKeys<Spread<[DKP[I], NullableKeys<ReturnCbParam<P>>]>> : DKP[I]; }; declare type DimensionResult<CT> = Record<string, boolean | null | Partial<CT>>; export declare type Dimensions = Record<string, DimensionValue>; declare type DimensionTypesHelper<DKP extends TDKP> = { [I in keyof DKP]: keyof DKP[I]; }; export declare type DimensionValue = DimensionValuePrimitive | DimensionValueObj; declare type DimensionValueObj = { propName: string; multi?: boolean; }; declare type DimensionValuePrimitive = string; export declare type ElementType<T extends TObj | unknown = any> = (ComponentType<T> & Partial<{ [key: string]: any; }>) | (ForwardRefExoticComponent<T> & { [key: string]: any; }); declare interface ExoticComponent<P = {}> { (props: P): ReactElement<P & InnerComponentProps> | null; readonly $$typeof: symbol; } declare type ExtractDimensionKey<T extends DimensionValue> = T extends DimensionValueObj ? T['propName'] : T; declare type ExtractDimensionMulti<T extends DimensionValue> = T extends DimensionValueObj ? true : false; export declare type ExtractDimensionProps<D extends Dimensions, DKP extends TDKP, UB extends boolean> = UB extends true ? Partial<ExtractNullableDimensionKeys<DimensionObjAttrs<D, DKP> & DimensionBooleanAttrs<DKP>>> : Partial<ExtractNullableDimensionKeys<DimensionObjAttrs<D, DKP>>>; export declare type ExtractDimensions<D extends Dimensions, DKP extends TDKP> = ExtractNullableDimensionKeys<DimensionObjAttrs<D, DKP>>; declare type ExtractNullableDimensionKeys<T> = { [P in keyof T as T[P] extends false ? never : P]: T[P]; }; declare type ExtractNullableKeys<T> = { [P in keyof T as T[P] extends null | never | undefined ? never : P]: T[P]; }; export declare type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends ElementType<infer TProps> ? TProps : TComponentOrTProps; export declare type GenericHoc = (component: ElementType) => ElementType; declare type Id<T> = T extends infer U ? { [K in keyof U]: U[K]; } : never; declare type InitConfiguration<C, D> = { name?: string; component: C; useBooleans: boolean; dimensions: D; dimensionKeys: ArrayOfKeys<D>; dimensionValues: ArrayOfValues<D>; multiKeys: MultiKeys; }; declare type InnerComponentProps = { $rocketstyleRef?: ForwardedRef<unknown>; 'data-rocketstyle': string; }; /** * @param OA Origin component props params. * @param EA Extended prop types * @param T Theme passed via context. * @param CSS Custom theme accepted by styles. * @param S Defined statics * @param D Dimensions to be used for defining component states. * @param UB Use booleans value * @param DKP Dimensions key props. * @param DFP Calculated final component props */ export declare interface IRocketStyleComponent<OA extends TObj = {}, EA extends TObj = {}, T extends TObj = {}, CSS extends TObj = {}, S extends TObj = {}, HOC extends TObj = {}, D extends Dimensions = Dimensions, UB extends boolean = boolean, DKP extends TDKP = TDKP, DFP = MergeTypes<[OA, EA, DefaultProps, ExtractDimensionProps<D, DKP, UB>]>> extends ExoticComponent<DFP> { /** * A chaining method to define default component theme * @param param _object_ * * ### Examples * * #### Component name / displayName * ```tsx * const base = rocketstyleComponent * .config({ * name: 'Component name' * }) * ``` * * #### Replace component by a new one * ```tsx * const base = rocketstyleComponent * .config({ * component: (props) => <div {...props} /> * }) * ``` * * #### Component as provider * ```tsx * const parent = rocketstyleComponent * .config({ * provider: true * }) * ``` * * #### Component as consumer * ```tsx * const base = rocketstyleComponent * .config({ * consumer: ctx => ctx<typeof parent>(({ pseudo, state, ...rest }) => ({ * pseudo, * state * })) * }) * ``` * * #### Inversed theme * A possibility to set individualy for each component to have `inversed` styles * when using dark / light theme modes * ```tsx * const base = rocketstyleComponent * .config({ * inversed: true * }) * ``` * * #### Pass props to original component * A possibility to set individualy for each component props names to be passed * to `origin` component * * ```tsx * const base = rocketstyleComponent * .config({ * passProps: ['disabled', 'readOnly'] * }) * ``` */ config: <NC extends ElementType | unknown = unknown>({ name, component: NC, provider, consumer, DEBUG, inversed, passProps, }: ConfigAttrs<NC, D, DKP, UB>) => NC extends ElementType ? RocketStyleComponent<ExtractProps<NC>, EA, T, CSS, S, HOC, D, UB, DKP> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * A chaining method to define default component props * @param param Can be either _object_ or a _callback_ * * #### Examples * * ##### Object as a parameter * ```tsx * const base = rocketstyleComponent * const newElement = base.attrs({ * propA: 'value', * propB: 'value, * }) * ``` * * ##### Callback as a parameter * ```tsx * const base = rocketstyleComponent * const newElement = base.attrs((props, theme, helpers) => ({ * propA: props.disabled ? 'valueA' : 'valueB', * propB: 'value, * })) * ``` */ attrs: <P extends TObj | unknown = unknown>(param: P extends TObj ? Partial<MergeTypes<[DFP, P]>> | AttrsCb<MergeTypes<[DFP, P]>, Theme<T>> : Partial<DFP> | AttrsCb<DFP, Theme<T>>, config?: Partial<{ /** * priority props will be resolved first and overwritten by normal `attrs` * callbacks and `props` afterwards */ priority: boolean; /** * filter props will be omitted when passing to final component */ filter: P extends TObj ? Partial<keyof MergeTypes<[EA, P]>>[] : Partial<keyof EA>[]; }>) => P extends TObj ? RocketStyleComponent<OA, MergeTypes<[EA, P]>, T, CSS, S, HOC, D, UB, DKP> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * A chaining method to define default component theme * @param param Can be either _object_ or a _callback_ * * ### Examples * * #### Object as a parameter * ```tsx * const base = rocketstyleComponent * const newElement = base.attrs({ * backgroundColor: 'black', * }) * ``` * * #### Callback as a parameter * ```tsx * const base = rocketstyleComponent * const newElement = base.theme((theme, css) => ({ * backgroundColor: t.color.black, // value from context * })) *``` * * #### Dark / light theme callback * ```tsx * const base = rocketstyleComponent * * const newElement = base.theme((theme, mode, css) => ({ * backgroundColor: mode(t.color.black, t.color.white), // theme from context * })) * ``` */ theme: <P extends TObj | unknown = unknown>(param: P extends TObj ? Partial<MergeTypes<[Styles<CSS>, P]>> | ThemeCb<MergeTypes<[Styles<CSS>, P]>, Theme<T>> : Partial<Styles<CSS>> | ThemeCb<Styles<CSS>, Theme<T>>) => P extends TObj ? RocketStyleComponent<OA, EA, T, MergeTypes<[CSS, P]>, S, HOC, D, UB, DKP> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * A chaining method to define default rendered styles * @param param Callback of styled-components `css` function * * #### Examples * * ```tsx * const base = rocketstyleComponent * * const newElement = base.styles(css => css``) * ``` */ styles: (param: StylesCb) => RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * A chaining method to define high-order components to wrap * the defined component * @param param object of key hoc function * * ### Examples * * #### Define new hoc component * Using the `{ key: hoc }` annotation allows to override or remove * the defined hoc(s) later on. See the examples below. * ```tsx * const hoc = (WrappedComponent) => (props) => <WrappedComponent {...props} /> * const base = rocketstyleComponent * * const newElement = base.compose({ hocName: hoc }) * ``` * * #### Remove previously defined hoc component * (1) Set value to be `false` * ```tsx * const newElement = base.compose({ hocName: false }) * ``` * (2) Set value to be `null` * ```tsx * const newElement = base.compose({ hocName: null }) * ``` * (3) Set value to be `undefined` * ```tsx * const newElement = base.compose({ hocName: undefined }) * ``` */ compose: <P extends ComposeParam>(param: P) => P extends TObj ? RocketStyleComponent<OA, EA, T, CSS, S, MergeTypes<[HOC, P]>, D, UB, DKP> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * A chaining method to define statics on the rocketstyle component. * All statics are accessible via `is` static key on the component. * @param param object of statics * * ### Examples * * #### Define new static * Using the `{ key: value }` annotation allows to override or remove * the defined static(s) later on. See the examples below. * ```tsx * const base = rocketstyleComponent * * const newElement = base.statics({ * isNewStatic: true, * arrayStatic: ['a', 'b'], * functionStatic: (param) => { ...do something } * }) * ``` * * #### Override previously defined hoc component * (1) Set value to be `false` * ```tsx * const newElement = base.statics({ isNewStatic: false }) * ``` * (2) Set value to be `null` * ```tsx * const newElement = base.statics({ isNewStatic: null }) * ``` * (3) Set value to be `undefined` * ```tsx * const newElement = base.statics({ isNewStatic: undefined }) * ``` */ statics: <P extends TObj | unknown = unknown>(param: P) => P extends TObj ? RocketStyleComponent<OA, EA, T, CSS, MergeTypes<[S, P]>, HOC, D, UB, DKP> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; /** * An access to all defined statics on the component. * * ### Examples * * #### Access a static property * ```tsx * const element = rocketcomponent.statics({ * isNewStatic: true, * arrayStatic: ['a', 'b'], * functionStatic: (param) => { ...do something } * }) * * // staticValue = true * const staticValue = element.meta.isNewStatic * ``` */ meta: S; getStaticDimensions: (theme: TObj) => { dimensions: DKP; useBooleans: UB; multiKeys: MultiKeys<D>; }; getDefaultAttrs: (props: TObj, theme: TObj, mode: ThemeModeKeys) => TObj; /** * Accessible via types only! * * Provides defined rocketstyle dimensions and their options * * ### Examples * ```tsx * const element = rocketcomponent * * type Props = typeof element['$$rocketstyle'] * * ``` */ readonly $$rocketstyle: ExtractDimensions<D, DKP>; /** * Accessible via types only! * * Provides defined original props types (props of origin * component passed to _rocketstyle_) * * ### Examples * ```tsx * const element = rocketcomponent * * type Props = typeof element['$$originProps'] * * ``` */ readonly $$originTypes: OA; /** * Accessible via types only! * * Provides defined extended props types (props types defined * on `.attrs()` chaining method * component passed to _rocketstyle_) * * ### Examples * ```tsx * const element = rocketcomponent * .attrs<{ propName: string }>({}) * * type Props = typeof element['$$extendedProps'] * * ``` */ readonly $$extendedTypes: EA; /** * Accessible via types only! * * Provides all defined props types (including **origin** * props types, **extended** props types & **rocketstyle** * props types all together) * * ### Examples * ```tsx * const element = rocketcomponent * * type Props = typeof element['$$allProps'] * * ``` */ readonly $$types: DFP; /** * Static Rocketstyle component identificator */ IS_ROCKETSTYLE: true; /** * Component displayName defined in `.config()` chaining * method * * ```tsx * const element = rockestyleComponent * .config({ * name: 'ComponentName' * }) * ``` */ displayName: string; } declare type IsFalseOrNullable<T> = T extends null | undefined | false ? never : true; export declare type IsRocketComponent = <T>(component: T) => boolean; export declare const isRocketComponent: IsRocketComponent; export declare type MergeTypes<A extends readonly [...any]> = ExtractNullableKeys<Spread<A>>; declare type MultiKeys<T extends Dimensions = Dimensions> = Partial<Record<ExtractDimensionKey<T[keyof T]>, true>>; declare type NullableKeys<T> = { [K in keyof T]: IsFalseOrNullable<T[K]>; }; declare type OptionFunc = (...arg: unknown[]) => Record<string, unknown>; export declare const Provider: FC<TProvider>; declare type PseudoActions = { onMouseEnter: MouseEventHandler; onMouseLeave: MouseEventHandler; onMouseDown: MouseEventHandler; onMouseUp: MouseEventHandler; onFocus: FocusEventHandler; onBlur: FocusEventHandler; }; declare type PseudoProps = Partial<PseudoState & PseudoActions>; declare type PseudoState = { active: boolean; hover: boolean; focus: boolean; pressed: boolean; disabled: boolean; readOnly: boolean; }; declare type ReturnCbParam<P extends TFn | TObj> = P extends TFn ? ReturnType<P> : P; declare type RocketComponent<C extends ElementType = ElementType, T extends TObj = {}, CSS extends TObj = {}, D extends Dimensions = DefaultDimensions, UB extends boolean = boolean> = (props: Configuration<C, D>) => RocketStyleComponent<ExtractProps<C>, {}, T, CSS, {}, {}, D, UB, {}>; export declare type RocketComponentType = ElementType & { IS_ROCKETSTYLE: true; $$rocketstyle: Record<string, unknown>; }; export declare type RocketProviderState<T extends RocketComponentType | TObj | unknown = unknown> = T extends RocketComponentType ? Partial<T['$$rocketstyle']> & { pseudo: PseudoState; } : T; export declare type Rocketstyle = <D extends Dimensions = DefaultDimensions, UB extends boolean = true>({ dimensions, useBooleans, }?: { dimensions?: D; useBooleans?: UB; }) => <C extends ElementType>({ name, component, }: { name: string; component: C; }) => ReturnType<RocketComponent<C, {}, {}, D, UB>>; declare const rocketstyle: Rocketstyle; export default rocketstyle; export { rocketstyle } export declare type RocketStyleComponent<OA extends TObj = {}, EA extends TObj = {}, T extends TObj = {}, CSS extends TObj = {}, S extends TObj = {}, HOC extends TObj = {}, D extends Dimensions = Dimensions, UB extends boolean = boolean, DKP extends TDKP = TDKP> = IRocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP> & { [I in keyof D]: <K extends DimensionValue = D[I], P extends DimensionCallbackParam<Theme<T>, Styles<CSS>> = DimensionCallbackParam<Theme<T>, Styles<CSS>>>(param: P) => P extends DimensionCallbackParam<Theme<T>, Styles<CSS>> ? RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DimensionProps<K, D, P, DKP>> : RocketStyleComponent<OA, EA, T, CSS, S, HOC, D, UB, DKP>; }; declare type Spread<A extends readonly [...any]> = A extends [ infer L, ...infer R ] ? SpreadTwo<L, Spread<R>> : unknown; declare type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>; declare type Styles<S> = S extends unknown ? StylesDefault : MergeTypes<[StylesDefault, S]>; export declare type StylesCb = (css: Css) => ReturnType<Css>; declare type StylesCbArray = StylesCb[]; export declare interface StylesDefault { } export declare type TDKP = Record<ExtractDimensionKey<Dimensions[keyof Dimensions]>, Record<string, boolean | never | Record<string, boolean>> | unknown>; declare type TFn = (...args: any) => any; declare type Theme<T> = T extends unknown ? ThemeDefault : MergeTypes<[ThemeDefault, T]>; declare type Theme_2 = { rootSize: number; breakpoints?: Record<string, number>; __VITUS_LABS__?: never; } & Record<string, unknown>; declare const THEME_MODES: { readonly light: true; readonly dark: true; }; export declare type ThemeCb<CSS, T> = (theme: T, mode: ThemeModeCallback, css: Css) => Partial<CSS>; export declare interface ThemeDefault { } export declare type ThemeMode = <A = any, B = any>(light: A, dark: B) => A | B; export declare interface ThemeModeCallback { <A = any, B = any>(light: A, dark: B): (mode: 'light' | 'dark') => A | B; } export declare type ThemeModeKeys = keyof typeof THEME_MODES; export declare type TObj = Record<string, unknown>; export declare type TProvider = { children: ReactNode; theme?: Theme_2; mode?: 'light' | 'dark'; inversed?: boolean; provider?: ComponentType<any>; }; declare type ValueOf<T> = T[keyof T]; export { }