UNPKG

react-tvcx

Version:

A library providing functions to help users create a reusable component system for their projects using React, Tailwind CSS, and TypeScript.

1 lines 8.42 kB
{"version":3,"sources":["../src/cn.ts","../src/forward-ref.ts","../src/tvcx.tsx"],"sourcesContent":["import type { ClassValue } from 'clsx'\nimport clsx from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import React from 'react'\n\nexport type As<BaseProps = any> = React.ElementType<BaseProps>\n\nexport type PropsWithAs<ComponentType extends As, ComponentProps> = ComponentProps &\n Omit<React.ComponentPropsWithRef<ComponentType>, 'as' | keyof ComponentProps> & {\n as?: ComponentType\n }\n\nexport type PropsFromAs<ComponentType extends As, ComponentProps> = (PropsWithAs<\n ComponentType,\n ComponentProps\n> & { as: ComponentType }) &\n PropsWithAs<ComponentType, ComponentProps>\n\nexport interface ForwardRefWithAsRenderFunction<\n DefaultComponentType extends As,\n ComponentProps = {},\n> {\n (\n props: React.PropsWithChildren<PropsFromAs<DefaultComponentType, ComponentProps>>,\n ref:\n | ((\n instance:\n | (DefaultComponentType extends keyof ElementTagNameMap\n ? ElementTagNameMap[DefaultComponentType]\n : any)\n | null\n ) => void)\n | React.MutableRefObject<\n | (DefaultComponentType extends keyof ElementTagNameMap\n ? ElementTagNameMap[DefaultComponentType]\n : any)\n | null\n >\n | null\n ): React.ReactElement | null\n displayName?: string\n defaultProps?: never\n propTypes?: never\n}\n\ninterface ExoticComponentWithAs<DefaultComponentType extends As, ComponentProps> {\n (props: PropsWithAs<DefaultComponentType, ComponentProps>): React.ReactElement | null\n <ComponentType extends As>(\n props: PropsWithAs<ComponentType, ComponentProps> & {\n as: ComponentType\n }\n ): React.ReactElement | null\n\n /**\n * Inherited from React.ExoticComponent\n */\n readonly $$typeof: symbol\n}\n\ninterface NamedExoticComponentWithAs<DefaultComponentType extends As, ComponentProps>\n extends ExoticComponentWithAs<DefaultComponentType, ComponentProps> {\n /**\n * Inherited from React.NamedExoticComponent\n */\n displayName?: string\n}\n\nexport interface ForwardRefExoticComponentWithAs<DefaultComponentType extends As, ComponentProps>\n extends NamedExoticComponentWithAs<DefaultComponentType, ComponentProps> {\n defaultProps?: Partial<PropsWithAs<DefaultComponentType, ComponentProps>>\n propTypes?: React.WeakValidationMap<PropsWithAs<DefaultComponentType, ComponentProps>>\n}\n\nexport function forwardRef<DefaultComponentType extends As = 'div', Props = {}>(\n render: ForwardRefWithAsRenderFunction<DefaultComponentType, Props>\n) {\n return React.forwardRef(render as any) as ForwardRefExoticComponentWithAs<\n DefaultComponentType,\n Props\n >\n}\n","import React from 'react'\nimport { VariantProps } from 'tailwind-variants'\nimport { cn } from './cn'\nimport { forwardRef } from './forward-ref'\n\nexport interface ComponentMetadata {\n displayName?: string\n defaultProps?: Partial<any>\n id?: string\n}\n\nexport type Recipe = (...args: any) => any\n\nexport type TVSlot2ClassNames<Slots extends string> = Partial<Record<Slots, any>>\nexport type TVReturn<TVFN extends Recipe> = ReturnType<TVFN>\n\nexport type TVSlots<TVFN extends Recipe> = keyof TVReturn<TVFN>\n\nexport type TVSlotClassNamesProps<TVFN extends Recipe> =\n TVSlots<TVFN> extends string ? { classNames?: TVSlot2ClassNames<TVSlots<TVFN>> } : object\n\nexport type ComposedTVProps<TVFN extends Recipe> = VariantProps<TVFN> & TVSlotClassNamesProps<TVFN>\n\nexport type UnstyledProps = {\n unstyled?: boolean\n}\n\nexport type CtxClassNames<TVFN extends Recipe> =\n ComposedTVProps<TVFN> extends { classNames: any } ? ComposedTVProps<TVFN>['classNames'] : unknown\n\nexport function createComponentFactory<TVFN extends Recipe, Slot extends keyof ReturnType<TVFN>>(\n tvFn: TVFN\n) {\n const Ctx = React.createContext<{\n variants?: ReturnType<TVFN>\n classNames?: CtxClassNames<TVFN>\n }>({})\n\n const useCtx = () => React.useContext(Ctx)\n\n function withRoot<C extends React.ElementType>(Component: C, slot?: Slot) {\n const Comp = React.forwardRef<\n React.ElementRef<C>,\n React.ComponentPropsWithoutRef<C> & ComposedTVProps<TVFN> & UnstyledProps\n >(function ({ className, classNames, unstyled, ...props }, ref) {\n const variants = tvFn(props) as any\n\n const _className = React.useMemo(\n function () {\n return cn(\n unstyled ? '' : typeof variants === 'string' ? variants : variants?.[slot ?? '']?.(),\n classNames?.[slot],\n className\n )\n },\n [variants, classNames, className, slot, unstyled]\n )\n\n return (\n <Ctx.Provider value={{ variants, classNames: classNames }}>\n <Component ref={ref} className={_className} {...(props as any)} />\n </Ctx.Provider>\n )\n })\n Comp.displayName = (Component as any).displayName || (Component as any).name\n return Comp\n }\n\n function withSlot<C extends React.ElementType>(Component: C, slot?: Slot) {\n const Comp = React.forwardRef<\n React.ElementRef<C>,\n React.ComponentPropsWithoutRef<C> & VariantProps<TVFN> & UnstyledProps\n >(function ({ className, unstyled, ...props }, ref) {\n const { variants, classNames } = useCtx()\n\n const _className = React.useMemo(\n function () {\n return cn(\n slot && !unstyled ? variants?.[slot]?.() : undefined,\n slot ? (classNames as any)?.[slot] : undefined,\n className\n )\n },\n [variants, classNames, className, slot, unstyled]\n )\n\n return <Component ref={ref} className={_className} {...(props as any)} />\n })\n\n Comp.displayName = (Component as any).displayName || (Component as any).name || 'Component'\n return Comp\n }\n\n return {\n withRoot,\n withSlot,\n }\n}\n\nexport function styled<TVFN extends Recipe, C extends React.ElementType>(Component: C, tvFn: TVFN) {\n return forwardRef<C, React.ComponentPropsWithoutRef<C> & VariantProps<TVFN>>(function (\n { as: Comp = Component as any, children, className, ...props },\n ref\n ) {\n return (\n <Comp ref={ref} className={cn(tvFn({ ...props, className }))} {...props}>\n {children}\n </Comp>\n )\n })\n}\n\nexport function createComponentTree<\n F extends React.ElementType,\n N extends Readonly<Record<string, React.ElementType | ((...args: any) => any)>>,\n>(Factory: F, nestedChildren: Readonly<N>) {\n const c = Factory as F & N\n return Object.assign(c, nestedChildren)\n}\n"],"mappings":";AACA,OAAO,UAAU;AACjB,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACNA,OAAO,WAAW;AAsEX,SAAS,WACd,QACA;AACA,SAAO,MAAM,WAAW,MAAa;AAIvC;;;AC7EA,OAAOA,YAAW;AA8BX,SAAS,uBACd,MACA;AACA,QAAM,MAAMC,OAAM,cAGf,CAAC,CAAC;AAEL,QAAM,SAAS,MAAMA,OAAM,WAAW,GAAG;AAEzC,WAAS,SAAsC,WAAc,MAAa;AACxE,UAAM,OAAOA,OAAM,WAGjB,SAAU,EAAE,WAAW,YAAY,UAAU,GAAG,MAAM,GAAG,KAAK;AAC9D,YAAM,WAAW,KAAK,KAAK;AAE3B,YAAM,aAAaA,OAAM;AAAA,QACvB,WAAY;AAhDpB;AAiDU,iBAAO;AAAA,YACL,WAAW,KAAK,OAAO,aAAa,WAAW,YAAW,0CAAW,sBAAQ,QAAnB;AAAA,YAC1D,yCAAa;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,QACA,CAAC,UAAU,YAAY,WAAW,MAAM,QAAQ;AAAA,MAClD;AAEA,aACE,gBAAAA,OAAA,cAAC,IAAI,UAAJ,EAAa,OAAO,EAAE,UAAU,WAAuB,KACtD,gBAAAA,OAAA,cAAC,aAAU,KAAU,WAAW,YAAa,GAAI,OAAe,CAClE;AAAA,IAEJ,CAAC;AACD,SAAK,cAAe,UAAkB,eAAgB,UAAkB;AACxE,WAAO;AAAA,EACT;AAEA,WAAS,SAAsC,WAAc,MAAa;AACxE,UAAM,OAAOA,OAAM,WAGjB,SAAU,EAAE,WAAW,UAAU,GAAG,MAAM,GAAG,KAAK;AAClD,YAAM,EAAE,UAAU,WAAW,IAAI,OAAO;AAExC,YAAM,aAAaA,OAAM;AAAA,QACvB,WAAY;AA5EpB;AA6EU,iBAAO;AAAA,YACL,QAAQ,CAAC,YAAW,0CAAW,UAAX,oCAAuB;AAAA,YAC3C,OAAQ,yCAAqB,QAAQ;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,QACA,CAAC,UAAU,YAAY,WAAW,MAAM,QAAQ;AAAA,MAClD;AAEA,aAAO,gBAAAA,OAAA,cAAC,aAAU,KAAU,WAAW,YAAa,GAAI,OAAe;AAAA,IACzE,CAAC;AAED,SAAK,cAAe,UAAkB,eAAgB,UAAkB,QAAQ;AAChF,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,OAAyD,WAAc,MAAY;AACjG,SAAO,WAAsE,SAC3E,EAAE,IAAI,OAAO,WAAkB,UAAU,WAAW,GAAG,MAAM,GAC7D,KACA;AACA,WACE,gBAAAA,OAAA,cAAC,QAAK,KAAU,WAAW,GAAG,KAAK,EAAE,GAAG,OAAO,UAAU,CAAC,CAAC,GAAI,GAAG,SAC/D,QACH;AAAA,EAEJ,CAAC;AACH;AAEO,SAAS,oBAGd,SAAY,gBAA6B;AACzC,QAAM,IAAI;AACV,SAAO,OAAO,OAAO,GAAG,cAAc;AACxC;","names":["React","React"]}