From e3d6a872ead53cce8c5684b4648cd1c57598da95 Mon Sep 17 00:00:00 2001 From: Oleksandr Fediashov Date: Tue, 6 Aug 2024 10:28:02 +0200 Subject: [PATCH] fix(Dialog): do not require ref forwarding (#32095) --- ...-d29eacce-56a3-4174-8f78-b577f330c2d0.json | 7 +++++++ .../src/components/Dialog/renderDialog.tsx | 9 ++++++--- .../DialogSurface/useDialogSurface.ts | 5 ++++- .../src/components/MotionRefForwarder.tsx | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 change/@fluentui-react-dialog-d29eacce-56a3-4174-8f78-b577f330c2d0.json create mode 100644 packages/react-components/react-dialog/library/src/components/MotionRefForwarder.tsx diff --git a/change/@fluentui-react-dialog-d29eacce-56a3-4174-8f78-b577f330c2d0.json b/change/@fluentui-react-dialog-d29eacce-56a3-4174-8f78-b577f330c2d0.json new file mode 100644 index 0000000000000..6b248ac6b6f81 --- /dev/null +++ b/change/@fluentui-react-dialog-d29eacce-56a3-4174-8f78-b577f330c2d0.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: do not require ref forwarding", + "packageName": "@fluentui/react-dialog", + "email": "olfedias@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-dialog/library/src/components/Dialog/renderDialog.tsx b/packages/react-components/react-dialog/library/src/components/Dialog/renderDialog.tsx index 8a32a24e3a172..eb4d97e93f337 100644 --- a/packages/react-components/react-dialog/library/src/components/Dialog/renderDialog.tsx +++ b/packages/react-components/react-dialog/library/src/components/Dialog/renderDialog.tsx @@ -4,6 +4,7 @@ import { assertSlots } from '@fluentui/react-utilities'; import * as React from 'react'; +import { MotionRefForwarder } from '../MotionRefForwarder'; import { DialogProvider, DialogSurfaceProvider } from '../../contexts'; import type { DialogState, DialogContextValues, DialogSlots } from './Dialog.types'; @@ -19,9 +20,11 @@ export const renderDialog_unstable = (state: DialogState, contextValues: DialogC {state.trigger} {state.content && ( - {/* Casting here as content should be equivalent to */} - {/* FIXME: content should not be ReactNode it should be ReactElement instead. */} - {state.content as React.ReactElement} + + {/* Casting here as content should be equivalent to */} + {/* FIXME: content should not be ReactNode it should be ReactElement instead. */} + {state.content as React.ReactElement} + )} diff --git a/packages/react-components/react-dialog/library/src/components/DialogSurface/useDialogSurface.ts b/packages/react-components/react-dialog/library/src/components/DialogSurface/useDialogSurface.ts index 3df0b4a5c00e8..51a6f5c59c7bc 100644 --- a/packages/react-components/react-dialog/library/src/components/DialogSurface/useDialogSurface.ts +++ b/packages/react-components/react-dialog/library/src/components/DialogSurface/useDialogSurface.ts @@ -13,6 +13,7 @@ import * as React from 'react'; import { useDialogContext_unstable } from '../../contexts'; import { useDisableBodyScroll } from '../../utils/useDisableBodyScroll'; import { DialogBackdropMotion } from '../DialogBackdropMotion'; +import { useMotionForwardedRef } from '../MotionRefForwarder'; import type { DialogSurfaceElement, DialogSurfaceProps, DialogSurfaceState } from './DialogSurface.types'; /** @@ -28,6 +29,8 @@ export const useDialogSurface_unstable = ( props: DialogSurfaceProps, ref: React.Ref, ): DialogSurfaceState => { + const contextRef = useMotionForwardedRef(); + const modalType = useDialogContext_unstable(ctx => ctx.modalType); const isNestedDialog = useDialogContext_unstable(ctx => ctx.isNestedDialog); @@ -116,7 +119,7 @@ export const useDialogSurface_unstable = ( // FIXME: // `DialogSurfaceElement` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement` // but since it would be a breaking change to fix it, we are casting ref to it's proper type - ref: useMergedRefs(ref, dialogRef) as React.Ref, + ref: useMergedRefs(ref, contextRef, dialogRef) as React.Ref, }), { elementType: 'div' }, ), diff --git a/packages/react-components/react-dialog/library/src/components/MotionRefForwarder.tsx b/packages/react-components/react-dialog/library/src/components/MotionRefForwarder.tsx new file mode 100644 index 0000000000000..0f20ddc705380 --- /dev/null +++ b/packages/react-components/react-dialog/library/src/components/MotionRefForwarder.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; + +const MotionRefForwarderContext = React.createContext | undefined>(undefined); + +/** + * @internal + */ +export function useMotionForwardedRef() { + return React.useContext(MotionRefForwarderContext); +} + +/** + * A component that forwards a ref to its children via a React context. + * + * @internal + */ +export const MotionRefForwarder = React.forwardRef((props, ref) => { + return {props.children}; +});