npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@skbkontur/side-menu

v3.0.4

Published

#fafafa 20px, #dfdede 20px, #dfdede 40px )`

Downloads

913

Readme

SideMenu в фирменном стиле (макеты живут здесь).

Пример в песочнице

Пример типизации кастомной темы SideMenu.

import { ThemeContext, ThemeFactory } from '@skbkontur/react-ui';
import { SideMenu, SideMenuThemeIn } from '@skbkontur/side-menu';

const myTheme = ThemeFactory.create<SideMenuThemeIn>({
  sideMenuProductColor: '#64b419',
});

<ThemeContext.Provider value={myTheme}>
  <SideMenu />
</ThemeContext.Provider>;

Базовый пример использования SideMenu

import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
import { Kontur, Ofd } from '@skbkontur/logos';
import { ThemeContext, ThemeFactory, MenuItem, MenuSeparator } from '@skbkontur/react-ui';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
import { AttachLinkIcon } from '@skbkontur/icons/icons/AttachLinkIcon';

<div style={{height: '600px', position: 'relative'}}>
  <ThemeContext.Provider value={ThemeFactory.create({ sideMenuProductColor: '#64b419' })}>
    <SideMenu>
          <SideMenu.Header konturLogo={<Kontur/>} productLogo={<Ofd/>}/>
          <SideMenu.Body>
              <SideMenu.Item icon={<DocTextIcon24Regular/>} caption={'Документы к подписанию'} marker={'2'}>
                  <SideMenu.SubItem caption={'Входящие'}/>
                  <SideMenu.SubItem caption={'Исходящие'} marker={'2'}>
                      <SideMenu.SubItem caption={'Исходящие1'}/>
                      <SideMenu.SubItem caption={'Исходящие2'}/>
                  </SideMenu.SubItem>
                  <SideMenu.SubItem caption={'Внутренние'} marker/>
                  <SideMenu.SubItem caption={'Черновики'}/>
                  <SideMenu.SubItem caption={'Удаленные'}/>
                  <SideMenu.SubLink caption={'Cсылка в подменю'} href={'https://www.google.com/search?q=test'} target={'_blank'}/>
                  <SideMenu.SubItemHeader>Согласованные</SideMenu.SubItemHeader>
                  <SideMenu.SubItem caption={'Требуют обработки'}/>
                  <SideMenu.SubItem caption={'Обработанные'}/>
              </SideMenu.Item>
              <SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты'} marker/>
              <SideMenu.Item icon={<CommentRectTextIcon24Regular/>} caption={'Сообщения'} marker={'5'}>
                  <SideMenu.SubItem caption={'Входящие'} marker={'5'}/>
                  <SideMenu.SubItem caption={'Исходящие'}/>
                  <SideMenu.SubItem caption={'Внутренние'}/>
                  <SideMenu.SubItem caption={'Черновики'}/>
                  <SideMenu.SubItem caption={'Удаленные'}/>
              </SideMenu.Item>
              <SideMenu.Item icon={<LightbulbIcon24Regular/>} caption={'Справочная'}/>
            <SideMenu.Divider/>
              <SideMenu.Link href={'https://google.com'} icon={<AttachLinkIcon />} caption={'Ссылка'} target={'_blank'}/>
              <SideMenu.Item icon={<BookOpenTextIcon24Regular/>} caption={'Еще раздел'}/>
              <SideMenu.Item icon={<BookmarkIcon24Regular/>} caption={'Отчетность'}/>
          </SideMenu.Body>
          <SideMenu.Footer>
              <SideMenu.Organisations icon={<StackHDownIcon24Regular/>}>
                  <MenuItem>СКБ Контур</MenuItem>
                  <MenuItem>Сириус Базинес</MenuItem>
                  <MenuItem>Контур НТТ</MenuItem>
                  <MenuItem>Промэлектроника</MenuItem>
                  <MenuSeparator />
                  <MenuItem>Список организаций</MenuItem>
              </SideMenu.Organisations>
              <SideMenu.Item icon={<SettingsGearIcon24Regular/>} caption={'Реквизиты и настройки'}/>
              <SideMenu.Avatar
                  userName={'Ишматова Елена'}
                  avatarUrl={getKonturAvatarUrl({
                      userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
                  })}
              >
                <MenuItem href={'https://cabinet.kontur.ru'} target="_blank">
                  Личный кабинет
                </MenuItem>
                <MenuItem >Безопасность</MenuItem>
                <MenuSeparator />
                <MenuItem >Выйти</MenuItem>
              </SideMenu.Avatar>
          </SideMenu.Footer>
      </SideMenu>
  </ThemeContext.Provider>
</div>

SideMenu с меню второго уровня в отдельной колонке

import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
import { Buhgalteria, Kontur } from '@skbkontur/logos';
import { ThemeContext, ThemeFactory, MenuItem, Modal, Input, MenuSeparator } from '@skbkontur/react-ui';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';

const [opened, setOpened] = React.useState(false);

const open = () => {
  setOpened(true);
}

const close = () => {
  setOpened(false);
}

const linearLightGradient = `repeating-linear-gradient(
                                60deg,
                                #fafafa,
                                #fafafa 20px,
                                #dfdede 20px,
                                #dfdede 40px
                              )`

const renderModal = () => {
  return (
    <Modal onClose={close}>
      <Modal.Header>Выбор организации</Modal.Header>
      <Modal.Body>
        <Input/>
        <div>Список организаций</div>
      </Modal.Body>
    </Modal>
  );
}

<div style={{height: '600px', width: '100%', position: 'relative', display: 'flex'}}>
  <ThemeContext.Provider value={ThemeFactory.create({ sideMenuProductColor: '#b750d1' })}>
    <SideMenu isSeparatedMenu={true}>
      <SideMenu.Header konturLogo={<Kontur/>} productLogo={<Buhgalteria/>} withWidget={false}/>
      <SideMenu.Body>
        <SideMenu.Item icon={<DocTextIcon24Regular/>} caption={'Документы'} marker={'2'}>
          <SideMenu.SubItem caption={'Входящие'} marker={'5'}>
            <SideMenu.SubItem caption={'Входящие 1'}>
              <SideMenu.SubItem caption={'Входящие11'}>
                <SideMenu.SubItem caption={'Входящие111'}/>
                <SideMenu.SubItem caption={'Входящие112'}/>
                <SideMenu.SubItem caption={'Входящие113'}/>
              </SideMenu.SubItem>
              <SideMenu.SubItem caption={'Входящие12'}/>
              <SideMenu.SubItem caption={'Входящие13'}/>
            </SideMenu.SubItem>
            <SideMenu.SubItem caption={'Входящие2'}>
              <SideMenu.SubItem caption={'Входящие21'}>
                <SideMenu.SubItem caption={'Входящие211'}/>
                <SideMenu.SubItem caption={'Входящие212'}/>
                <SideMenu.SubItem caption={'Входящие213'}/>
              </SideMenu.SubItem>
              <SideMenu.SubItem caption={'Входящие22'}/>
              <SideMenu.SubItem caption={'Входящие23'}/>
            </SideMenu.SubItem>
            <SideMenu.SubItem caption={'Входящие3'}/>
          </SideMenu.SubItem>
          <SideMenu.SubItem caption={'Исходящие'}/>
          <SideMenu.SubItem caption={'Внутренние'}/>
          <SideMenu.SubItem caption={'Черновики'}/>
          <SideMenu.SubItem caption={'Удаленные'}/>
          <SideMenu.SubItemHeader>Согласованные</SideMenu.SubItemHeader>
          <SideMenu.SubItem caption={'Требуют обработки'}/>
          <SideMenu.SubItem caption={'Обработанные'}/>
        </SideMenu.Item>
        <SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты'}/>
        <SideMenu.Item icon={<CommentRectTextIcon24Regular/>} caption={'Сообщения'} marker={'5'}>
          <SideMenu.SubItem caption={'Входящие'} marker={'5'}/>
          <SideMenu.SubItem caption={'Исходящие'}/>
          <SideMenu.SubItem caption={'Внутренние'}/>
          <SideMenu.SubItem caption={'Черновики'}/>
          <SideMenu.SubItem caption={'Удаленные'}/>
        </SideMenu.Item>
        <SideMenu.Item icon={<LightbulbIcon24Regular/>} caption={'Справочная'}/>
        <SideMenu.Divider />
        <SideMenu.Item icon={<BookOpenTextIcon24Regular/>}  caption={'Еще раздел'}/>
        <SideMenu.Item icon={<BookmarkIcon24Regular/>} caption={'Отчетность'}/>
      </SideMenu.Body>
      <SideMenu.Footer>
        <SideMenu.Item icon={<StackHDownIcon24Regular/>} caption={'СКБ Контур'} onClick={open} isButton={true}/>
        <SideMenu.Item icon={<SettingsGearIcon24Regular/>} caption={'Реквизиты и настройки'}/>
        <SideMenu.Avatar
          userName={'Ишматова Елена'}
          avatarUrl={getKonturAvatarUrl({
            userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
          })}
        >
          <MenuItem href={'https://cabinet.kontur.ru'} target="_blank">
            Личный кабинет
          </MenuItem>
          <MenuItem >Безопасность</MenuItem>
          <MenuSeparator />
          <MenuItem >Выйти</MenuItem>
        </SideMenu.Avatar>
      </SideMenu.Footer>
    </SideMenu>
  </ThemeContext.Provider>
  <div style={{ background: linearLightGradient, width: '100%', height: '100%' }}>
    {'Content '.repeat(100)}
    {opened && renderModal()}
  </div>
