From bcefcd087e61971c60bf1a699653646352167ae4 Mon Sep 17 00:00:00 2001 From: Marcos Moura Date: Wed, 11 Sep 2024 09:58:53 -0300 Subject: [PATCH] fix(react-drawer): apply position: absolute when mountNode is passed (#32816) --- ...-6eaa1e97-38f8-4d08-8748-8eecd859a585.json | 7 ++ .../library/etc/react-drawer.api.md | 2 +- .../OverlayDrawer/OverlayDrawer.types.ts | 4 +- .../OverlayDrawer/useOverlayDrawer.tsx | 3 +- .../useOverlayDrawerStyles.styles.ts | 7 +- .../Drawer/OverlayInsideContainer.stories.tsx | 79 +++++++++++++++++++ .../stories/src/Drawer/index.stories.tsx | 1 + 7 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 change/@fluentui-react-drawer-6eaa1e97-38f8-4d08-8748-8eecd859a585.json create mode 100644 packages/react-components/react-drawer/stories/src/Drawer/OverlayInsideContainer.stories.tsx diff --git a/change/@fluentui-react-drawer-6eaa1e97-38f8-4d08-8748-8eecd859a585.json b/change/@fluentui-react-drawer-6eaa1e97-38f8-4d08-8748-8eecd859a585.json new file mode 100644 index 0000000000000..d448b258eac1f --- /dev/null +++ b/change/@fluentui-react-drawer-6eaa1e97-38f8-4d08-8748-8eecd859a585.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: apply position: absolute when mountNode is passed", + "packageName": "@fluentui/react-drawer", + "email": "marcosvmmoura@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-drawer/library/etc/react-drawer.api.md b/packages/react-components/react-drawer/library/etc/react-drawer.api.md index f7c01bc44050d..261a3308c320a 100644 --- a/packages/react-components/react-drawer/library/etc/react-drawer.api.md +++ b/packages/react-components/react-drawer/library/etc/react-drawer.api.md @@ -170,7 +170,7 @@ export type OverlayDrawerSlots = { }; // @public -export type OverlayDrawerState = ComponentState & Required; +export type OverlayDrawerState = ComponentState & Required & Pick; // @public export const renderDrawer_unstable: (state: DrawerState, contextValue: DrawerContextValue) => JSX.Element; diff --git a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/OverlayDrawer.types.ts b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/OverlayDrawer.types.ts index 23fad795bdb83..f774ca01cf20c 100644 --- a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/OverlayDrawer.types.ts +++ b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/OverlayDrawer.types.ts @@ -45,4 +45,6 @@ export type OverlayDrawerProps = ComponentProps & /** * State used in rendering OverlayDrawer */ -export type OverlayDrawerState = ComponentState & Required; +export type OverlayDrawerState = ComponentState & + Required & + Pick; diff --git a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawer.tsx b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawer.tsx index c236ab6de61bf..29e07857a9b6c 100644 --- a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawer.tsx +++ b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawer.tsx @@ -29,7 +29,7 @@ export const useOverlayDrawer_unstable = ( ref: React.Ref, ): OverlayDrawerState => { const { open, size, position } = useDrawerDefaultProps(props); - const { backdropMotion, modalType = 'modal', inertTrapFocus, onOpenChange, surfaceMotion } = props; + const { backdropMotion, modalType = 'modal', inertTrapFocus, onOpenChange, surfaceMotion, mountNode } = props; const backdropProps = slot.resolveShorthand(props.backdrop); const hasCustomBackdrop = modalType !== 'non-modal' && backdropProps !== null; @@ -80,6 +80,7 @@ export const useOverlayDrawer_unstable = ( open, size, position, + mountNode, motion: STATIC_MOTION, }; }; diff --git a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawerStyles.styles.ts b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawerStyles.styles.ts index aab5aeb4aeb8a..4eff0a94554c0 100644 --- a/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawerStyles.styles.ts +++ b/packages/react-components/react-drawer/library/src/components/OverlayDrawer/useOverlayDrawerStyles.styles.ts @@ -32,6 +32,9 @@ const useDrawerRootStyles = makeStyles({ height: `var(${drawerCSSVars.drawerSizeVar})`, width: '100vw', }, + absolute: { + position: 'absolute', + }, }); /** @@ -44,6 +47,7 @@ export const useOverlayDrawerStyles_unstable = (state: OverlayDrawerState): Over const resetStyles = useDrawerResetStyles(); const rootStyles = useDrawerRootStyles(); + const absoluteStyles = !!state.mountNode && rootStyles.absolute; const backdrop = state.root.backdrop as React.HTMLAttributes | undefined; state.root.className = mergeClasses( @@ -51,11 +55,12 @@ export const useOverlayDrawerStyles_unstable = (state: OverlayDrawerState): Over baseClassNames, resetStyles, rootStyles[state.position], + absoluteStyles, state.root.className, ); if (backdrop) { - backdrop.className = mergeClasses(overlayDrawerClassNames.backdrop, backdrop.className); + backdrop.className = mergeClasses(overlayDrawerClassNames.backdrop, absoluteStyles, backdrop.className); } return state; diff --git a/packages/react-components/react-drawer/stories/src/Drawer/OverlayInsideContainer.stories.tsx b/packages/react-components/react-drawer/stories/src/Drawer/OverlayInsideContainer.stories.tsx new file mode 100644 index 0000000000000..3e5c669f6cfe2 --- /dev/null +++ b/packages/react-components/react-drawer/stories/src/Drawer/OverlayInsideContainer.stories.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import { + DrawerBody, + DrawerHeader, + DrawerHeaderTitle, + OverlayDrawer, + Button, + makeStyles, + tokens, +} from '@fluentui/react-components'; +import { Dismiss24Regular } from '@fluentui/react-icons'; + +const useStyles = makeStyles({ + root: { + display: 'flex', + alignItems: 'flex-start', + gap: tokens.spacingHorizontalL, + }, + + container: { + width: '500px', + height: '300px', + padding: `${tokens.spacingVerticalL} ${tokens.spacingHorizontalL}`, + position: 'relative', + overflow: 'hidden', + border: `${tokens.strokeWidthThicker} solid ${tokens.colorNeutralStroke1}`, + backgroundColor: tokens.colorBrandBackground2, + }, +}); + +export const OverlayInsideContainer = () => { + const [isOpen, setIsOpen] = React.useState(false); + const ref = React.useRef(null); + const styles = useStyles(); + + return ( +
+
+ setIsOpen(open)}> + + } + onClick={() => setIsOpen(false)} + /> + } + > + Overlay Drawer + + + + +

