f1daa1e52b
* 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
65 lines
1.3 KiB
TypeScript
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>
|
|
}
|