From bb68793f08a57833095a38519b639a744076dc69 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 11 Feb 2021 12:01:22 +0100 Subject: [PATCH] correctly handle TypeScript render abstractions --- .../src/components/listbox/listbox.tsx | 2 +- .../src/components/transitions/transition.tsx | 9 ++++++--- packages/@headlessui-react/src/types.ts | 13 ++++++++++--- packages/@headlessui-react/src/utils/render.ts | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/@headlessui-react/src/components/listbox/listbox.tsx b/packages/@headlessui-react/src/components/listbox/listbox.tsx index 0f812699b1..eacb2d78d2 100644 --- a/packages/@headlessui-react/src/components/listbox/listbox.tsx +++ b/packages/@headlessui-react/src/components/listbox/listbox.tsx @@ -365,7 +365,7 @@ function Label( state.buttonRef, ]) - let propsBag = useMemo( + let propsBag = useMemo( () => ({ open: state.listboxState === ListboxStates.Open, disabled: state.disabled }), [state] ) diff --git a/packages/@headlessui-react/src/components/transitions/transition.tsx b/packages/@headlessui-react/src/components/transitions/transition.tsx index 8dc8276c64..a9778ff940 100644 --- a/packages/@headlessui-react/src/components/transitions/transition.tsx +++ b/packages/@headlessui-react/src/components/transitions/transition.tsx @@ -12,7 +12,7 @@ import React, { ElementType, MutableRefObject, } from 'react' -import { Props, Expand } from '../../types' +import { Props } from '../../types' import { useId } from '../../hooks/use-id' import { useIsInitialRender } from '../../hooks/use-is-initial-render' @@ -201,8 +201,10 @@ function TransitionChild + } = props as typeof props let container = useRef(null) let [state, setState] = useState(TreeStates.Visible) let strategy = rest.unmount ? RenderStrategy.Unmount : RenderStrategy.Hidden @@ -331,7 +333,8 @@ function TransitionChild( props: TransitionChildProps & { show: boolean; appear?: boolean } ) { - let { show, appear = false, unmount, ...passthroughProps } = props as Expand + // @ts-expect-error + let { show, appear = false, unmount, ...passthroughProps } = props as typeof props if (![true, false].includes(show)) { throw new Error('A is used but it is missing a `show={true | false}` prop.') diff --git a/packages/@headlessui-react/src/types.ts b/packages/@headlessui-react/src/types.ts index c968d5c1d3..6775799076 100644 --- a/packages/@headlessui-react/src/types.ts +++ b/packages/@headlessui-react/src/types.ts @@ -1,3 +1,4 @@ +import { ReactNode, ReactElement } from 'react' // A unique placeholder we can use as some defaults. This is nice because we can use this instead of // defaulting to null / never / ... and possibly collide with actual data. const __: unique symbol = Symbol('__placeholder__') @@ -9,11 +10,17 @@ export type PropsOf = TTag extends React.ElementType ? React.ComponentProps : never -export type Props = { +export type Props< + TTag, + TSlot = any, + TOmitableProps extends keyof any = __ +> = (TOmitableProps extends __ + ? Omit, 'as' | 'children' | 'refName'> + : Omit, TOmitableProps | 'as' | 'children' | 'refName'>) & { as?: TTag - children?: React.ReactNode | ((bag: TSlot) => React.ReactElement) + children?: ReactNode | ((bag: TSlot) => ReactElement) refName?: string -} & (TOmitableProps extends __ ? PropsOf : Omit, TOmitableProps>) +} type Without = { [P in Exclude]?: never } export type XOR = T | U extends __ diff --git a/packages/@headlessui-react/src/utils/render.ts b/packages/@headlessui-react/src/utils/render.ts index b001f6edad..bcc6541132 100644 --- a/packages/@headlessui-react/src/utils/render.ts +++ b/packages/@headlessui-react/src/utils/render.ts @@ -88,7 +88,7 @@ export function render( - props: Expand & { ref?: unknown }>, + props: Props & { ref?: unknown }, bag: TBag, tag: ElementType ) {