Skip to content

SidePanel

Basic usage ​

tsx
import Button from '@semcore/ui/button';
import type { NSSidePanel } from '@semcore/ui/side-panel';
import SidePanel from '@semcore/ui/side-panel';
import { Text } from '@semcore/ui/typography';
import React from 'react';

const Demo = (props: NSSidePanel.Props) => {
  const [visible, setVisible] = React.useState(false);

  return (
    <React.Fragment>
      <Button onClick={() => setVisible(true)}>Show SidePanel</Button>
      <SidePanel
        visible={visible}
        onClose={() => setVisible(false)}
        aria-label='SidePanel example'
        placement={props.placement}
        closable={props.closable}
        disablePreventScroll={props.disablePreventScroll}
      >
        <SidePanel.Header>
          <SidePanel.Title mt={3}>SidePanel Title</SidePanel.Title>
        </SidePanel.Header>
        <SidePanel.Body>
          <Text size={300} tag='p'>
            SidePanel content
          </Text>
        </SidePanel.Body>
      </SidePanel>
    </React.Fragment>
  );
};

export const defaultProps: NSSidePanel.Props = {
  placement: undefined,
  closable: undefined,
  disablePreventScroll: undefined,
};

Demo.defaultProps = defaultProps;

export default Demo;
tsx
import Button from '@semcore/ui/button';
import SidePanel from '@semcore/ui/side-panel';
import type { NSSidePanel } from '@semcore/ui/side-panel';
import React from 'react';

const Demo = (props: NSSidePanel.Props) => {
  const [visible, setVisible] = React.useState(false);

  return (
    <>
      <Button onClick={() => setVisible(true)}>Show SidePanel</Button>
      <SidePanel
        visible={visible}
        onClose={() => setVisible(false)}
        aria-label='SidePanel example'
        placement={props.placement}
        closable={props.closable}
        disablePreventScroll={props.disablePreventScroll}
      >
        <SidePanel.Header h='64px'>
          <SidePanel.Back>Go to Tool Name</SidePanel.Back>
          <SidePanel.Title mt={3}>SidePanel title</SidePanel.Title>
        </SidePanel.Header>
        <SidePanel.Body>Content</SidePanel.Body>
        <SidePanel.Footer justifyContent='center' pt={2} h='80px'>
          <Button size='l' use='primary'>Got it!</Button>
          <Button size='l' ml={2}>Cancel</Button>
        </SidePanel.Footer>
      </SidePanel>
    </>
  );
};

export const defaultProps: NSSidePanel.Props = {
  placement: undefined,
  closable: undefined,
  disablePreventScroll: undefined,
};

Demo.defaultProps = defaultProps;

export default Demo;

Advanced usage ​

You can access the internal components by expanding SidePanel for SidePanel.Overlay, SidePanel.Panel or SidePanel.Close.

tsx
import Button from '@semcore/ui/button';
import type { NSSidePanel } from '@semcore/ui/side-panel';
import SidePanel from '@semcore/ui/side-panel';
import { Text } from '@semcore/ui/typography';
import React from 'react';

const Demo = (props: NSSidePanel.Props) => {
  const [visible, setVisible] = React.useState(false);

  return (
    <React.Fragment>
      <Button onClick={() => setVisible(true)}>Show SidePanel</Button>
      <SidePanel
        closable={props.closable}
        visible={visible}
        aria-label='SidePanel example'
        onClose={() => setVisible(false)}
        placement={props.placement}
        disablePreventScroll={props.disablePreventScroll}
      >
        <SidePanel.Overlay>
          <SidePanel.Panel>
            <SidePanel.Header>
              <SidePanel.Title mt={3}>Taking the Stage</SidePanel.Title>
            </SidePanel.Header>
            <SidePanel.Body>
              <Text size={300} tag='p'>
                Trends and Strategies for 2024 and Beyond
              </Text>
              <Button size='l' mt={3}>Read more</Button>
            </SidePanel.Body>
          </SidePanel.Panel>
        </SidePanel.Overlay>
      </SidePanel>
    </React.Fragment>
  );
};

export const defaultProps: NSSidePanel.Props = {
  placement: undefined,
  closable: false,
  disablePreventScroll: undefined,
};