</div>

SideMenu с ручным управлением.

Для управления активным пунктом меню используйте проп activeItem.

Для SideMenu.Link при отсутствии id будет использован href

import { useState } from 'react';
import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
import { Kontur, Ofd } from '@skbkontur/logos';
import { ThemeContext, ThemeFactory, MenuItem, Select, Switcher, MenuSeparator} from '@skbkontur/react-ui';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
import { AttachLinkIcon24Regular } from '@skbkontur/icons/icons/AttachLinkIcon/AttachLinkIcon24Regular';


const [activeItem, setActiveItem] = useState('122');
const [isSeparatedMenu, setIsSeparatedMenu] = useState(false)
const items = [
  "100",
  "110",
  "120",
  "121",
  "122",
  "130",
  "140",
  "150",
  "160",
  "170",
  "200",
  "300",
  "310",
  "320",
  "330",
  "340",
  "350",
  "400",
  "500",
  "600",
  "https://google.com"
];

<div style={{ height: '600px', display: 'flex', position: 'relative' }}>
  <ThemeContext.Provider value={ThemeFactory.create({ sideMenuProductColor: '#64b419' })}>
    <SideMenu activeItem={activeItem} onActiveItemChange={setActiveItem} isSeparatedMenu={isSeparatedMenu}>
      <SideMenu.Header konturLogo={<Kontur />} productLogo={<Ofd />} withWidget={false} />
      <SideMenu.Body>
        <SideMenu.Item icon={<DocTextIcon24Regular />} caption={'Документы к подписанию id=100'} marker={'2'} id={'100'}>
          <SideMenu.SubItem caption={'Входящие id=110'} id={'110'} />
          <SideMenu.SubItem caption={'Исходящие id=120'} marker={'2'} id={'120'}>
            <SideMenu.SubItem caption={'Исходящие1 id=121'} id={'121'} />
            <SideMenu.SubItem caption={'Исходящие2 id=122'} id={'122'} />
          </SideMenu.SubItem>
          <SideMenu.SubItem caption={'Внутренние id=130'} id={'130'} />
          <SideMenu.SubItem caption={'Черновики id=140'} id={'140'} />
          <SideMenu.SubItem caption={'Удаленные id=150'} id={'150'} />
          <SideMenu.SubItemHeader>Согласованные</SideMenu.SubItemHeader>
          <SideMenu.SubItem caption={'Требуют обработки id=160'} id={'160'} />
          <SideMenu.SubItem caption={'Обработанные id=170'} id={'170'} />
        </SideMenu.Item>
        <SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты id=200'} id={'200'} />
        <SideMenu.Item icon={<CommentRectTextIcon24Regular />} caption={'Сообщения id=300'} marker={'5'} id={'300'}>
          <SideMenu.SubItem caption={'Входящие id=310'} marker={'5'} id={'310'} />
          <SideMenu.SubItem caption={'Исходящие id=320'} id={'320'} />
          <SideMenu.SubItem caption={'Внутренние id=330'} id={'330'} />
          <SideMenu.SubItem caption={'Черновики id=340'} id={'340'} />
          <SideMenu.SubItem caption={'Удаленные id=350'} id={'350'} />
        </SideMenu.Item>
        <SideMenu.Item icon={<LightbulbIcon24Regular />} caption={'Справочная id=400'} id={'400'} />
        <SideMenu.Divider />
        <SideMenu.Item icon={<BookOpenTextIcon24Regular />} caption={'Еще раздел id=500'} id={'500'} />
        <SideMenu.Item icon={<BookmarkIcon24Regular />} caption={'Отчетность id=600'} id={'600'} />
        <SideMenu.Link href={'https://google.com'} icon={<AttachLinkIcon24Regular />} caption={'Ссылка'}
                       target={'_blank'} />
      </SideMenu.Body>
      <SideMenu.Footer>
        <SideMenu.Dropdown icon={<StackHDownIcon24Regular />}>
          <MenuItem>СКБ Контур</MenuItem>
          <MenuItem>Сириус Базинес</MenuItem>
          <MenuItem>Контур НТТ</MenuItem>
          <MenuItem>Промэлектроника</MenuItem>
          <MenuSeparator />
          <MenuItem>Список организаций</MenuItem>
        </SideMenu.Dropdown>
        <SideMenu.Item icon={<SettingsGearIcon24Regular />} caption={'Реквизиты и настройки'} />
        <SideMenu.Avatar
          userName={'Ишматова Елена'}
          avatarUrl={getKonturAvatarUrl({
            userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
          })}
        >
          <MenuItem href={'https://cabinet.kontur.ru'} target="_blank">
            Личный кабинет
          </MenuItem>
          <MenuItem>Безопасность</MenuItem>
          <MenuSeparator />
          <MenuItem>Выйти</MenuItem>
        </SideMenu.Avatar>
      </SideMenu.Footer>
    </SideMenu>
  </ThemeContext.Provider>
  <div style={isSeparatedMenu ? { position: 'absolute', left: '464px' } : {}}>
    <p>Active Item: {activeItem}</p>
    <Select items={items} value={activeItem} onValueChange={setActiveItem} />
    <Switcher
      caption="isSeparatedMenu: "
      items={[
        {
          label: 'True',
          value: true,
        },
        {
          label: 'False',
          value: false,
        }
      ]
      }
      value={isSeparatedMenu}
      onValueChange={setIsSeparatedMenu}
    />
  </div>
