Transitions
Learn how to use transitions with Bits UI components.
Svelte Transitions are one of the awesome features of Svelte. Unfortunately, they don't play very nicely with components.
This is due to the fact that they rely on various directives like in:
, out:
, and transition:
to use them, which aren't supported by Svelte components.
In previous version of Bits UI, we had a workaround for this by exposing a ton of transition*
props on the components that we felt were most likely to be used with transitions. However, this was a bit of a hack and limited us to only Svelte Transitions, and users who wanted to use other libraries or just CSS were left out.
With Bits UI for Svelte 5, we've completely removed this workaround and instead exposed props and snippets that allow you to use any animation or transitions library you want.
The Defaults
By default, Bits UI components handle the mounting and unmounting of specific components for you. They are wrapped in a component that ensures the component waits for transitions to finish before unmounting.
You can use any CSS transitions or animations you want with this approach, which is what we're doing in the various example components in this documentation, using tailwindcss-animate.
Force Mounting
On each component that we conditionally render, a forceMount
prop is exposed. If set to true
, the component will be forced to mount in the DOM and become visible to the user. You can use this prop in conjunction with the delegated child
snippet to conditionally render the component and apply Svelte Transitions or another animation library.
The child
snippet exposes a prop that you can use to conditionally render the element and apply your transitions.
In the example above, we're using the forceMount
prop to tell the component to forcefully mount the Dialog.Content
component. We're then using the child
snippet to delegate the rendering of the Dialog.Content
to a div
element which we can apply our props and transitions to.
We understand this isn't the prettiest syntax, but it enables us to cover everyones use cases. If you intend to use this approach across your application, we recommend creating a reusable component that handles this logic, like so:
Which can then be used alongside the other Dialog.*
components: