@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
TypeScript
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 { }