</div>

Адаптивность

Брейкпойнты можно менять через пропы:

desktopMediaQuery narrowDesktopMediaQuery tabletMediaQuery mobileMediaQuery

Либо через переменные темы:

sideMenuDesktopMediaQuery = '(min-width: 1200px)'; sideMenuNarrowDesktopMediaQuery = '(min-width: 992px)'; sideMenuTabletMediaQuery = '(min-width: 768px)'; sideMenuMobileMediaQuery = '(min-width: 0px)';

Для того чтобы пропускать брекпойнты, достаточно указать значение, равное следующему за ним брейкпойнту. Например, в следующем случае у SideMenu не будет адаптива для планшетов:

<SideMenu tabletMediaQuery={'(min-width: 768px)'} narrowDesktopMediaQuery={'(min-width: 768px)'}/>

Пример встраивания SideMenu с адаптивом (более наглядно в песочнице):

<div className="App">
  <div className="layout">
    <div className="menu">
      <SideMenu />
    </div>
    <div className="content">
      ...
    </div>
  </div>
</div>

где

  .layout {
    display: flex;
    flex-direction: column;
  }

  .layout .menu {
    height: 68px;
  }

  @media screen and (min-width: 992px) {
      .layout {
          flex-direction: row;
          height: 100vh;
      }

      .layout .menu {
          height: 100%;
      }
  }

