Fix issues spreading omitted props onto components (#3313)
* Simplify props types wip wip * Remove unused types * Remove test it’s no longer relevant * Update changelog
This commit is contained in:
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Nothing yet!
|
||||
### Fixed
|
||||
|
||||
- Fix issues spreading omitted props onto components ([#3313](https://github.com/tailwindlabs/headlessui/pull/3313))
|
||||
|
||||
## [2.1.0] - 2024-06-21
|
||||
|
||||
|
||||
@@ -318,7 +318,6 @@ function TransitionChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_
|
||||
leaveFrom,
|
||||
leaveTo,
|
||||
|
||||
// @ts-expect-error
|
||||
...theirProps
|
||||
} = props as typeof props
|
||||
let container = useRef<HTMLElement | null>(null)
|
||||
@@ -444,6 +443,8 @@ function TransitionChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_
|
||||
className:
|
||||
classNames(
|
||||
// Incoming classes if any
|
||||
// @ts-expect-error: className may not exist because not
|
||||
// all components accept className (but all HTML elements do)
|
||||
theirProps.className,
|
||||
|
||||
// Apply these classes immediately
|
||||
@@ -498,7 +499,6 @@ function TransitionRootFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_C
|
||||
props: TransitionRootProps<TTag>,
|
||||
ref: Ref<HTMLElement>
|
||||
) {
|
||||
// @ts-expect-error
|
||||
let { show, appear = false, unmount = true, ...theirProps } = props as typeof props
|
||||
let internalTransitionRef = useRef<HTMLElement | null>(null)
|
||||
let requiresRef = shouldForwardRef(props)
|
||||
@@ -610,10 +610,8 @@ function ChildFn<TTag extends ElementType = typeof DEFAULT_TRANSITION_CHILD_TAG>
|
||||
return (
|
||||
<>
|
||||
{!hasTransitionContext && hasOpenClosedContext ? (
|
||||
// @ts-expect-error This is an object
|
||||
<TransitionRoot ref={ref} {...props} />
|
||||
) : (
|
||||
// @ts-expect-error This is an object
|
||||
<InternalTransitionChild ref={ref} {...props} />
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -2,12 +2,6 @@ import type { JSXElementConstructor, ReactElement, ReactNode } from 'react'
|
||||
|
||||
export type ReactTag = keyof JSX.IntrinsicElements | JSXElementConstructor<any>
|
||||
|
||||
// A unique placeholder we can use as a default. This is nice because we can use this instead of
|
||||
// defaulting to null / never / ... and possibly collide with actual data.
|
||||
// Ideally we use a unique symbol here.
|
||||
let __ = '1D45E01E-AF44-47C4-988A-19A94EBAF55C' as const
|
||||
export type __ = typeof __
|
||||
|
||||
export type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never
|
||||
|
||||
export type PropsOf<TTag extends ReactTag> = TTag extends React.ElementType
|
||||
@@ -55,15 +49,4 @@ export type Props<
|
||||
ClassNameOverride<TTag, TSlot> &
|
||||
Overrides
|
||||
|
||||
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
|
||||
export type XOR<T, U> = T | U extends __
|
||||
? never
|
||||
: T extends __
|
||||
? U
|
||||
: U extends __
|
||||
? T
|
||||
: T | U extends object
|
||||
? (Without<T, U> & U) | (Without<U, T> & T)
|
||||
: T | U
|
||||
|
||||
export type EnsureArray<T> = T extends any[] ? T : Expand<T>[]
|
||||
|
||||
@@ -423,16 +423,6 @@ describe('Features.Static | Features.RenderStrategy', () => {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Can we "legit" test this? 🤔
|
||||
it('should result in a typescript error', () => {
|
||||
testRender(
|
||||
// @ts-expect-error static & unmount together are incompatible
|
||||
<Dummy show={false} static unmount>
|
||||
Contents
|
||||
</Dummy>
|
||||
)
|
||||
})
|
||||
|
||||
// To avoid duplication, and to make sure that the features tested in isolation can also be
|
||||
// re-used when they are combined.
|
||||
testStaticFeature(Dummy)
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
type ReactElement,
|
||||
type Ref,
|
||||
} from 'react'
|
||||
import type { Expand, Props, XOR, __ } from '../types'
|
||||
import type { Expand, Props } from '../types'
|
||||
import { classNames } from './class-names'
|
||||
import { match } from './match'
|
||||
|
||||
@@ -40,17 +40,21 @@ export enum RenderStrategy {
|
||||
Hidden,
|
||||
}
|
||||
|
||||
type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any
|
||||
? R
|
||||
: never
|
||||
|
||||
type PropsForFeature<
|
||||
TPassedInFeatures extends RenderFeatures,
|
||||
TForFeature extends RenderFeatures,
|
||||
TProps,
|
||||
> = {
|
||||
[P in TPassedInFeatures]: P extends TForFeature ? TProps : __
|
||||
}[TPassedInFeatures]
|
||||
> = TPassedInFeatures extends TForFeature ? TProps : {}
|
||||
|
||||
export type PropsForFeatures<T extends RenderFeatures> = XOR<
|
||||
PropsForFeature<T, RenderFeatures.Static, { static?: boolean }>,
|
||||
PropsForFeature<T, RenderFeatures.RenderStrategy, { unmount?: boolean }>
|
||||
export type PropsForFeatures<T extends RenderFeatures> = Expand<
|
||||
UnionToIntersection<
|
||||
| PropsForFeature<T, RenderFeatures.Static, { static?: boolean }>
|
||||
| PropsForFeature<T, RenderFeatures.RenderStrategy, { unmount?: boolean }>
|
||||
>
|
||||
>
|
||||
|
||||
export function render<TFeature extends RenderFeatures, TTag extends ElementType, TSlot>({
|
||||
|
||||
Reference in New Issue
Block a user