Demo.defaultProps = defaultProps;

export default Demo;

Placement ​

The component is supplied with three positioning options.

tsx
import Button from '@semcore/ui/button';
import Select from '@semcore/ui/select';
import type { NSSidePanel } from '@semcore/ui/side-panel';
import SidePanel from '@semcore/ui/side-panel';
import { Text } from '@semcore/ui/typography';
import React from 'react';

const placements: NSSidePanel.Placement[] = ['left', 'right', 'bottom'];

const Demo = () => {
  const [visible, setVisible] = React.useState(false);
  const [placement, setPlacement] = React.useState(placements[1]);

  return (
    <React.Fragment>
      <Text size={300} tag='div' mb={2}>
        <label htmlFor='select-placement'>Placement</label>
      </Text>
      <Select
        id='select-placement'
        value={placement}
        options={arrToOptions(placements)}
        onChange={setPlacement}
        size='l'
      />
      <Button onClick={() => setVisible(true)} use='primary' theme='success' size='l' ml={3}>
        Show SidePanel
      </Button>
      <SidePanel
        visible={visible}
        onClose={() => setVisible(false)}
        placement={placement}
        aria-label={`Here is a ${placement}-placed side panel`}
      >
        <Text size={300} tag='p'>
          SidePanel content
        </Text>
      </SidePanel>
    </React.Fragment>
  );
};

function arrToOptions(arr: any) {
  return arr.map((i: any) => ({ value: i, label: i, children: i }));
}

export default Demo;

Disabling overlay ​

By default, the component is rendered with an overlay, but you can change this by not passing it.

tsx
import Button from '@semcore/ui/button';
import type { NSSidePanel } from '@semcore/ui/side-panel';
import SidePanel from '@semcore/ui/side-panel';
import { Text } from '@semcore/ui/typography';
import React from 'react';

const Demo = (props: NSSidePanel.Props) => {
  const [visible, setVisible] = React.useState(false);

  return (
    <React.Fragment>
      <Button onClick={() => setVisible(true)}>Show SidePanel</Button>
      <SidePanel
        visible={visible}
        onClose={() => setVisible(false)}
        placement={props.placement}
        closable={props.closable}
        disablePreventScroll={props.disablePreventScroll}
      >
        <SidePanel.Panel aria-label='SidePanel example' mt={20}>
          <SidePanel.Header>
            <SidePanel.Title mt={3}>SidePanel Title</SidePanel.Title>
          </SidePanel.Header>
          <SidePanel.Body>
            <Text size={300} tag='p'>
              SidePanel content
            </Text>
          </SidePanel.Body>
        </SidePanel.Panel>
      </SidePanel>
    </React.Fragment>
  );
};

export const defaultProps: NSSidePanel.Props = {
  placement: undefined,
  closable: undefined,
  disablePreventScroll: undefined,
};

Demo.defaultProps = defaultProps;

export default Demo;

Portals ​

By default, the component is rendered to the portal, at the bottom of the body. You can redefine this behavior with PortalProvider and disable it with disablePortal.

tsx
import Button from '@semcore/ui/button';
import SidePanel from '@semcore/ui/side-panel';
import { Text } from '@semcore/ui/typography';
import React from 'react';

const Demo = () => {
  const [visible, setVisible] = React.useState(false);

  return (
    <React.Fragment>
      <Button onClick={() => setVisible(true)}>Show SidePanel</Button>
      <SidePanel visible={visible} onClose={() => setVisible(false)} disablePortal>
        <SidePanel.Panel aria-label='Taking the stage' mt={20}>
          <SidePanel.Header>
            <SidePanel.Title mt={3}>SidePanel Title</SidePanel.Title>
          </SidePanel.Header>
          <SidePanel.Body>
            <Text size={300} tag='p'>
              SidePanel content
            </Text>
          </SidePanel.Body>
        </SidePanel.Panel>
      </SidePanel>
    </React.Fragment>
  );
};

export default Demo;

Iframe ​

We recommend not using this component inside an iframe. Instead, use modal window or dropdown.

Released under the MIT License.

Released under the MIT License.