Роутинг

Компонент SideMenu.Link можно использовать, например, вместе с react-router-dom.

Для этого можно сделать подобную обёртку:

// react-router-dom v6
import { useNavigate } from "react-router-dom";

interface SideMuneReLinkProps extends SideMenuLinkProps {
  href: string;
}

const SideMuneReLink: React.FunctionComponent<SideMuneReLinkProps> = (
  props
) => {
  const navigate = useNavigate();

  return (
    <SideMenu.Link
      {...props}
      onClick={(e) => {
        e.preventDefault();
        navigate(props.href);
      }}
    />
  );
};

Пример v6 в песочнице.


В предыдущей мажорной версии хук назывался иначе - useHistory.

// react-router-dom v5
import { useHistory } from "react-router-dom";

Пример v5 в песочнице.

В самом пакете react-router-dom v5 обработчик клика немного умнее. Например, он игнорирует клики с модификаторами, чтобы ссылка отрабатывала привычным способом.

Детали реализации можно посмотреть здесь: https://github.com/remix-run/react-router/blob/v5/packages/react-router-dom/modules/Link.js#L36

При необходимости вы можете повторить часть этой логики в своей обёртке.


Также можно использовать SideMenu.Link передав туда компонент ссылки, например обертку со ссылкой из react-router-dom:

import { Link } from 'react-router-dom';

interface SideMenuReactRouterLinkProps extends SideMenuLinkProps {
  href: string;
}

const LinkWrapper = React.forwardRef<HTMLAnchorElement, SideMenuReactRouterLinkProps>(({ href, ...rest }, ref) => (
  <Link {...rest} to={href} ref={ref} />
));

const SideMenuReactRouterLink: React.FunctionComponent<SideMenuReactRouterLinkProps> = (props) => (
  <SideMenu.Link {...props} component={LinkWrapper} />
);

Если вы используете кастомную ссылку, то убедитесь, что она прокидывает ref и остальные пропсы в корневой элемент.

Пример в песочнице

Пример кастомизации

import { Kontur, Ofd } from '@skbkontur/logos';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { ThemeContext, ThemeFactory } from '@skbkontur/react-ui';

<div style={{ height: '200px', position: 'relative' }}>
  <ThemeContext.Provider value={ThemeFactory.create({ sideMenuWidth: '300px', sideMenuIconSize: '32px', sideMenuProductColor: '#64b419' })}>
    <SideMenu>
      <SideMenu.Header konturLogo={<Kontur />} productLogo={<Ofd />} />
      <SideMenu.Body>
        <SideMenu.Item icon={<DocTextIcon24Regular />} caption={'Документы к подписанию'} marker={'2'} />
      </SideMenu.Body>
      <SideMenu.Footer>
        <SideMenu.Item icon={<SettingsGearIcon24Regular />} caption={'Реквизиты и настройки'} />
      </SideMenu.Footer>
    </SideMenu>
  </ThemeContext.Provider>
</div>

Пример с использованием пропа isOpen

import { Kontur, Ofd } from '@skbkontur/logos';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { ThemeContext, ThemeFactory, Button } from '@skbkontur/react-ui';

const [isOpen, setIsOpen] = React.useState(true);

