Skip to content

Commit af29093

Browse files
committed
Merge branch 'feat/css-transition-support' into feat/drawer
2 parents 77ce119 + 162f3b7 commit af29093

39 files changed

Lines changed: 611 additions & 228 deletions

.changeset/crazy-vans-follow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bits-ui": minor
3+
---
4+
5+
feat: support CSS transitions

docs/content/styling.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,30 @@ Here's an example styling an accordion with different states:
224224

225225
## Advanced Styling Techniques
226226

227+
### CSS Transitions on Mount-Managed Surfaces
228+
229+
Components that manage their mount lifecycle for animations expose transient
230+
`data-starting-style` and `data-ending-style` attributes on their animated
231+
surfaces. This is useful for popup content, overlays, and similar parts where
232+
you want enter and exit transitions without losing the close animation during
233+
unmount.
234+
235+
```css
236+
[data-popover-content] {
237+
opacity: 1;
238+
transform: scale(1);
239+
transition:
240+
opacity 150ms ease,
241+
transform 150ms ease;
242+
}
243+
244+
[data-popover-content][data-starting-style],
245+
[data-popover-content][data-ending-style] {
246+
opacity: 0;
247+
transform: scale(0.96);
248+
}
249+
```
250+
227251
### Combining Data Attributes with CSS Variables
228252

229253
You can combine data attributes with CSS variables to create dynamic styles based on component state. Here's how to animate the accordion content using the `--bits-accordion-content-height` variable and the `data-state` attribute:

