@isilin/react-slot
Version:
Simple and powerful typed slots for React components
40 lines (34 loc) • 1.51 kB
TypeScript
import { ComponentType, ReactElement, ReactNode } from 'react';
type SlotComponent = ComponentType<any> & {
displayName?: string;
};
type SlotMap = Record<string, SlotComponent>;
type ExtraMap = Record<string, unknown>;
type SlotRules<T extends SlotMap> = {
[K in keyof T]: 'single' | 'multiple';
};
type SlotResult<T extends SlotMap> = {
[K in keyof T]?: ReactElement | ReactElement[];
} & {
others: ReactNode[];
};
interface DefineSlotComponentOptions<TSlots extends SlotMap, TExtras extends ExtraMap> {
slots: TSlots;
extras?: TExtras;
rules?: Partial<SlotRules<TSlots>>;
}
type NamedComponent<TProps = any> = ((props: TProps) => ReactElement) | React.MemoExoticComponent<any> | React.ForwardRefExoticComponent<any>;
declare function defineSlotComponent<TProps extends {} = {
children: ReactNode;
}, TSlots extends SlotMap = {}, TExtras extends ExtraMap = {}>(render: NamedComponent<TProps>, options: DefineSlotComponentOptions<TSlots, TExtras>): typeof render & {
[K in keyof TSlots as Capitalize<string & K>]: TSlots[K];
} & {
slots: TSlots;
rules?: Partial<SlotRules<TSlots>>;
} & TExtras;
declare function getSlots<T extends {
slots: SlotMap;
rules?: Partial<SlotRules<T['slots']>>;
}>(children: ReactNode, slotHost: T): SlotResult<T['slots']>;
declare function getDisplayName(component: unknown): string;
export { type ExtraMap, type SlotComponent, type SlotMap, type SlotResult, type SlotRules, defineSlotComponent, getDisplayName, getSlots };