Files
headlessui/packages/@headlessui-react/src/internal/stack-context.tsx
T
Jordan Pittman f1daa1e52b Adjust outside click handling (#1667)
* Don’t close dialog if opened during mouse up event

* Don’t close dialog if drag starts inside dialog and ends outside dialog

* Handle closing of nested dialogs that are always mounted

* Fix focus trap restoration in Vue

* Update changelog
2022-07-14 14:20:04 -04:00

65 lines
1.3 KiB
TypeScript

import React, {
createContext,
useContext,
// Types
MutableRefObject,
ReactNode,
} from 'react'
import { useIsoMorphicEffect } from '../hooks/use-iso-morphic-effect'
import { useEvent } from '../hooks/use-event'
type OnUpdate = (
message: StackMessage,
type: string,
element: MutableRefObject<HTMLElement | null>
) => void
let StackContext = createContext<OnUpdate>(() => {})
StackContext.displayName = 'StackContext'
export enum StackMessage {
Add,
Remove,
}
export function useStackContext() {
return useContext(StackContext)
}
export function StackProvider({
children,
onUpdate,
type,
element,
enabled,
}: {
children: ReactNode
onUpdate?: OnUpdate
type: string
element: MutableRefObject<HTMLElement | null>
enabled?: boolean
}) {
let parentUpdate = useStackContext()
let notify = useEvent((...args: Parameters<OnUpdate>) => {
// Notify our layer
onUpdate?.(...args)
// Notify the parent
parentUpdate(...args)
})
useIsoMorphicEffect(() => {
let shouldNotify = enabled === undefined || enabled === true
shouldNotify && notify(StackMessage.Add, type, element)
return () => {
shouldNotify && notify(StackMessage.Remove, type, element)
}
}, [notify, type, element, enabled])
return <StackContext.Provider value={notify}>{children}</StackContext.Provider>
}