docs/src/lib/content/api-reference/accordion.api.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import type {
55
AccordionRootPropsWithoutHTML,
66
AccordionTriggerPropsWithoutHTML,
77
} from "bits-ui";
8-
import { disabledDataAttr, forceMountProp, orientationDataAttr, withChildProps } from "./shared.js";
8+
import {
9+
disabledDataAttr,
10+
forceMountProp,
11+
orientationDataAttr,
12+
transitionStyleDataAttrs,
13+
withChildProps,
14+
} from "./shared.js";
915
import {
1016
HeaderLevelProp,
1117
OnChangeStringOrArrayProp,
@@ -150,6 +156,7 @@ const content = defineComponentApiSchema<AccordionContentPropsWithoutHTML>({
150156
dataAttributes: [
151157
orientationDataAttr,
152158
disabledDataAttr,
159+
...transitionStyleDataAttrs,
153160
defineSimpleDataAttr({
154161
name: "accordion-content",
155162
description: "Present on the content element.",

docs/src/lib/content/api-reference/alert-dialog.api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
preventOverflowTextSelectionProp,
2828
preventScrollProp,
2929
restoreScrollDelayProp,
30+
transitionStyleDataAttrs,
3031
withChildProps,
3132
} from "$lib/content/api-reference/shared.js";
3233
import {
@@ -104,6 +105,7 @@ const content = defineComponentApiSchema<AlertDialogContentPropsWithoutHTML>({
104105
},
105106
dataAttributes: [
106107
stateDataAttr,
108+
...transitionStyleDataAttrs,
107109
defineSimpleDataAttr({
108110
name: "alert-dialog-content",
109111
description: "Present on the content element.",
@@ -177,6 +179,7 @@ const overlay = defineComponentApiSchema<AlertDialogOverlayPropsWithoutHTML>({
177179
},
178180
dataAttributes: [
179181
stateDataAttr,
182+
...transitionStyleDataAttrs,
180183
defineSimpleDataAttr({
181184
name: "alert-dialog-overlay",
182185
description: "Present on the overlay element.",

docs/src/lib/content/api-reference/collapsible.api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
forceMountProp,
88
onOpenChangeCompleteProp,
99
onOpenChangeProp,
10+
transitionStyleDataAttrs,
1011
withChildProps,
1112
} from "./shared.js";
1213
import { CollapsibleContentChildSnippetProps } from "./extended-types/collapsible/index.js";
@@ -111,6 +112,7 @@ export const content = defineComponentApiSchema<CollapsibleContentPropsWithoutHT
111112
name: "disabled",
112113
description: "Present when the collapsible is disabled.",
113114
}),
115+
...transitionStyleDataAttrs,
114116
defineSimpleDataAttr({
115117
name: "collapsible-content",
116118
description: "Present on the content element.",

docs/src/lib/content/api-reference/combobox.api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
portalProps,
4040
preventOverflowTextSelectionProp,
4141
preventScrollProp,
42+
transitionStyleDataAttrs,
4243
withChildProps,
4344
} from "$lib/content/api-reference/shared.js";
4445
import {
@@ -163,6 +164,7 @@ export const content = defineComponentApiSchema<ComboboxContentPropsWithoutHTML>
163164
},
164165
dataAttributes: [
165166
stateDataAttr,
167+
...transitionStyleDataAttrs,
166168
defineSimpleDataAttr({
167169
name: "combobox-content",
168170
description: "Present on the content element.",
@@ -194,6 +196,7 @@ export const contentStatic = defineComponentApiSchema<ComboboxContentStaticProps
194196
},
195197
dataAttributes: [
196198
stateDataAttr,
199+
...transitionStyleDataAttrs,
197200
defineSimpleDataAttr({
198201
name: "combobox-content",
199202
description: "Present on the content element.",

docs/src/lib/content/api-reference/dialog.api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
preventOverflowTextSelectionProp,
2222
preventScrollProp,
2323
restoreScrollDelayProp,
24+
transitionStyleDataAttrs,
2425
withChildProps,
2526
} from "./shared.js";
2627
import { HeaderLevelProp, OpenClosedProp } from "./extended-types/shared/index.js";
@@ -110,6 +111,7 @@ export const content = defineComponentApiSchema<DialogContentPropsWithoutHTML>({
110111
},
111112
dataAttributes: [
112113
stateDataAttr,
114+
...transitionStyleDataAttrs,
113115
defineSimpleDataAttr({
114116
name: "dialog-content",
115117
description: "Present on the content.",
@@ -175,6 +177,7 @@ export const overlay = defineComponentApiSchema<DialogOverlayPropsWithoutHTML>({
175177
},
176178
dataAttributes: [
177179
stateDataAttr,
180+
...transitionStyleDataAttrs,
178181
defineSimpleDataAttr({
179182
name: "dialog-overlay",
180183
description: "Present on the overlay.",

docs/src/lib/content/api-reference/link-preview.api.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
onOpenChangeCompleteProp,
2121
onOpenChangeProp,
2222
portalProps,
23+
transitionStyleDataAttrs,
2324
withChildProps,
2425
} from "$lib/content/api-reference/shared.js";
2526
import {
@@ -98,6 +99,7 @@ export const content = defineComponentApiSchema<LinkPreviewContentPropsWithoutHT
9899
},
99100
dataAttributes: [
100101
openClosedDataAttr,
102+
...transitionStyleDataAttrs,
101103
defineSimpleDataAttr({
102104
name: "link-preview-content",
103105
description: "Present on the content element.",
@@ -120,6 +122,7 @@ export const contentStatic = defineComponentApiSchema<LinkPreviewContentStaticPr
120122
},
121123
dataAttributes: [
122124
openClosedDataAttr,
125+
...transitionStyleDataAttrs,
123126
defineSimpleDataAttr({
124127
name: "link-preview-content",
125128
description: "Present on the content element.",

docs/src/lib/content/api-reference/menu.api.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
preventScrollProp,
4141
radioGroupItemChildDefinition,
4242
radioGroupItemChildrenDefinition,
43+
transitionStyleDataAttrs,
4344
withChildProps,
4445
} from "./shared.js";
4546
import {
@@ -282,7 +283,7 @@ type DataAttrs = ComponentAPISchema["dataAttributes"];
282283

283284
const triggerAttrs: DataAttrs = [STATE];
284285

285-
const contentAttrs: DataAttrs = [STATE];
286+
const contentAttrs: DataAttrs = [STATE, ...transitionStyleDataAttrs];
286287

287288
const arrowAttrs: DataAttrs = [STATE];
288289

@@ -340,7 +341,7 @@ const separatorAttrs: DataAttrs = [
340341
}),
341342
];
342343

343-
const subContentAttrs: DataAttrs = [STATE];
344+
const subContentAttrs: DataAttrs = [STATE, ...transitionStyleDataAttrs];
344345

345346
const subTriggerAttrs: DataAttrs = [...sharedItemAttrs, STATE];
346347

docs/src/lib/content/api-reference/navigation-menu.api.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
dismissibleLayerProps,
1515
escapeLayerProps,
1616
forceMountProp,
17+
transitionStyleDataAttrs,
1718
withChildProps,
1819
} from "./shared.js";
1920
import {
@@ -27,6 +28,7 @@ import {
2728
defineEnumProp,
2829
defineFunctionProp,
2930
defineNumberProp,
31+
defineSimpleDataAttr,
3032
defineStringProp,
3133
} from "../utils.js";
3234

@@ -133,6 +135,13 @@ export const content = defineComponentApiSchema<NavigationMenuContentPropsWithou
133135
forceMount: forceMountProp,
134136
...withChildProps({ elType: "HTMLDivElement" }),
135137
},
138+
dataAttributes: [
139+
...transitionStyleDataAttrs,
140+
defineSimpleDataAttr({
141+
name: "navigation-menu-content",
142+
description: "Present on the content element.",
143+
}),
144+
],
136145
});
137146

138147
export const link = defineComponentApiSchema<NavigationMenuLinkPropsWithoutHTML>({
@@ -160,6 +169,13 @@ export const indicator = defineComponentApiSchema<NavigationMenuIndicatorPropsWi
160169
forceMount: forceMountProp,
161170
...withChildProps({ elType: "HTMLSpanElement" }),
162171
},
172+
dataAttributes: [
173+
...transitionStyleDataAttrs,
174+
defineSimpleDataAttr({
175+
name: "navigation-menu-indicator",
176+
description: "Present on the indicator element.",
177+
}),
178+
],
163179
});
164180

165181
export const viewport = defineComponentApiSchema<NavigationMenuViewportPropsWithoutHTML>({
@@ -170,6 +186,13 @@ export const viewport = defineComponentApiSchema<NavigationMenuViewportPropsWith
170186
forceMount: forceMountProp,
171187
...withChildProps({ elType: "HTMLDivElement" }),
172188
},
189+
dataAttributes: [
190+
...transitionStyleDataAttrs,
191+
defineSimpleDataAttr({
192+
name: "navigation-menu-viewport",
193+
description: "Present on the viewport element.",
194+
}),
195+
],
173196
});
174197

175198
export const navigationMenu = [root, sub, list, item, trigger, content, link, viewport, indicator];

0 commit comments

Comments
 (0)