@@ -25,6 +25,13 @@ const createSelector = (id: string) => `[${componentAttributeId}="${id}"] > *`;
25
25
const cartesian = < A , B > ( a : A [ ] , b : B [ ] ) =>
26
26
a . flatMap ( ( x ) => b . map ( ( y ) => [ x , y ] as const ) ) ;
27
27
28
+ /**
29
+ * Scroll does not support https://drafts.csswg.org/scroll-animations/#named-ranges
30
+ * However, for simplicity and type unification with the view, we will use the names "start" and "end,"
31
+ * which will be transformed as follows:
32
+ * - "start" → `calc(0% + range)`
33
+ * - "end" → `calc(100% - range)`
34
+ */
28
35
const getScrollRangeValue = ( [ name , value ] : ScrollRangeValue ) => {
29
36
// See also WAAPI has bug https://issues.chromium.org/issues/40929569#comment9
30
37
// so we are using calc even it it's not needed in some cases
@@ -79,6 +86,7 @@ const Animate = ({ id, action }: { id: string; action: AnimationAction }) => {
79
86
const keyframe : Keyframe = {
80
87
offset : animationKeyframe . offset ,
81
88
composite : "auto" ,
89
+ // Probably having linear() easing we don't need easing per keyframe
82
90
// easing: animationKeyframe.easing,
83
91
} ;
84
92
@@ -114,6 +122,16 @@ const Animate = ({ id, action }: { id: string; action: AnimationAction }) => {
114
122
return undefined ;
115
123
} ;
116
124
125
+ /**
126
+ * We use JavaScript to execute animations.
127
+ * For animations that run initially, such as scroll or view-based animations,
128
+ * we need to set the initial position during server rendering.
129
+ *
130
+ * On the client side, there's another issue: we use Scroll and View Timeline polyfills.
131
+ * These polyfills must be loaded dynamically because they rely on the `window` object globally,
132
+ * making them incompatible with standard imports.
133
+ * Similarly, for SSR, we need to set styles if the polyfill hasn't loaded yet.
134
+ */
117
135
const StylesBeforeAnimate = ( {
118
136
id,
119
137
action,
@@ -141,6 +159,8 @@ const StylesBeforeAnimate = ({
141
159
( [ property , value ] ) => `${ hyphenateProperty ( property ) } :${ toValue ( value ) } ;`
142
160
) ;
143
161
162
+ // We use animation to set initial styles to ensure the exact same behavior
163
+ // (including specificity and keyframe composition) as the animation executed afterward.
144
164
styleContent = `
145
165
${ styleContent }
146
166
@@ -171,6 +191,7 @@ type ScrollProps = {
171
191
action : AnimationAction ;
172
192
} ;
173
193
194
+ // @todo : With high probablity it will be unified animation object
174
195
export const Scroll = forwardRef < ElementRef < "div" > , ScrollProps > (
175
196
( { debug = false , children, action } , ref ) => {
176
197
const nakedId = useId ( ) ;
0 commit comments