Files
headlessui/playgrounds/react/pages/transitions/component-examples/nested/unmount.tsx
T
Robin Malfait 8fa5caf0dc Change default tag from div to Fragment on Transition components (#3110)
* use `Fragment` as the default element for `Transition` components

* update tests to reflect default tag change

* only error on missing `ref` if it's actually required

If the `<Transition />` component "root" is used as a root placeholder
(for state management) and not making actual transitions itself, then we
don't require a `ref` element.

* add test to ensure we don't error on missing `ref` when not required

+ add `className="…"` to some places to indicate that we _do_ want to
  perform a transition and thus have to fail if the `ref` is missing.

* improve `requiresRef` check

Also ensure that a ref is required if the `as` prop is provided and
it's not a `Fragment`

* add `shouldForwardRef` helper

* fix broken tests

These tests were rendering a `Debug` element that didn't render any DOM
nodes. Adding `as="div"` ensures that we are forwarding the ref
correctly.

* update changelog

* update playgrounds to reflect tag change

* Tweak changelog

---------

Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>
2024-04-19 16:15:11 +02:00

62 lines
1.9 KiB
TypeScript

import { Transition } from '@headlessui/react'
import { ReactNode, useState } from 'react'
export default function Home() {
let [isOpen, setIsOpen] = useState(true)
return (
<>
<div className="flex h-full w-screen justify-center bg-gray-50 p-12">
<div className="w-96 space-y-2">
<span className="inline-flex rounded-md shadow-sm">
<button
type="button"
onClick={() => setIsOpen((v) => !v)}
className="duration-150-out focus:shadow-outline-blue inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium leading-4 text-gray-700 transition hover:text-gray-500 focus:border-blue-300 focus:outline-none active:bg-gray-50 active:text-gray-800"
>
{isOpen ? 'Hide' : 'Show'}
</button>
</span>
<Transition as="div" show={isOpen} unmount={true}>
<Box>
<Box>
<Box>
<Box />
</Box>
<Box>
<Box>
<Box>
<Box />
</Box>
</Box>
</Box>
</Box>
</Box>
</Transition>
</div>
</div>
</>
)
}
function Box({ children }: { children?: ReactNode }) {
return (
<Transition.Child
as="div"
unmount={true}
enter="transition translate duration-300"
enterFrom="transform -translate-x-full"
enterTo="transform translate-x-0"
leave="transition translate duration-300"
leaveFrom="transform translate-x-0"
leaveTo="transform translate-x-full"
>
<div className="space-y-2 rounded-md bg-white p-4 text-sm font-semibold uppercase tracking-wide text-gray-700 shadow">
<span>This is a box</span>
{children}
</div>
</Transition.Child>
)
}