11import styles from './Section.module.scss'
2- import { forwardRef } from 'react'
2+ import { forwardRef , useRef , useState , useEffect } from 'react'
3+ import cn from 'classnames'
34
45type Props = {
56 title : string
@@ -8,11 +9,55 @@ type Props = {
89}
910
1011export const Section = forwardRef < HTMLDivElement , Props > ( ( props , ref ) => {
12+ const marker_ref = useRef < HTMLDivElement > ( null )
13+ const container_ref = useRef < HTMLDivElement > ( null )
14+ const [ is_stuck , set_is_stuck ] = useState ( false )
15+
16+ useEffect ( ( ) => {
17+ const marker = marker_ref . current
18+ const container = container_ref . current
19+ if ( ! marker || ! container ) return
20+
21+ let is_marker_stuck = false
22+ let is_container_visible = true
23+
24+ const update_stuck_state = ( ) => {
25+ set_is_stuck ( is_marker_stuck && is_container_visible )
26+ }
27+
28+ const marker_observer = new IntersectionObserver (
29+ ( [ entry ] ) => {
30+ is_marker_stuck = ! entry . isIntersecting
31+ update_stuck_state ( )
32+ } ,
33+ { threshold : 1 }
34+ )
35+
36+ const container_observer = new IntersectionObserver (
37+ ( [ entry ] ) => {
38+ is_container_visible = entry . isIntersecting
39+ update_stuck_state ( )
40+ } ,
41+ { threshold : 0 }
42+ )
43+
44+ marker_observer . observe ( marker )
45+ container_observer . observe ( container )
46+
47+ return ( ) => {
48+ marker_observer . disconnect ( )
49+ container_observer . disconnect ( )
50+ }
51+ } , [ ] )
52+
1153 return (
12- < div ref = { ref } className = { styles . container } >
13- < div className = { styles . header } >
14- < div className = { styles . title } > { props . title } </ div >
15- < div className = { styles . subtitle } > { props . subtitle } </ div >
54+ < div ref = { container_ref } className = { styles . container } >
55+ < div
56+ className = { cn ( styles . header , { [ styles [ 'header--stuck' ] ] : is_stuck } ) }
57+ >
58+ < div className = { styles . header__marker } ref = { marker_ref } />
59+ < div className = { styles . header__title } > { props . title } </ div >
60+ < div className = { styles . header__subtitle } > { props . subtitle } </ div >
1661 </ div >
1762 { props . children }
1863 </ div >
0 commit comments