diff --git a/packages/@react-aria/utils/src/index.ts b/packages/@react-aria/utils/src/index.ts index 1d72775097a..40c1c8047e2 100644 --- a/packages/@react-aria/utils/src/index.ts +++ b/packages/@react-aria/utils/src/index.ts @@ -79,7 +79,12 @@ export { useLoadMoreSentinel as UNSTABLE_useLoadMoreSentinel } from 'react-aria/private/utils/useLoadMoreSentinel'; export {inertValue} from 'react-aria/private/utils/inertValue'; -export {isCtrlKeyPressed, willOpenKeyboard} from 'react-aria/private/utils/keyboard'; +export { + isCtrlKeyPressed, + isKeyboardOpen, + isKeyboardVisible, + willOpenKeyboard +} from 'react-aria/private/utils/keyboard'; export {useEnterAnimation, useExitAnimation} from 'react-aria/private/utils/animation'; export {isFocusable, isTabbable} from 'react-aria/private/utils/isFocusable'; export {getNonce} from 'react-aria/private/utils/getNonce'; diff --git a/packages/@react-spectrum/s2/src/Modal.tsx b/packages/@react-spectrum/s2/src/Modal.tsx index 73f83f1d088..4f1250fd56a 100644 --- a/packages/@react-spectrum/s2/src/Modal.tsx +++ b/packages/@react-spectrum/s2/src/Modal.tsx @@ -40,6 +40,8 @@ const modalOverlayStyles = style({ isolation: 'isolate', backgroundColor: 'transparent-black-500', opacity: { + default: 0, + isOpen: 1, isEntering: 0, isExiting: 0 }, @@ -148,6 +150,8 @@ export const Modal = forwardRef(function Modal(props: ModalProps, ref: DOMRef = T extends SyntheticEvent ? E : EventTarget; + +// Type helper to extract the event map from a target +export type EventMapType = T extends Window + ? WindowEventMap + : T extends Document + ? DocumentEventMap + : T extends Element + ? HTMLElementEventMap + : T extends VisualViewport + ? VisualViewportEventMap + : GlobalEventHandlersEventMap; + // Event bubbling can be problematic in real-world applications, so the default for React Spectrum components // is not to propagate. This can be overridden by calling continuePropagation() on the event. export type BaseEvent = T & { diff --git a/packages/dev/docs/pages/react-aria/getting-started.mdx b/packages/dev/docs/pages/react-aria/getting-started.mdx index e7a3eb88af8..f94e5fba948 100644 --- a/packages/dev/docs/pages/react-aria/getting-started.mdx +++ b/packages/dev/docs/pages/react-aria/getting-started.mdx @@ -193,6 +193,10 @@ This is a quick way to get started, but you can also create your own custom clas --origin: translateY(-8px); } + &:not([data-open]) { + opacity: 0; + } + &[data-entering] { animation: slide 200ms; } diff --git a/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx b/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx index c1fdf6b6a87..c3b9a2248a0 100644 --- a/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx +++ b/packages/dev/docs/pages/react-aria/home/ExampleApp.tsx @@ -787,7 +787,7 @@ function PlantModal(props: ModalOverlayProps) { ${isEntering ? 'animate-in fade-in duration-200 ease-out' : ''} ${isExiting ? 'animate-out fade-out duration-200 ease-in' : ''} `}> - {({isEntering, isExiting}) => ( + {({isEntering, isExiting, isOpen}) => ( <> {/* Inner position: sticky div sized to the visual viewport height so the modal appears in view. @@ -799,6 +799,7 @@ function PlantModal(props: ModalOverlayProps) {