@dr.pogodin/react-themes
Version:
UI theme composition with CSS Modules and React
86 lines (85 loc) • 3.93 kB
TypeScript
import { type ComponentType, type FunctionComponent, type ReactNode, type RefObject } from 'react';
export interface ThemeI {
ad: string;
hoc: string;
context: string;
}
export type Theme<KeyT extends string> = string extends KeyT ? never : ThemeI & Partial<Record<KeyT, string>>;
export interface ThemeMap {
[key: string]: ThemeI | undefined;
}
export interface ThemeableComponentProps {
theme: ThemeI;
}
export interface ThemePropsMapper<ComponentProps extends ThemeableComponentProps> {
(props: ThemedComponentProps<ComponentProps>, theme: ComponentProps['theme']): ComponentProps;
}
/** Supported theme composition modes. */
export declare enum COMPOSE {
DEEP = "DEEP",
SOFT = "SOFT",
SWAP = "SWAP"
}
/** Supported theme priorities. */
export declare enum PRIORITY {
ADHOC_CONTEXT_DEFAULT = "ADHOC_CONTEXT_DEFAULT",
ADHOC_DEFAULT_CONTEXT = "ADHOC_DEFAULT_CONTEXT"
}
export type ThemedOptions<ComponentProps extends ThemeableComponentProps> = {
adhocTag?: 'ad.hoc';
contextTag?: 'context';
composeAdhocTheme?: COMPOSE;
composeContextTheme?: COMPOSE;
mapThemeProps?: ThemePropsMapper<ComponentProps>;
themePriority?: PRIORITY;
};
export type ThemedComponentProps<ComponentProps extends ThemeableComponentProps> = Omit<ComponentProps, 'theme'> & {
children?: ReactNode;
composeAdhocTheme?: COMPOSE;
composeContextTheme?: COMPOSE;
mapThemeProps?: ThemePropsMapper<ComponentProps>;
ref?: RefObject<unknown>;
theme?: ComponentProps['theme'];
themePriority?: PRIORITY;
};
export type ThemedComponent<ComponentProps extends ThemeableComponentProps> = FunctionComponent<ThemedComponentProps<ComponentProps>>;
export type ThemedComponentFactory<ComponentProps extends ThemeableComponentProps> = (component: ComponentType<ComponentProps>) => ThemedComponent<ComponentProps>;
export type ThemeProviderProps = {
children?: ReactNode;
themes?: ThemeMap;
};
/**
* Theme provider defines style contexts. It accepts a single property
* `themes` (`theme` in compatibility modes).
*
* In case of nested context, the context theme from the closest context takes
* the effect on a component. If the context theme for a component is not set in
* the closest context, but it is set in an outer context, the theme from outer
* context will be applied.
*
* @param props.children React content to render in-place of
* <ThemeProvider> component.
*
* @param props.themes The mapping of between themeable component names
* (the first parameter passed into themed() function for such components
* registration), and context themes to apply to them within the context.
*
* @param props.theme Fallback mapping for backward compatibility
* with `react-css-themr` and `react-css-super-themr` libraries.
*/
export declare const ThemeProvider: FunctionComponent<ThemeProviderProps>;
declare function themed<ComponentProps extends ThemeableComponentProps>(componentName: string, defaultThemeOrOptions?: ComponentProps['theme'] | ThemedOptions<ComponentProps>, options?: ThemedOptions<ComponentProps>): ThemedComponentFactory<ComponentProps>;
declare function themed<ComponentProps extends ThemeableComponentProps>(component: ComponentType<ComponentProps>, componentName: string, defaultThemeOrOptions?: ComponentProps['theme'] | ThemedOptions<ComponentProps>, options?: ThemedOptions<ComponentProps>): ThemedComponent<ComponentProps>;
/** @deprecated */
export default themed;
type UseThemeOptions = {
adhocTag?: 'ad.hoc';
contextTag?: 'context';
composeAdhocTheme?: COMPOSE;
composeContextTheme?: COMPOSE;
themePriority?: PRIORITY;
};
/**
* React hook for theme composition.
*/
export declare function useTheme<ComponentTheme extends ThemeI, DefaultTheme extends ComponentTheme = ComponentTheme>(componentName: string, defaultTheme?: DefaultTheme, adHocTheme?: ComponentTheme, options?: UseThemeOptions): ComponentTheme;