Skip to content

Commit 7e87d33

Browse files
cwoolummaiieul
andauthored
Update animations functionality to only support the native popover approach (#970)
* Change how popover animations work and update docs * fix: modal route not working + naming * fix: modal route not working + naming #2 * fix: p code style * chore: remove unnecessary import * refactor: make compatibility note easier to maintain --------- Co-authored-by: maiieul <[email protected]>
1 parent 9cb3c96 commit 7e87d33

File tree

25 files changed

+384
-305
lines changed

25 files changed

+384
-305
lines changed

.changeset/two-jeans-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/headless': minor
3+
---
4+
5+
We are removing the existing popover animations shimming and instead wil now only support native popover animations. This is considered a breaking change but will be more reliable overall.

.eslintignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ node_modules
22
dist
33
coverage
44
.eslintrc.*
5-
vite.config.ts
5+
vite.config.ts
6+
packages/kit-headless/browsers/**

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
jobs:
88
test:
99
runs-on: ubuntu-latest
10+
name: Test NodeJS ${{ matrix.node_version }}
1011

1112
strategy:
1213
matrix:

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
],
77
"editor.codeActionsOnSave": {
88
"source.removeUnusedImports": "explicit"
9-
}
9+
},
10+
"vitest.disableWorkspaceWarning": true
1011
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { Note, NoteStatus } from '../note/note'; // Adjust the import path based on your structure
3+
4+
export const TopLayerAnimationsCaveats = component$(() => {
5+
return (
6+
<Note status={NoteStatus.Warning}>
7+
<strong>Important Caveats for Animating Discrete Properties</strong>
8+
9+
<ul class="mt-4 list-disc bg-gradient-to-b pl-4">
10+
<li>
11+
<strong>
12+
Animating <code>display</code> and <code>overlay</code>:
13+
</strong>
14+
<p>
15+
The <code>display</code> property must be included in the transitions list to
16+
ensure the element remains visible throughout the animation. The value flips
17+
from <code>none</code> to <code>block</code> at 0% of the animation, ensuring
18+
visibility for the entire duration. The&nbsp;
19+
<code>overlay</code> ensures the element stays in the top layer until the
20+
animation completes.
21+
</p>
22+
</li>
23+
<li>
24+
<strong>
25+
Using <code>transition-behavior: allow-discrete</code>:
26+
</strong>
27+
<p>
28+
This property is essential when animating discrete properties like{' '}
29+
<code>display</code> and <code>overlay</code>, which are not typically
30+
animatable. It ensures smooth transitions for these discrete properties.
31+
</p>
32+
</li>
33+
<li>
34+
<strong>
35+
Setting Starting Styles with <code>@starting-style</code>:
36+
</strong>
37+
<p>
38+
CSS transitions are only triggered when a property changes on a visible
39+
element. The&nbsp;
40+
<code>@starting-style</code> at-rule allows you to set initial styles (e.g.,{' '}
41+
<code>opacity</code> and
42+
<code>transform</code>) when the element first appears, ensuring that the
43+
animation behaves predictably.
44+
</p>
45+
</li>
46+
</ul>
47+
</Note>
48+
);
49+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { component$ } from '@builder.io/qwik';
2+
import { Note, NoteStatus } from '../note/note'; // Adjust the import path based on your structure
3+
4+
export const BrowserAnimationsCompatability = component$(() => {
5+
return (
6+
<Note status={NoteStatus.Info}>
7+
<div class="flex flex-col gap-2">
8+
<h4>
9+
<strong>Browser Compatability</strong>
10+
</h4>
11+
<p>
12+
<a href="https://caniuse.com/?search=popover%20API">
13+
Browser versions that do not support the popover API natively
14+
</a>{' '}
15+
have known issues when trying to use animations or transitions. If you need to
16+
support legacy versions of browsers, please be sure to test this functionality
17+
independently.
18+
</p>
19+
</div>
20+
</Note>
21+
);
22+
});

apps/website/src/components/mdx-components/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { KeyboardInteractionTable } from '../keyboard-interaction-table/keyboard
1111
import { Note } from '../note/note';
1212
import { Showcase } from '../showcase/showcase';
1313
import { StatusBanner } from '../status-banner/status-banner';
14+
import { TopLayerAnimationsCaveats } from '../animations/caveats';
15+
import { BrowserAnimationsCompatability } from '../animations/compatability';
1416

1517
export const components: Record<string, Component> = {
1618
p: component$<PropsOf<'p'>>(({ ...props }) => {
@@ -134,4 +136,6 @@ export const components: Record<string, Component> = {
134136
StatusBanner,
135137
Showcase,
136138
AutoAPI,
139+
TopLayerAnimationsCaveats,
140+
BrowserAnimationsCompatability,
137141
};

apps/website/src/routes/docs/headless/modal/examples/animatable.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,37 @@
11
import { component$, useStyles$ } from '@builder.io/qwik';
22
import { Modal, Label } from '@qwik-ui/headless';
3-
import styles from '../snippets/animation.css?inline';
43

54
export default component$(() => {
6-
useStyles$(styles);
5+
useStyles$(`
6+
.modal-animation {
7+
animation: modalClose 0.35s ease-in-out forwards;
8+
}
9+
10+
.modal-animation:popover-open {
11+
animation: modalOpen 0.75s ease-in-out forwards;
12+
}
13+
14+
@keyframes modalOpen {
15+
from {
16+
opacity: 0;
17+
transform: scale(0.9);
18+
}
19+
to {
20+
opacity: 1;
21+
transform: scale(1);
22+
}
23+
}
24+
25+
@keyframes modalClose {
26+
from {
27+
opacity: 1;
28+
transform: scale(1);
29+
}
30+
to {
31+
opacity: 0;
32+
transform: scale(0.9);
33+
}
34+
}`);
735

836
return (
937
<Modal.Root>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { component$, useStyles$ } from '@builder.io/qwik';
2+
import { Modal, Label } from '@qwik-ui/headless';
3+
4+
export default component$(() => {
5+
useStyles$(`
6+
.modal-animation[open]::backdrop {
7+
animation: backdropFadeIn 0.75s ease-in-out forwards;
8+
}
9+
10+
@keyframes backdropFadeIn {
11+
from {
12+
background-color: rgba(0, 0, 0, 0);
13+
}
14+
to {
15+
background-color: rgba(0, 0, 0, 0.65);
16+
}
17+
}`);
18+
19+
return (
20+
<Modal.Root>
21+
<Modal.Trigger class="modal-trigger">Open Modal</Modal.Trigger>
22+
<Modal.Panel class="modal-panel modal-animation">
23+
<Modal.Title>Edit Profile</Modal.Title>
24+
<Modal.Description>
25+
You can update your profile here. Hit the save button when finished.
26+
</Modal.Description>
27+
<Label>
28+
Name
29+
<input type="text" placeholder="John Doe" />
30+
</Label>
31+
<Label>
32+
Email
33+
<input type="text" placeholder="[email protected]" />
34+
</Label>
35+
<footer>
36+
<Modal.Close class="modal-close">Cancel</Modal.Close>
37+
<Modal.Close class="modal-close">Save Changes</Modal.Close>
38+
</footer>
39+
</Modal.Panel>
40+
</Modal.Root>
41+
);
42+
});

apps/website/src/routes/docs/headless/modal/examples/transition.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
import { component$, useStyles$ } from '@builder.io/qwik';
22
import { Modal, Label } from '@qwik-ui/headless';
3-
import styles from '../snippets/animation.css?inline';
43

54
export default component$(() => {
6-
useStyles$(styles);
5+
useStyles$(`
6+
.modal-transition {
7+
opacity: 0;
8+
transform: scale(0.9);
9+
transition:
10+
opacity 0.35s ease-in-out,
11+
transform 0.35s ease-in-out,
12+
display 0.35s,
13+
overlay 0.35s;
14+
transition-behavior: allow-discrete;
15+
}
16+
17+
.modal-transition:popover-open {
18+
opacity: 1;
19+
transform: scale(1);
20+
}
21+
22+
@starting-style {
23+
.modal-transition:popover-open {
24+
opacity: 0;
25+
transform: scale(0.9);
26+
}
27+
}`);
728

829
return (
930
<Modal.Root>

0 commit comments

Comments
 (0)