Skip to content

Commit

Permalink
feat(Drawer): add keepMounted prop (#321)
Browse files Browse the repository at this point in the history
* feat(Drawer): keepMounted prop

* chore(Drawer): fix documentation and jsdoc

* chore(Drawer): update screenshots

* fix(Drawer): revert visibility hidden on transition exit done
  • Loading branch information
flops authored Oct 9, 2024
1 parent e729695 commit 760d063
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 4 deletions.
22 changes: 19 additions & 3 deletions src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ export interface DrawerItemProps {

/** The maximum width of the resizable drawer item */
maxResizeWidth?: number;

/**
* Keep child components mounted when closed, prioritized over Drawer.keepMounted property
* @default false
* */
keepMounted?: boolean;
}

export const DrawerItem = React.forwardRef<HTMLDivElement, DrawerItemProps>(
Expand All @@ -71,6 +77,7 @@ export const DrawerItem = React.forwardRef<HTMLDivElement, DrawerItemProps>(
minResizeWidth,
maxResizeWidth,
onResize,
keepMounted = false,
} = props;

const itemRef = React.useRef<HTMLDivElement>(null);
Expand All @@ -95,7 +102,8 @@ export const DrawerItem = React.forwardRef<HTMLDivElement, DrawerItemProps>(
<CSSTransition
in={visible}
timeout={TIMEOUT}
unmountOnExit
mountOnEnter={!keepMounted}
unmountOnExit={!keepMounted}
classNames={b('item-transition', {direction: cssDirection})}
nodeRef={itemRef}
>
Expand Down Expand Up @@ -144,6 +152,12 @@ export interface DrawerProps {

/** Optional flag to not use `Portal` for drawer */
disablePortal?: boolean;

/**
* Keep child components mounted when closed
* @default false
* */
keepMounted?: boolean;
}

export const Drawer: React.FC<DrawerProps> = ({
Expand All @@ -156,6 +170,7 @@ export const Drawer: React.FC<DrawerProps> = ({
preventScrollBody = true,
hideVeil,
disablePortal = true,
keepMounted = false,
}) => {
let someItemVisible = false;
React.Children.forEach(children, (child) => {
Expand Down Expand Up @@ -190,8 +205,8 @@ export const Drawer: React.FC<DrawerProps> = ({
<Transition
in={someItemVisible}
timeout={{enter: 0, exit: TIMEOUT}}
mountOnEnter
unmountOnExit
mountOnEnter={!keepMounted}
unmountOnExit={!keepMounted}
nodeRef={containerRef}
>
{(state) => {
Expand All @@ -218,6 +233,7 @@ export const Drawer: React.FC<DrawerProps> = ({
) {
const childVisible = Boolean(child.props.visible);
return React.cloneElement(child, {
keepMounted,
...child.props,
visible: childVisible && childrenVisible,
});
Expand Down
2 changes: 2 additions & 0 deletions src/components/Drawer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ The Drawer module consists of two primary components: `Drawer` and `DrawerItem`.
| onResize | Callback function called at the end of resizing. Can be used to save the new width. | `(width: number) => void` | |
| minResizeWidth | The minimum width of the resizable drawer item | `number` | |
| maxResizeWidth | The maximum width of the resizable drawer item | `number` | |
| keepMounted | Keep child components mounted when closed, prioritized over Drawer.keepMounted property | `boolean` | `false` |

### `Drawer` Props

Expand All @@ -90,6 +91,7 @@ The Drawer module consists of two primary components: `Drawer` and `DrawerItem`.
| onEscape | Optional callback function that is called when the escape key is pressed, if the drawer is open. | `() => void` | |
| hideVeil | Optional flag to hide the background darkening | `boolean` | |
| disablePortal | Optional flag to not render drawer inside `Portal` | `boolean` | `true` |
| keepMounted | Keep child components mounted when closed | `boolean` | `false` |

## CSS API

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 27 additions & 1 deletion src/components/Drawer/__stories__/DrawerShowcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export function DrawerShowcase() {
const [direction, setDirection] = React.useState<string>('left');
const [direction2, setDirection2] = React.useState<string>('left');

const [keepMountedGlobal, setKeepMountedGlobal] = React.useState<boolean>(false);
const [keepMounted1, setKeepMounted1] = React.useState<boolean>(false);

const hideAll = React.useCallback(() => {
setVisible1(false);
setVisible2(false);
Expand All @@ -41,9 +44,32 @@ export function DrawerShowcase() {
<RadioButton.Option value="left">left</RadioButton.Option>
<RadioButton.Option value="right">right</RadioButton.Option>
</RadioButton>
<br /> Keep Mounted Drawer: &nbsp;
<Button
view="action"
size="l"
onClick={() => setKeepMountedGlobal(!keepMountedGlobal)}
>
{keepMountedGlobal ? 'On' : 'Off'}
</Button>
&nbsp;&nbsp; Keep Mounted 1: &nbsp;
<Button
disabled={!keepMountedGlobal}
view="action"
size="l"
onClick={() => setKeepMounted1(!keepMounted1)}
>
{keepMounted1 ? 'On' : 'Off'}
</Button>
</div>
<Drawer className={b('drawer')} onVeilClick={hideAll} onEscape={hideAll}>
<Drawer
className={b('drawer')}
onVeilClick={hideAll}
onEscape={hideAll}
keepMounted={keepMountedGlobal}
>
<DrawerItem
keepMounted={keepMounted1}
visible={visible1}
id="item-1"
className={b('item-1')}
Expand Down

0 comments on commit 760d063

Please sign in to comment.