Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(react-drawer): apply position: absolute when mountNode is passed #32816

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
marcosmoura marked this conversation as resolved.
Show resolved Hide resolved
"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,24 @@ export const useOverlayDrawerStyles_unstable = (state: OverlayDrawerState): Over
const resetStyles = useDrawerResetStyles();
const rootStyles = useDrawerRootStyles();

const isRenderingInsideContainer = !!state.mountNode;
marcosmoura marked this conversation as resolved.
Show resolved Hide resolved
const backdrop = state.root.backdrop as React.HTMLAttributes<HTMLDivElement> | undefined;

state.root.className = mergeClasses(
overlayDrawerClassNames.root,
baseClassNames,
resetStyles,
rootStyles[state.position],
isRenderingInsideContainer && rootStyles.absolute,
marcosmoura marked this conversation as resolved.
Show resolved Hide resolved
state.root.className,
);

if (backdrop) {
backdrop.className = mergeClasses(overlayDrawerClassNames.backdrop, backdrop.className);
backdrop.className = mergeClasses(
overlayDrawerClassNames.backdrop,
isRenderingInsideContainer && rootStyles.absolute,
marcosmoura marked this conversation as resolved.
Show resolved Hide resolved
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: [
'An overlay drawer can be rendered within a container by setting the `mountNode` prop to the container element.',
'This is useful when the drawer needs to be rendered within a specific container and not at the root level.',
marcosmoura marked this conversation as resolved.
Show resolved Hide resolved
].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
Loading