@@ -53,6 +53,35 @@ function BaseDemo({ horizontal = false }: DemoProps) {
5353 )
5454}
5555
56+ // Sticky layer wrapped in a component rather than passed as a direct child of
57+ // Parallax — the scenario reported in #2052.
58+ function WrappedSticky ( ) {
59+ return (
60+ < ParallaxLayer sticky = { { start : 1 , end : 2 } } data-testid = "sticky-layer" >
61+ < div > Sticky</ div >
62+ </ ParallaxLayer >
63+ )
64+ }
65+
66+ function WrappedStickyDemo ( ) {
67+ return (
68+ < div
69+ style = { {
70+ position : 'absolute' ,
71+ top : 0 ,
72+ left : 0 ,
73+ width : WIDTH ,
74+ height : HEIGHT ,
75+ } }
76+ >
77+ < Parallax pages = { 3 } data-testid = "container" >
78+ < ParallaxLayer offset = { 1 } speed = { 1 } data-testid = "default-layer" />
79+ < WrappedSticky />
80+ </ Parallax >
81+ </ div >
82+ )
83+ }
84+
5685function transformOf ( testId : string ) : string {
5786 const el = page . getByTestId ( testId ) . element ( ) as HTMLElement
5887 return el . style . transform
@@ -134,6 +163,28 @@ describe('Parallax - vertical', () => {
134163 } )
135164} )
136165
166+ describe ( 'Parallax - sticky layer wrapped in a component (#2052)' , ( ) => {
167+ beforeEach ( async ( ) => {
168+ await page . viewport ( WIDTH , HEIGHT )
169+ render ( < WrappedStickyDemo /> )
170+ } )
171+
172+ // Skipped: documents a known, unfixed limitation. Parallax decides DOM
173+ // placement by reading `child.props.sticky` while walking its children with
174+ // React.Children.map, which traverses the static element tree and never
175+ // renders components — so a wrapped layer's `sticky` prop is invisible and it
176+ // lands inside the scrolling content, scrolling away between start and end.
177+ // A real fix moves the placement decision into the layer (e.g. createPortal).
178+ // Unskip when #2052 is fixed.
179+ it . skip ( 'keeps the sticky layer a direct child of the container, not the scrolling content' , async ( ) => {
180+ const sticky = page . getByTestId ( 'sticky-layer' ) . element ( ) as HTMLElement
181+ // A sticky layer must render as a sibling of the scrolling content div
182+ // (i.e. a direct child of the container), otherwise it scrolls away and
183+ // vanishes between its start and end offsets.
184+ expect ( sticky . parentElement ?. dataset . testid ) . toBe ( 'container' )
185+ } )
186+ } )
187+
137188describe ( 'Parallax - horizontal' , ( ) => {
138189 beforeEach ( async ( ) => {
139190 await page . viewport ( WIDTH , HEIGHT )
0 commit comments