3.0.0 • Published 7 months ago

@leafygreen-ui/drawer v3.0.0

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
7 months ago

Drawer

npm (scoped)

View on MongoDB.design

Installation

PNPM

pnpm add @leafygreen-ui/drawer

Yarn

yarn add @leafygreen-ui/drawer

NPM

npm install @leafygreen-ui/drawer

Example

Single Overlay Drawer

import React, { useState } from 'react';

import Button from '@leafygreen-ui/button';
import {
  DisplayMode,
  Drawer,
  DrawerStackProvider,
} from '@leafygreen-ui/drawer';

function ExampleComponent() {
  const [open, setOpen] = useState(false);

  return (
    <DrawerStackProvider>
      <Button onClick={() => setOpen(prevOpen => !prevOpen)}>
        Open Drawer
      </Button>
      <Drawer
        displayMode={DisplayMode.Overlay}
        onClose={() => setOpen(false)}
        open={open}
        title="Drawer Title"
      >
        content
      </Drawer>
    </DrawerStackProvider>
  );
}

Multiple Overlay Drawers

import React, { useState } from 'react';

import Button from '@leafygreen-ui/button';
import {
  DisplayMode,
  Drawer,
  DrawerStackProvider,
} from '@leafygreen-ui/drawer';

function ExampleComponent() {
  const [openA, setOpenA] = useState(false);
  const [openB, setOpenB] = useState(false);

  return (
    <DrawerStackProvider>
      <Button onClick={() => setOpenA(prevOpen => !prevOpen)}>
        Open Drawer A
      </Button>
      <Button onClick={() => setOpenB(prevOpen => !prevOpen)}>
        Open Drawer B
      </Button>
      <Drawer
        displayMode={DisplayMode.Overlay}
        onClose={() => setOpenA(false)}
        open={openA}
        title="Drawer Title A"
      >
        Drawer Content A
      </Drawer>
      <Drawer
        displayMode={DisplayMode.Overlay}
        onClose={() => setOpenB(false)}
        open={openA}
        title="Drawer Title B"
      >
        Drawer Content B
      </Drawer>
    </DrawerStackProvider>
  );
}

Embedded Drawer

import React, { useState } from 'react';

import Button from '@leafygreen-ui/button';
import {
  DisplayMode,
  Drawer,
  DrawerStackProvider,
  EmbeddedDrawerLayout,
} from '@leafygreen-ui/drawer';

function ExampleComponent() {
  const [open, setOpen] = useState(false);

  return (
    <DrawerStackProvider>
      <EmbeddedDrawerLayout isDrawerOpen={open}>
        <main>
          <Button onClick={() => setOpen(prevOpen => !prevOpen)}>
            Open Drawer
          </Button>
        </main>
        <Drawer
          displayMode={DisplayMode.Embedded}
          onClose={() => setOpen(false)}
          open={open}
          title="Drawer Title"
        >
          Drawer content
        </Drawer>
      </EmbeddedDrawerLayout>
    </DrawerStackProvider>
  );
}

Properties

Drawer

PropTypeDescriptionDefault
children (optional)React.ReactNodeChildren that will be rendered inside the Drawer
displayMode (optional)'embedded' | 'overlay'Options to control how the drawer element is displayed * 'embedded' will display a drawer as a <div> element that takes up the full parent container height and on the same elevation as main page content. It is recommended to wrap an embedded drawer within the EmbeddedDrawerLayout container * 'overlay' will display a drawer as a <dialog> element that takes up the full viewport height and elevated above main page content'overlay'
onClose (optional)React.MouseEventHandler<HTMLButtonElement>Event handler called on close button click. If provided, a close button will be rendered in the Drawer header
open (optional)booleanDetermines if the Drawer is open or closedfalse
titleReact.ReactNodeTitle of the Drawer

EmbeddedDrawerLayout

PropTypeDescriptionDefault
isDrawerOpenbooleanDetermines if the Drawer instance is open or closed

Test Harnesses

getTestUtils()

getTestUtils() is a util that allows consumers to reliably interact with LG Drawer in a product test suite. If the Drawer component cannot be found, an error will be thrown.

Usage

import { Drawer, getTestUtils } from '@leafygreen-ui/drawer';

const utils = getTestUtils(lgId?: string); // lgId refers to the custom `data-lgid` attribute passed to `Drawer`. It defaults to 'lg-drawer' if left empty.

Single Drawer

import { render } from '@testing-library/react';
import { Drawer, DrawerStackProvider, getTestUtils } from '@leafygreen-ui/drawer';

...

test('drawer', () => {
  render(
    <DrawerStackProvider>
      <Drawer open={open} onClose={() => setOpen(false)} title="Drawer Title">
        Drawer content goes here.
      </Drawer>
    </DrawerStackProvider>
  );
  const { getCloseButtonUtils, getDrawer, isOpen } = getTestUtils();

  expect(getDrawer()).toBeInTheDocument();
  expect(getCloseButtonUtils().getButton()).toBeInTheDocument();
  expect(isOpen()).toBeTruthy();
});

Multiple Drawer instances

When testing multiple Drawer instances it is recommended to add the custom data-lgid attribute to each Drawer.

import { render } from '@testing-library/react';
import { Drawer, DrawerStackProvider, getTestUtils } from '@leafygreen-ui/drawer';

...

test('Drawer', () => {
  render(
    <DrawerStackProvider>
      <Drawer data-lgid="lg-drawer-A" open={false} title="Drawer Title A">
        Drawer A content goes here.
      </Drawer>
      <Drawer data-lgid="lg-drawer-B" open={true} title="Drawer Title B">
        Drawer B content goes here.
      </Drawer>
    </DrawerStackProvider>,
  );

  const utilsA = getTestUtils('lg-drawer-A');
  const utilsB = getTestUtils('lg-drawer-B');

  // Drawer A
  expect(utilsA.getDrawer()).toBeInTheDocument();
  expect(utilsA.isOpen()).toBeFalsy();

  // Drawer B
  expect(utilsB.getDrawer()).toBeInTheDocument();
  expect(utilsB.isOpen()).toBeTruthy();
});

Test Utils

const { findDrawer, getCloseButtonUtils, getDrawer, isOpen, queryDrawer } =
  getTestUtils();
UtilDescriptionReturns
findDrawerReturns a promise that resolves to the drawer element. The promise is rejected if no elements match or if more than one match is found.Promise<HTMLDialogElement> | Promise<HTMLDivElement>
getCloseButtonUtilsReturns the button test utils for the close buttonButton test utils return type
getDrawerReturns the drawer element and throws if no elements match or if more than one match is found.HTMLDivElement
isOpenChecks the aria-hidden attribute and that the drawer element is visible based on CSS properties for display, opacity, transform, and visibilityboolean
queryDrawerReturns the drawer element or null if no elements match and throws if more than one match is found.HTMLDivElement