primitives
primitives copied to clipboard
[Accordion][Collapsible][Tabs][…] Consider adding an option to control how `Content` is mounted/unmounted over time/activation cycle
Feature request
Overview
For the tabs I would like an option to keep the inactive tab contents around in the DOM. For components with a heavy mounting cost, or components with internal state, the current solution is suboptimal. Instead of unmounting, tabs could be set to aria-hidden
.
Examples in other libraries
Reach works like this: https://reach.tech/tabs/
Who does this impact? Who is this for?
Anyone using the tabs for components with internal state.
Additional context
n/a
Edit (April 5th 2022): People tend to ask for one or the other, so the gist is for us to see if we can provide an option to cater for both.
We had a previous discussion about all this for reference https://github.com/radix-ui/primitives/discussions/855
Notably a "lazy" state which could be useful where the tab contents start unmounted but remain mounted when opened and then closed https://github.com/radix-ui/primitives/discussions/855#discussioncomment-1621945
Hi, just looping back on this. I saw you mentioned about the previous discussion as reference, but is there a conclusion over this request? Seems that both behavior are useful, so I can think of this as a prop like hasDestructiveBehavior
being acting as flag, and then if the flag is enabled then the elements are going to be unmounted from the DOM, if not enabled simply hiding them but not removing them from the DOM.
Asking about this cause we are using this tabs and we have some text edit boxes implemented on our site that are placed over the tabs content that needs to retain its state if the other tab content is active, like when you are writing a big amount of text and it gets lost because of changing the tab. Happy to contribute to add this change if needed :)
Thanks in advance!
Based on @jjenzz 's solution from https://github.com/radix-ui/primitives/discussions/855#discussioncomment-1626807 , You can keep tab content mounted and visually hidden by
const [tab, setActiveTab] = useState("0");
<Accordion value={tab} onValueChange={setActiveTab}>
// ...
<Accordion.Content forceMount={true} hidden={activeTab !== tab} />
// ...
</Accordion>
The problem is that because now the visibility is controlled by hidden={activeTab !== tab}
, we lost the animation of collapsing, From a user's perspective, this will be simply viewed as buggy or laggy. So we still end up lifting the heavy computation above the Accordion
component.
I'm actually not sure how to resolve this problem.
Apologize for the tagging, @jjenzz is there anyway we can utilize the current tool to enable the collapse animation to further expand your solution as a workaround in this case?
For those that use forceMount
, you also have to add an onPointerLeave
on the NavigationMenuPrimitive.Viewport
primitive. This way the content won't close when your mouse goes out of it.
For those that use
forceMount
, you also have to add anonPointerLeave
on theNavigationMenuPrimitive.Viewport
primitive. This way the content won't close when your mouse goes out of it.
I personally don't have this issue. Animations would be nice though
You could also use the state data attribute as the conditional. I personally find this a bit cleaner than having useState.
<Tabs.Content
value='tab-1'
forceMount
className='data-[state=inactive]:hidden'
>
{children}
</Tabs.Content>
It would be great to have an option for preserving content on Accordion Content hide
You could also use the state data attribute as the conditional. I personally find this a bit cleaner than having useState.
<Tabs.Content value='tab-1' forceMount className='data-[state=inactive]:hidden' > {children} </Tabs.Content>
How do you use this? Super new to Radix, and would also like to preserve content when the accordion is collapsed without having to useState. Thank you!
It would be great to have an option for preserving content on Accordion Content hide
You could also use the state data attribute as the conditional. I personally find this a bit cleaner than having useState.
<Tabs.Content value='tab-1' forceMount className='data-[state=inactive]:hidden' > {children} </Tabs.Content>
How do you use this? Super new to Radix, and would also like to preserve content when the accordion is collapsed without having to useState. Thank you!
For Accordion in tailwind it should be data=[state=closed]:hidden
instead of inactive
for it to work.