Skip to content

Commit

Permalink
fix(react-drawer): apply position: absolute when mountNode is passed (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosmoura committed Sep 11, 2024
1 parent db57a7b commit bcefcd0
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export type OverlayDrawerSlots = {
};

// @public
export type OverlayDrawerState = ComponentState<OverlayDrawerInternalSlots> & Required<DrawerBaseState>;
export type OverlayDrawerState = ComponentState<OverlayDrawerInternalSlots> & Required<DrawerBaseState> & Pick<OverlayDrawerProps, 'mountNode'>;

// @public
export const renderDrawer_unstable: (state: DrawerState, contextValue: DrawerContextValue) => JSX.Element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ export type OverlayDrawerProps = ComponentProps<OverlayDrawerSlots> &
/**
* State used in rendering OverlayDrawer
*/
export type OverlayDrawerState = ComponentState<OverlayDrawerInternalSlots> & Required<DrawerBaseState>;
export type OverlayDrawerState = ComponentState<OverlayDrawerInternalSlots> &
Required<DrawerBaseState> &
Pick<OverlayDrawerProps, 'mountNode'>;
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const useOverlayDrawer_unstable = (
ref: React.Ref<HTMLElement>,
): 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;
Expand Down Expand Up @@ -80,6 +80,7 @@ export const useOverlayDrawer_unstable = (
open,
size,
position,
mountNode,
motion: STATIC_MOTION,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const useDrawerRootStyles = makeStyles({
height: `var(${drawerCSSVars.drawerSizeVar})`,
width: '100vw',
},
absolute: {
position: 'absolute',
},
});

/**
Expand All @@ -44,18 +47,20 @@ 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<HTMLDivElement> | undefined;

state.root.className = mergeClasses(
overlayDrawerClassNames.root,
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>(null);
const styles = useStyles();

return (
<div className={styles.root}>
<div className={styles.container} ref={ref}>
<OverlayDrawer as="aside" mountNode={ref.current} open={isOpen} onOpenChange={(_, { open }) => setIsOpen(open)}>
<DrawerHeader>
<DrawerHeaderTitle
action={
<Button
appearance="subtle"
aria-label="Close"
icon={<Dismiss24Regular />}
onClick={() => setIsOpen(false)}
/>
}
>
Overlay Drawer
</DrawerHeaderTitle>
</DrawerHeader>

<DrawerBody>
<p>Drawer content</p>
</DrawerBody>
</OverlayDrawer>

<p>Drawer will be rendered within this container</p>
</div>

<Button appearance="primary" onClick={() => setIsOpen(true)}>
Open Drawer
</Button>
</div>
);
};

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'),
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit bcefcd0

Please sign in to comment.