Skip to content

Commit f8c5c2a

Browse files
committed
Add test
1 parent c5e00e9 commit f8c5c2a

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

apps/builder/app/routes/_ui.playground.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,21 @@ import { Scroll } from "@webstudio-is/sdk-components-animation";
33
const Playground = () => {
44
return (
55
<>
6-
<Scroll debug={true} />
6+
<Scroll debug={process.env.NODE_ENV !== "production"}>
7+
<div
8+
style={{ height: "200px", width: "200px", backgroundColor: "red" }}
9+
></div>
10+
<div
11+
style={{
12+
height: "100px",
13+
width: "100px",
14+
backgroundColor: "yellow",
15+
position: "fixed",
16+
left: 0,
17+
top: 0,
18+
}}
19+
></div>
20+
</Scroll>
721
</>
822
);
923
};

packages/sdk-components-animation/src/scroll.tsx

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,53 @@ import { escapeCssSpecifier } from "./shared/css-utils";
77

88
const componentAttributeId = `data-ws-animate-id`;
99

10+
const createSelector = (id: string) => `[${componentAttributeId}="${id}"] > *`;
11+
1012
const Animate = ({ id }: { id: string }) => {
1113
useLayoutEffect(() => {
12-
const elt = document.querySelector(`[${componentAttributeId}="${id}"]`);
13-
if (elt === null) {
14+
const selector = createSelector(id);
15+
const elements = document.querySelectorAll(selector);
16+
if (elements.length === 0) {
1417
return;
1518
}
19+
const disposables = Array.from(elements)
20+
.map((elt) => {
21+
if (elt instanceof HTMLElement) {
22+
const animation = elt.animate(
23+
[{ offset: 0, transform: "translate(0, 100px)" }],
24+
{
25+
fill: "backwards",
26+
duration: 400,
27+
easing: "linear",
28+
}
29+
);
1630

17-
if (elt instanceof HTMLElement) {
18-
const animation = elt.animate(
19-
[{ offset: 0, transform: "translate(0, 100px)" }],
20-
{
21-
fill: "backwards",
22-
duration: 400,
23-
easing: "linear",
31+
return () => {
32+
animation.cancel();
33+
};
2434
}
25-
);
35+
})
36+
.filter((disposable) => disposable !== undefined);
2637

27-
return () => {
28-
animation.cancel();
29-
};
30-
}
38+
return () => {
39+
disposables.forEach((dispose) => dispose());
40+
};
3141
}, [id]);
3242

3343
return undefined;
3444
};
3545

3646
const StylesBeforeAnimate = ({ id }: { id: string }) => {
47+
const selector = createSelector(id);
48+
3749
const styleContent = `
3850
@keyframes ws-scroll-animation-${id} {
3951
from {
4052
transform: translate(0, 100px);
4153
}
4254
}
4355
44-
[${componentAttributeId}="${id}"] {
56+
${selector} {
4557
animation-name: ws-scroll-animation-${id};
4658
animation-fill-mode: backwards;
4759
animation-play-state: paused;
@@ -52,9 +64,9 @@ const StylesBeforeAnimate = ({ id }: { id: string }) => {
5264
return <style dangerouslySetInnerHTML={{ __html: styleContent }} />;
5365
};
5466

55-
type ScrollProps = { debug?: boolean };
67+
type ScrollProps = { debug?: boolean; children?: React.ReactNode };
5668

57-
export const Scroll = ({ debug = false }: ScrollProps) => {
69+
export const Scroll = ({ debug = false, children }: ScrollProps) => {
5870
const nakedId = useId();
5971
const id = escapeCssSpecifier(nakedId);
6072

@@ -74,21 +86,9 @@ export const Scroll = ({ debug = false }: ScrollProps) => {
7486
<Animate id={id} />
7587
</Suspense>
7688
</ClientOnly>
77-
<div
78-
{...{ [componentAttributeId]: id }}
79-
style={{ height: "200px", width: "200px", backgroundColor: "red" }}
80-
></div>
81-
<div
82-
data-ws-id={id}
83-
style={{
84-
height: "100px",
85-
width: "100px",
86-
backgroundColor: "yellow",
87-
position: "fixed",
88-
left: 0,
89-
top: 0,
90-
}}
91-
></div>
89+
<div {...{ [componentAttributeId]: id }} style={{ display: "contents" }}>
90+
{children}
91+
</div>
9292
</>
9393
);
9494
};

0 commit comments

Comments
 (0)