/*
* The MIT License (MIT)
*
* Copyright (c) 2015 - present Instructure, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from 'react'
import type { PortalNode, PortalProps } from '@instructure/ui-portal'
import type { PositionMountNode } from '@instructure/ui-position'
import type { TransitionProps, TransitionType } from '@instructure/ui-motion'
import type { DialogProps } from '@instructure/ui-dialog'
import type {
OtherHTMLAttributes,
PickPropsWithExceptions,
UIElement
} from '@instructure/shared-types'
type OverlayOwnProps = {
/**
* Whether or not the `` is open
*/
open?: boolean
/**
* The type of `` to use for animating in/out
*/
transition?: TransitionType // passed as to Transition as `type`
} & PropsForPortal &
PropsForDialog &
PropsForTransition
type PropsForPortal = {
/**
* Callback fired when `` content has been mounted in the DOM
*/
onOpen?: (DOMNode: PortalNode) => void
/**
* Callback fired when `` has been unmounted from the DOM
*/
onClose?: () => void
/**
* An element or a function returning an element to use as the mount node
* for the `` (defaults to `document.body`)
*/
mountNode?: PositionMountNode
/**
* Insert the element at the 'top' of the mountNode or at the 'bottom'
*/
insertAt?: 'bottom' | 'top'
}
type PropsForDialog = {
children?: React.ReactNode
/**
* An accessible label for the `` content
*/
label: string
/**
* An element or a function returning an element to focus by default
*/
defaultFocusElement?: UIElement
/**
* An element or a function returning an element that wraps the content of the ``
*/
contentElement?: UIElement
shouldContainFocus?: boolean
shouldReturnFocus?: boolean
shouldCloseOnDocumentClick?: boolean
shouldCloseOnEscape?: boolean
/**
* Callback fired when the `` is requesting to be closed
*/
onDismiss?: (
event: React.UIEvent | React.FocusEvent,
documentClick?: boolean
) => void
}
type PropsForTransition = {
/**
* Show the component; triggers the enter or exit animation
*/
in?: boolean
/**
* Unmount the component (remove it from the DOM) when it is not shown
*/
unmountOnExit?: boolean
/**
* Run the enter animation when the component mounts, if it is initially
* shown
*/
transitionOnMount?: boolean
/**
* Run the enter animation
*/
transitionEnter?: boolean
/**
* Run the exit animation
*/
transitionExit?: boolean
/**
* Callback fired before the "entering" classes are applied
*/
onEnter?: () => void
/**
* Callback fired after the "entering" classes are applied
*/
onEntering?: () => void
/**
* Callback fired after the "enter" classes are applied
*/
onEntered?: (type?: TransitionType) => void
/**
* Callback fired before the "exiting" classes are applied
*/
onExit?: () => void
/**
* Callback fired after the "exiting" classes are applied
*/
onExiting?: () => void
/**
* Callback fired after the "exited" classes are applied
*/
onExited?: (type?: TransitionType) => void
}
type PropKeys = keyof OverlayOwnProps
type AllowedPropKeys = Readonly>
type OverlayProps =
// pickProps can pass props to Dialog
PickPropsWithExceptions<
DialogProps,
keyof PropsForDialog | 'open' | 'elementRef'
> &
// pickProps can pass props to Portal
PickPropsWithExceptions<
PortalProps,
keyof PropsForPortal | 'open' | 'children'
> &
// pickProps can pass props to Transition
PickPropsWithExceptions<
TransitionProps,
keyof PropsForTransition | 'children' | 'type'
> &
OverlayOwnProps &
OtherHTMLAttributes
type OverlayState = {
open: boolean
transitioning: boolean
}
const allowedProps: AllowedPropKeys = [
'children',
'open',
'onOpen',
'onClose',
'mountNode',
'insertAt',
'label',
'onDismiss',
'defaultFocusElement',
'contentElement',
'shouldReturnFocus',
'shouldCloseOnDocumentClick',
'shouldCloseOnEscape',
'transition',
'in',
'unmountOnExit',
'transitionOnMount',
'transitionEnter',
'transitionExit',
'onEnter',
'onEntering',
'onEntered',
'onExit',
'onExiting',
'onExited'
]
export type { OverlayProps, OverlayState }
export { allowedProps }