diff --git a/README.md b/README.md index a6d66f2..c50e3ec 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Or using yarn: First you need to define your default slots ```jsx -import { SlotsProps, Slots, SlotsCreator } from 'slots-component'; +import { SlotsProps, Slots, SlotsConfigCreator } from 'slots-component'; const DEFAULT_SLOTS = { Container: 'ul', @@ -100,7 +100,7 @@ interface TItem { name: string; } -type SlotsConfig = SlotsCreator @@ -135,7 +135,7 @@ export const List = < ## Roadmap -- Add CD -- Write a simpler generic -- Better documentation -- Add example +- [ ] Add CD +- [ ] Write a simpler generic +- [ ] Better documentation +- [ ] Add example diff --git a/index.test.tsx b/index.test.tsx index cea9171..69e5634 100644 --- a/index.test.tsx +++ b/index.test.tsx @@ -1,5 +1,5 @@ import type { Equal, Expect } from '@type-challenges/utils' -import type { Slots, SlotsCreator, SlotsProps } from "./index" +import type { Slots, SlotsConfigCreator, SlotsProps } from "./index" import type { ComponentProps, PropsWithChildren, JSX } from 'react' const SLOTS = { @@ -8,7 +8,7 @@ const SLOTS = { Custom1: (props: PropsWithChildren) => <> } satisfies Slots -type SlotsConfig = SlotsCreator +type SlotsConfig = SlotsConfigCreator type Props = SlotsProps JSX.Element }> diff --git a/index.ts b/index.ts index e02d4d6..90d19fe 100644 --- a/index.ts +++ b/index.ts @@ -1,52 +1,37 @@ -import { ComponentProps, JSXElementConstructor, JSX } from 'react'; +import { CallbacksCreator, MaybeFunc, Merge, PartialProps, ReactComponent, Slots } from './utils'; -type MaybeFunc> = - | Value - | ((...args: Args) => Value); - -type ReactComponent = keyof JSX.IntrinsicElements | JSXElementConstructor; -type Slots = Record; - -type CallbacksCreator = { - [Key in keyof DefaultProps]?: Array; -}; - -type SlotProps< - TSlots extends Slots, - SlotPropsWithCallback extends CallbacksCreator -> = { - [SlotKey in keyof TSlots as SlotKey extends string - ? Lowercase - : never]: TSlots[SlotKey] extends ReactComponent - ? SlotPropsWithCallback[SlotKey] extends Array - ? MaybeFunc< - Partial>, - SlotPropsWithCallback[SlotKey] - > - : Partial> - : never; - }; - -type SlotsCreator< +type SlotsConfigCreator< TDefaultSlots extends Slots, TCallbacks extends CallbacksCreator > = { DefaultSlots: TDefaultSlots; - Slots: { [Key in keyof TDefaultSlots]?: ReactComponent }; + Slots: Partial>; Callbacks: TCallbacks; }; +type SlotPropsCreator< + TSlotsConfig extends SlotsConfigCreator, + TSlots extends Slots, +> = { + [SlotKey in keyof TSlots as Lowercase]?: + // Get the props and rename it to Props + PartialProps extends infer Props ? + // get the slot args for slotProps callback if avaliable, name it Args + TSlotsConfig["Callbacks"][SlotKey] extends infer Args extends Array + ? MaybeFunc : Props + : never + }; + type SlotsProps< - TSlotsConfig extends SlotsCreator, - TSlots extends TSlotsConfig['Slots'] + TSlotsConfig extends SlotsConfigCreator, + TSlots extends TSlotsConfig['Slots'], > = { slots?: TSlots; - slotProps?: Partial< - SlotProps< - Omit & TSlots, - TSlotsConfig['Callbacks'] + slotProps?: + SlotPropsCreator< + TSlotsConfig, + Merge > - >; }; -export type { SlotsProps, SlotsCreator, Slots }; +export type { SlotsProps, SlotsConfigCreator, Slots, CallbacksCreator }; diff --git a/utils.ts b/utils.ts new file mode 100644 index 0000000..42a0661 --- /dev/null +++ b/utils.ts @@ -0,0 +1,18 @@ +import { JSXElementConstructor, JSX, ComponentProps } from 'react'; + +type MaybeFunc> = + | Value + | ((...args: Args) => Value); + +type ReactComponent = keyof JSX.IntrinsicElements | JSXElementConstructor; +type Slots = Record; + +type PartialProps = Partial> + +type CallbacksCreator = { + [Key in keyof DefaultProps]?: Array; +}; + +type Merge = Omit & U + +export type { Merge, MaybeFunc, ReactComponent, Slots, CallbacksCreator, PartialProps }