UNPKG

@zemd/react-slottable

Version:

A lightweight concept to customize subcomponents in React

53 lines (49 loc) 1.78 kB
import { ElementType, ComponentProps } from 'react'; type Prettify<T> = { [K in keyof T]: T[K]; } & {}; /** * A helper type that allows to define proper slot props. * * Usage: * ```ts * type ButtonProps = PropsWithSlots< * React.PropsWithChildren<{ name: string }>, * ["startDecorator", "endDecorator"] * >; * const Button: React.FC<ButtonProps> = (props) => { * const SlotStartDecorator = useSlot("startDecorator", props); * const SlotEndDecorator = useSlot("endDecorator", props); * * return ( * <button> * <SlotStartDecorator /> * {props.children} * <SlotEndDecorator /> * </button> * ); * }; * ``` */ type PropsWithSlots<ArgProps = {}, ArgSlots extends string[] = []> = ArgProps & (ArgSlots["length"] extends 0 ? {} : { slots?: { [K in ArgSlots[number]]?: ElementType; }; slotProps?: { [K in ArgSlots[number]]?: ComponentProps<ElementType>; }; }); type SlotOptions<T extends ElementType> = { slot?: T; }; type SlotsProps<T extends Record<string, ElementType>> = { slots?: T; }; type SlotPropsProps<T extends Record<string, any>> = { slotProps?: Partial<T>; }; /** * A hook that returns a component for a given slot. */ declare function useSlot<ArgSlotType extends ElementType, ArgExtraProps extends Partial<ComponentProps<ArgSlotType>>, ArgSlotOptions extends SlotOptions<ArgSlotType> & ArgExtraProps, ReturnComponent extends ArgSlotOptions extends SlotOptions<infer T> ? T : ElementType, ArgSlotsKeys extends Record<string, ElementType>>(name: keyof ArgSlotsKeys, props: Prettify<SlotsProps<ArgSlotsKeys> & SlotPropsProps<Record<keyof ArgSlotsKeys, any>>>, { slot, ...extraProps }?: ArgSlotOptions): ReturnComponent; export { type PropsWithSlots, useSlot };