11import React , { useCallback , useImperativeHandle , forwardRef , useState , useEffect } from 'react'
22import { twMerge } from 'tailwind-merge'
3+ import { useModalBottomToTopOptional } from './ModalBottomToTopContext'
34
45interface ModalBottomToTopProps {
56 modalId ?: string
@@ -32,21 +33,35 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
3233 const [ startHeight , setStartHeight ] = useState < number > ( 0 )
3334 const [ isTouched , setIsTouched ] = useState < boolean > ( false )
3435
36+ // Use context if available, otherwise rely on checkbox state
37+ const modalContext = useModalBottomToTopOptional ( )
38+
3539 const handleCheckboxChange = useCallback (
3640 ( event : React . ChangeEvent < HTMLInputElement > ) => {
37- if ( event . target . checked ) {
41+ const isChecked = event . target . checked
42+
43+ if ( isChecked ) {
3844 window . history . pushState ( { modal : modalId } , '' )
3945 } else {
4046 if ( window . history . state ?. modal === modalId ) {
4147 window . history . back ( )
4248 }
4349 }
4450
51+ // Update context if available
52+ if ( modalContext ) {
53+ if ( isChecked ) {
54+ modalContext . openModal ( )
55+ } else {
56+ modalContext . closeModal ( )
57+ }
58+ }
59+
4560 if ( onModalStateChange ) {
46- onModalStateChange ( event . target . checked )
61+ onModalStateChange ( isChecked )
4762 }
4863 } ,
49- [ onModalStateChange , modalId ]
64+ [ onModalStateChange , modalId , modalContext ]
5065 )
5166
5267 const handleTouchStart = useCallback (
@@ -91,6 +106,13 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
91106 }
92107 } , [ isDragging ] )
93108
109+ // Sync context state with checkbox
110+ useEffect ( ( ) => {
111+ if ( modalContext && checkboxRef . current ) {
112+ checkboxRef . current . checked = modalContext . isOpen
113+ }
114+ } , [ modalContext ?. isOpen ] )
115+
94116 useEffect ( ( ) => {
95117 const handlePopState = ( ) => {
96118 if ( checkboxRef . current ?. checked ) {
@@ -105,22 +127,32 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
105127 return ( ) => window . removeEventListener ( 'popstate' , handlePopState )
106128 } , [ handleCheckboxChange ] )
107129
108- useImperativeHandle ( ref , ( ) => ( {
109- check : ( ) => {
110- if ( checkboxRef . current ) {
111- checkboxRef . current . checked = true
112- handleCheckboxChange ( { target : { checked : true } } as React . ChangeEvent < HTMLInputElement > )
113- }
114- } ,
115- uncheck : ( ) => {
116- if ( checkboxRef . current ) {
117- checkboxRef . current . checked = false
118- handleCheckboxChange ( {
119- target : { checked : false }
120- } as React . ChangeEvent < HTMLInputElement > )
130+ useImperativeHandle (
131+ ref ,
132+ ( ) => ( {
133+ check : ( ) => {
134+ if ( modalContext ) {
135+ modalContext . openModal ( )
136+ } else if ( checkboxRef . current ) {
137+ checkboxRef . current . checked = true
138+ handleCheckboxChange ( {
139+ target : { checked : true }
140+ } as React . ChangeEvent < HTMLInputElement > )
141+ }
142+ } ,
143+ uncheck : ( ) => {
144+ if ( modalContext ) {
145+ modalContext . closeModal ( )
146+ } else if ( checkboxRef . current ) {
147+ checkboxRef . current . checked = false
148+ handleCheckboxChange ( {
149+ target : { checked : false }
150+ } as React . ChangeEvent < HTMLInputElement > )
151+ }
121152 }
122- }
123- } ) )
153+ } ) ,
154+ [ modalContext , handleCheckboxChange ]
155+ )
124156
125157 return (
126158 < div className = { twMerge ( 'bottom-to-top-modal' , className ) } >
@@ -153,7 +185,7 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
153185 onTouchStart = { handleTouchStart }
154186 onTouchMove = { handleTouchMove }
155187 onTouchEnd = { handleTouchEnd } >
156- < div className = "h-2 w-24 rounded-md bg-neutral group-hover:drop-shadow-md" />
188+ < div className = "bg-neutral h-2 w-24 rounded-md group-hover:drop-shadow-md" />
157189 </ div >
158190 { children }
159191 </ div >
@@ -162,7 +194,7 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
162194 < div
163195 ref = { contentRef }
164196 className = { twMerge (
165- 'modal-content sticky bottom -0 left -0 right -0 z-50 w-full max-w-md translate-y-full rounded-t-2xl bg-white shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.1)] transition-transform duration-300 ease-in-out peer-checked:translate-y-0' ,
197+ 'modal-content sticky right -0 bottom -0 left -0 z-50 w-full max-w-md translate-y-full rounded-t-2xl bg-white shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.1)] transition-transform duration-300 ease-in-out peer-checked:translate-y-0' ,
166198 contentClassName
167199 ) }
168200 style = { { height : modalHeight ? `${ modalHeight } px` : '300px' , maxHeight : '100%' } } >
@@ -174,7 +206,7 @@ export const ModalBottomToTop = forwardRef<unknown, ModalBottomToTopProps>(
174206 onTouchStart = { handleTouchStart }
175207 onTouchMove = { handleTouchMove }
176208 onTouchEnd = { handleTouchEnd } >
177- < div className = "h-2 w-24 rounded-md bg-neutral group-hover:drop-shadow-md" />
209+ < div className = "bg-neutral h-2 w-24 rounded-md group-hover:drop-shadow-md" />
178210 </ div >
179211 { children }
180212 </ div >
0 commit comments