Bluesky app fork with some witchin' additions 馃挮
at main 2.1 kB view raw
1import { 2 createContext, 3 useContext, 4 useEffect, 5 useId, 6 useMemo, 7 useRef, 8} from 'react' 9 10import {useDialogStateContext} from '#/state/dialogs' 11import { 12 type DialogContextProps, 13 type DialogControlRefProps, 14 type DialogOuterProps, 15} from '#/components/Dialog/types' 16import {IS_DEV} from '#/env' 17import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types' 18 19export const Context = createContext<DialogContextProps>({ 20 close: () => {}, 21 isNativeDialog: false, 22 nativeSnapPoint: BottomSheetSnapPoint.Hidden, 23 disableDrag: false, 24 setDisableDrag: () => {}, 25 isWithinDialog: false, 26}) 27Context.displayName = 'DialogContext' 28 29export function useDialogContext() { 30 return useContext(Context) 31} 32 33export function useDialogControl(): DialogOuterProps['control'] { 34 const id = useId() 35 const control = useRef<DialogControlRefProps>({ 36 open: () => {}, 37 close: () => {}, 38 }) 39 const {activeDialogs} = useDialogStateContext() 40 41 useEffect(() => { 42 activeDialogs.current.set(id, control) 43 return () => { 44 // eslint-disable-next-line react-hooks/exhaustive-deps 45 activeDialogs.current.delete(id) 46 } 47 }, [id, activeDialogs]) 48 49 return useMemo<DialogOuterProps['control']>( 50 () => ({ 51 id, 52 ref: control, 53 open: () => { 54 if (control.current) { 55 control.current.open() 56 } else { 57 if (IS_DEV) { 58 console.warn( 59 'Attemped to open a dialog control that was not attached to a dialog!\n' + 60 'Please ensure that the Dialog is mounted when calling open/close', 61 ) 62 } 63 } 64 }, 65 close: cb => { 66 if (control.current) { 67 control.current.close(cb) 68 } else { 69 if (IS_DEV) { 70 console.warn( 71 'Attemped to close a dialog control that was not attached to a dialog!\n' + 72 'Please ensure that the Dialog is mounted when calling open/close', 73 ) 74 } 75 } 76 }, 77 }), 78 [id, control], 79 ) 80}