diff --git a/packages/@react-spectrum/overlays/package.json b/packages/@react-spectrum/overlays/package.json index f138102a408..d411e6fb39c 100644 --- a/packages/@react-spectrum/overlays/package.json +++ b/packages/@react-spectrum/overlays/package.json @@ -38,7 +38,7 @@ "@react-stately/overlays": "^3.1.1", "@react-types/overlays": "^3.4.0", "@react-types/shared": "^3.3.0", - "react-transition-group": "^2.2.0" + "react-transition-group": "^4.4.1" }, "devDependencies": { "@adobe/spectrum-css-temp": "^3.0.0-alpha.1" diff --git a/packages/@react-spectrum/overlays/src/Modal.tsx b/packages/@react-spectrum/overlays/src/Modal.tsx index 2d05c154b41..ddef4f06893 100644 --- a/packages/@react-spectrum/overlays/src/Modal.tsx +++ b/packages/@react-spectrum/overlays/src/Modal.tsx @@ -17,7 +17,7 @@ import {ModalProps} from '@react-types/overlays'; import modalStyles from '@adobe/spectrum-css-temp/components/modal/vars.css'; import {Overlay} from './Overlay'; import overrideStyles from './overlays.css'; -import React, {forwardRef, HTMLAttributes, ReactNode, RefObject} from 'react'; +import React, {forwardRef, HTMLAttributes, ReactNode, RefObject, useRef} from 'react'; import {Underlay} from './Underlay'; import {useModal, useOverlay, usePreventScroll} from '@react-aria/overlays'; @@ -35,9 +35,11 @@ function Modal(props: ModalProps, ref: DOMRef) { let domRef = useDOMRef(ref); let {styleProps} = useStyleProps(props); + let underlayRef = useRef(null); + return ( - - + + ) { - let {children, isOpen, container, onEnter, onEntering, onEntered, onExit, onExiting, onExited} = props; + let {children, isOpen, container, onEnter, onEntering, onEntered, onExit, onExiting, onExited, nodeRef} = props; let [exited, setExited] = useState(!isOpen); let handleEntered = useCallback(() => { @@ -52,7 +52,8 @@ function Overlay(props: OverlayProps, ref: DOMRef) { onExited={handleExited} onEnter={onEnter} onEntering={onEntering} - onEntered={handleEntered}> + onEntered={handleEntered} + nodeRef={nodeRef}> {children} diff --git a/packages/@react-spectrum/overlays/src/Popover.tsx b/packages/@react-spectrum/overlays/src/Popover.tsx index ac6a0e8678c..15687a13a26 100644 --- a/packages/@react-spectrum/overlays/src/Popover.tsx +++ b/packages/@react-spectrum/overlays/src/Popover.tsx @@ -52,7 +52,7 @@ function Popover(props: PopoverProps, ref: DOMRef) { let {styleProps} = useStyleProps(props); return ( - + ) { let domRef = useDOMRef(ref); let {styleProps} = useStyleProps(props); + let underlayRef = useRef(null); + return ( - - + + ) { return ( -
+
); } + +const _Underlay = React.forwardRef(Underlay); +export {_Underlay as Underlay}; diff --git a/packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx b/packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx index 8cd5f9ef1b4..0c64b6c163c 100644 --- a/packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx +++ b/packages/@react-spectrum/tooltip/src/TooltipTrigger.tsx @@ -15,6 +15,7 @@ import {Overlay} from '@react-spectrum/overlays'; import React, {ReactElement, useRef} from 'react'; import {SpectrumTooltipTriggerProps} from '@react-types/tooltip'; import {TooltipContext} from './context'; +import {unwrapDOMRef} from '@react-spectrum/utils'; import {useOverlayPosition} from '@react-aria/overlays'; import {useTooltipTrigger} from '@react-aria/tooltip'; import {useTooltipTriggerState} from '@react-stately/tooltip'; @@ -31,7 +32,22 @@ function TooltipTrigger(props: SpectrumTooltipTriggerProps) { trigger: triggerAction } = props; - let [trigger, tooltip] = React.Children.toArray(children); + let tooltipRef = useRef(); + + let [trigger, tooltip] = React.Children.toArray(children) as [ReactElement, ReactElement]; + + // this does mean that we can't have some element wrapping the Tooltip + // we'd need to do it through context if we wanted to allow for that + let tooltipWithRef = React.cloneElement(tooltip, { + ref: node => { + tooltipRef.current = node; + // @ts-ignore react forwardRef doesn't get typed quite right, so we ignore these two warnings about accessing ref + if (tooltip.ref) { + // @ts-ignore + tooltip.ref.current = node; + } + } + }); let state = useTooltipTriggerState(props); @@ -65,8 +81,8 @@ function TooltipTrigger(props: SpectrumTooltipTriggerProps) { arrowProps, ...tooltipProps }}> - - {tooltip} + + {tooltipWithRef} diff --git a/packages/@react-types/overlays/src/index.d.ts b/packages/@react-types/overlays/src/index.d.ts index e149bf73561..68c4a224687 100644 --- a/packages/@react-types/overlays/src/index.d.ts +++ b/packages/@react-types/overlays/src/index.d.ts @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {HTMLAttributes, ReactElement, ReactNode} from 'react'; +import {HTMLAttributes, MutableRefObject, ReactElement, ReactNode} from 'react'; import {StyleProps} from '@react-types/shared'; export type Placement = 'bottom' | 'bottom left' | 'bottom right' | 'bottom start' | 'bottom end' | @@ -71,10 +71,11 @@ export interface OverlayProps { onEntered?: () => void, onExit?: () => void, onExiting?: () => void, - onExited?: () => void + onExited?: () => void, + nodeRef: MutableRefObject } -export interface ModalProps extends StyleProps, OverlayProps { +export interface ModalProps extends StyleProps, Omit { children: ReactElement, isOpen?: boolean, onClose?: () => void, @@ -82,7 +83,7 @@ export interface ModalProps extends StyleProps, OverlayProps { isDismissable?: boolean } -export interface PopoverProps extends StyleProps, OverlayProps { +export interface PopoverProps extends StyleProps, Omit { children: ReactNode, placement?: PlacementAxis, arrowProps?: HTMLAttributes, @@ -93,7 +94,7 @@ export interface PopoverProps extends StyleProps, OverlayProps { isNonModal?: boolean } -export interface TrayProps extends StyleProps, OverlayProps { +export interface TrayProps extends StyleProps, Omit { children: ReactElement, isOpen?: boolean, onClose?: () => void, diff --git a/yarn.lock b/yarn.lock index 77c1d231726..09d7aff0ebe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1402,7 +1402,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.9.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@7.9.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.0.tgz#337eda67401f5b066a6f205a3113d4ac18ba495b" integrity sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA== @@ -8955,6 +8955,14 @@ dom-helpers@^3.2.1, dom-helpers@^3.3.1, dom-helpers@^3.4.0: dependencies: "@babel/runtime" "^7.1.2" +dom-helpers@^5.0.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b" + integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -19017,6 +19025,16 @@ react-transition-group@^2.2.0, react-transition-group@^2.2.1: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" +react-transition-group@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" + integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@^16.7.0, "react@^16.8.0 || ^17.0.0-rc.1": version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"