Drawer content

+
+
+ +

Drawer will be rendered within this container

+
+ + +
+ ); +}; + +OverlayInsideContainer.parameters = { + docs: { + description: { + story: [ + 'The overlay Drawer can be rendered inside a specific container by setting the `mountNode` prop to the desired container element.', + 'This approach is useful when you need the Drawer to appear within a particular section of the DOM, rather than being attached to the root element.', + ].join('\n'), + }, + }, +}; diff --git a/packages/react-components/react-drawer/stories/src/Drawer/index.stories.tsx b/packages/react-components/react-drawer/stories/src/Drawer/index.stories.tsx index 4933e61c6d800..b6465bf38347d 100644 --- a/packages/react-components/react-drawer/stories/src/Drawer/index.stories.tsx +++ b/packages/react-components/react-drawer/stories/src/Drawer/index.stories.tsx @@ -13,6 +13,7 @@ import bestPracticesMd from './DrawerBestPractices.md'; export { Default } from './DrawerDefault.stories'; export { Overlay } from './OverlayDrawer.stories'; export { OverlayNoModal } from './OverlayDrawerNoModal.stories'; +export { OverlayInsideContainer } from './OverlayInsideContainer.stories'; export { Inline } from './InlineDrawer.stories'; export { Position } from './DrawerPosition.stories'; export { Size } from './DrawerSize.stories';