Support transitions based on list mutations #732
Replies: 13 comments 1 reply
-
Thanks @sarahdayan suggested workaround did help me overcome this same issue that you are describing. And I do agree that, it does become an additional effort to manage additional prop rather than having filtered array of only needed items. |
Beta Was this translation helpful? Give feedback.
-
same request here ! |
Beta Was this translation helpful? Give feedback.
-
Same request |
Beta Was this translation helpful? Give feedback.
-
Came looking for function SomeComponent({ onRemove }: { onRemove: MouseEventHandler<HTMLButtonElement> }) {
const [shown, setShown] = useState(true);
const delayRemove = (evt) => {
setShown(false);
setTimeout(onRemove(evt), 150);
};
return (
<Transition
show={shown}
leave='transition duration-150'
leaveFrom='opacity-100'
leaveTo='opacity-0'
...
>
...
<button onClick={delayRemove}>Remove</button>
</Transition>
)
} |
Beta Was this translation helpful? Give feedback.
-
Same request here! @RobinMalfait any news on this? |
Beta Was this translation helpful? Give feedback.
-
Same request over here! Would love a headlessui transition group. |
Beta Was this translation helpful? Give feedback.
-
I haven't published this to npm or written proper docs yet, but I have been playing with an Would love input! |
Beta Was this translation helpful? Give feedback.
-
Another +1 here. |
Beta Was this translation helpful? Give feedback.
-
@RobinMalfait @adamwathan still no updates on this? :( |
Beta Was this translation helpful? Give feedback.
-
Here's my go at this; first, the solution, then a short explanation: function List() {
const [items, setItems] = useState([]);
const close = (item) => (e) => {
setItems(items.filter((i) => i.id !== item.id));
};
return (
{items.length > 0 && (
<>
{items.map((item) => (
<ListItem item={item} key={item.id} close={close} />
))}
</>
)}
);
}
function ListItem({ item, close }) {
const [show, setShow] = useState(true);
return (
<Transition
appear={true}
show={show}
afterLeave={close(item)}
as={Fragment}
>
<Transition.Child
as={'div'}
className="w-full max-w-sm overflow-hidden bg-white rounded-lg shadow-lg pointer-events-auto ring-1 ring-black ring-opacity-5"
enter="transform ease-out duration-300 transition"
enterFrom="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
enterTo="translate-y-0 opacity-100 sm:translate-x-0"
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
{item.name}
<button onClick={() => setShow(!show)}>Close</button>
</Transition.Child>
</Transition>
)
} First, create a Next, separate the mapped list items into their own Finally, note the following in the
Hope that helps anybody still wrestling with this! |
Beta Was this translation helpful? Give feedback.
-
Still unfortunately unsupported, had to switch to Framer :/ |
Beta Was this translation helpful? Give feedback.
-
+1 for addressing this natively.. running into this issue. Thanks to everyone who provided their solutions. |
Beta Was this translation helpful? Give feedback.
-
Heads up, I switched to using a lightweight package named AutoAnimate to solve this -- https://github.com/formkit/auto-animate. Code to implement and bundle size is minimal and works perfectly for this use case. |
Beta Was this translation helpful? Give feedback.
-
Hey Tailwind UI team! Thanks for the lovely library.
I'm creating ecommerce examples with Tailwind UI and Headless UI, and a typical scenario where you want to animate transitions is when adding items to or deleting items from a list (e.g., adding or removing items from a cart).
Here's an example with todos:
transition-list.mov
When doing so, you typically want to delete items no differently from if you weren't transitioning, and let the transition component handle the animation. This is currently not possible with Headless UI because it doesn't provide a way to track mutations on a list.
For example, the following React example wouldn't work (items would disappear but without transitions):
To make it work, you'd need to mutate some prop on each item (e.g.,
isRemoved: true
) instead of mutating the list.This solution works, but forces you to adapt your data to implementation details of the transition library. This is a code smell, and can be annoying when you need to perform further manipulation on the data (e.g., computing a total price on a list of items in a cart, extracting the items count) because you must filter out "soft deleted" items.
A possible solution would be to do something similar to what React Transition Group does with its
TransitionGroup
component, by tracking mutations on the passedchildren
and automatically update theshow
prop.@RobinMalfait Is there already something similar in the Headless UI roadmap? And if not, is this a problem you'd be interested seeing solved in Headless UI?
Beta Was this translation helpful? Give feedback.
All reactions