<div style={{ height: '200px', position: 'relative', display: 'flex' }}>
  <ThemeContext.Provider
    value={ThemeFactory.create({ sideMenuWidth: '300px', sideMenuProductColor: '#64b419' })}>
    <SideMenu isOpen={isOpen} onOpen={() => console.log('onOpen')} onClose={() => console.log('onClose')}>
      <SideMenu.Header konturLogo={<Kontur />} productLogo={<Ofd />} />
      <SideMenu.Body>
        <SideMenu.Item icon={<DocTextIcon24Regular />} caption={'Документы к подписанию'} />
      </SideMenu.Body>
      <SideMenu.Footer>
        <SideMenu.Item icon={<SettingsGearIcon24Regular />} caption={'Реквизиты и настройки'} />
      </SideMenu.Footer>
    </SideMenu>
  </ThemeContext.Provider>
  <Button onClick={() => {
    setIsOpen(!isOpen)
  }}>{isOpen ? 'Закрыть меню' : 'Открыть меню'}</Button>
</div>

Пример с использованием пропа isPinned

import { Kontur, Ofd } from '@skbkontur/logos';
import { SideMenu } from '@skbkontur/side-menu';
import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
import { ThemeContext, ThemeFactory, Button } from '@skbkontur/react-ui';

const [isPinned, setIsPinned] = React.useState(localStorage.getItem('sideMenuIsPinned') === 'true');

React.useEffect(() => {
  window.addEventListener('storage', () => {
    setIsPinned(localStorage.getItem('sideMenuIsPinned') === 'true');
  });
}, []);

<div style={{ height: '200px', position: 'relative', display: 'flex' }}>
  <ThemeContext.Provider
    value={ThemeFactory.create({ sideMenuWidth: '300px', sideMenuProductColor: '#64b419' })}>
    <SideMenu isPinned={isPinned}
              onPinnedValueChange={(isPinned) => {
                localStorage.setItem('sideMenuIsPinned', String(isPinned));
              }}>
      <SideMenu.Header konturLogo={<Kontur />} productLogo={<Ofd />} />
      <SideMenu.Body>
        <SideMenu.Item icon={<DocTextIcon24Regular />} caption={'Документы к подписанию'} />
      </SideMenu.Body>
      <SideMenu.Footer>
        <SideMenu.Item icon={<SettingsGearIcon24Regular />} caption={'Реквизиты и настройки'} />
      </SideMenu.Footer>
    </SideMenu>
  </ThemeContext.Provider>
</div>

Переменные кастомизации (см. ThemeContext)

{
  sideMenuWidth: string;
  sideMenuWidthForTouchScreens: string;
  sideMenuMinimizedWidth: string;
  sideMenuMarginX: string;
  sideMenuBgColor: string;
  sideMenuBoxShadowOffsetX: string;
  sideMenuBoxShadowOffsetY: string;
  sideMenuBoxShadowBlurRadius: string;
  sideMenuBoxShadowColor: string;
  sideMenuBoxShadow: string;
  sideMenuLineHeight: string;
  sideMenuLargeLineHeight: string;
  sideMenuProductColor: string;
  sideMenuDividerBgColor: string;
  sideMenuDesktopMediaQuery: string;
  sideMenuNarrowDesktopMediaQuery: string;
  sideMenuTabletMediaQuery: string;
  sideMenuMobileMediaQuery: string;
  //#region SeparatedSubMenu
  sideMenuSeparatedSubMenuBgColor: string;
  sideMenuSeparatedSubMenuBorderRightColor: string;
  sideMenuSeparatedSubMenuPaddingY: string;
  sideMenuSeparatedSubMenuPaddingX: string;
  //#endregion
  //#region NestedMenu
  sideMenuNestedMenuPaddingLeft: string;
  //#endregion
  //#region RightBorder
  sideMenuRightBorderWidth: string;
  sideMenuRightBorderIconColor: string;
  sideMenuRightBorderHoverIconColor: string;
  // #region BackButton (for Mobiles)
  sideMenuBackButtonCaptionFontWeight: string;
  sideMenuBackButtonCaptionFontSize: string;
  sideMenuBackButtonCaptionLineHeight: string;
  sideMenuBackButtonCaptionPaddingY: string;
  sideMenuBackButtonIconPaddingLeft: string;
  sideMenuBackButtonIconPaddingRight: string;
  //#endregion
  // #region Burger (for Mobiles or Tablets)
  sideMenuBurgerMarginRight: string;
  //#endregion
}