react-pro-sidebar

repository·master·Indexed 23 days ago

https://github.com/azouaoui-med/react-pro-sidebar

A highly customizable and responsive sidebar component for React dashboard applications. Version 2.0.0-alpha.1 requires React 18+ and introduces a fully controlled API, removing the legacy useProSidebar hook and ProSidebarProvider. It features components like Sidebar, Menu, MenuItem, and SubMenu, with support for React Router integration via the component prop and extensive styling options through rootStyles and menuItemStyles.

Tokens
19.4K
Snippets
53
Records
87
Agent score
82%

What's inside react-pro-sidebar

  1. How the Sidebar component works in v2

    master

    In v2, the Sidebar component is fully controlled. Instead of relying on an internal context provided by ProSidebarProvider, the parent component is responsible for maintaining the state of the sidebar and passing it down via props. This allows for more predictable state management and integration with other state management libraries or routing systems.

    // The Sidebar component expects controlled props in v2
    <Sidebar
      collapsed={collapsed}
      toggled={toggled}
      onBackdropClick={() => setToggled(false)}
      onBreakPoint={(broken) => setBroken(broken)}
    >
      {/* ... content ... */}
    </Sidebar>
  2. Control SubMenu open state

    master

    You can manage the SubMenu open state in two ways:

    1. Uncontrolled: Use the defaultOpen prop to set the initial state.
    2. Controlled: Use the open prop to provide the state and the onOpenChange callback to handle state updates. When using open, you must manage the state yourself (e.g., via useState).
    const [open, setOpen] = useState(false);
    
    <SubMenu label="Charts" open={open} onOpenChange={setOpen}>
      …
    </SubMenu>;
  3. Use the accordion mode in SubMenu

    master

    By setting the accordion prop to true, you ensure that only one of the SubMenu's direct child SubMenus can be open at a time.

    Note that the scope of the accordion is per-level; opening an accordion does not affect the open/closed state of its ancestors or non-direct descendants.

    <SubMenu label="Components" accordion>
      <SubMenu label="Forms">…</SubMenu>
      <SubMenu label="Layout">…</SubMenu>
      <SubMenu label="Display">…</SubMenu>
    </SubMenu>
  4. What the Menu component does

    master

    The Menu is the styled container for MenuItem and SubMenu children. It manages several core behaviors for the sidebar navigation, including:

    • Styling system: Uses menuItemStyles to apply consistent styles to children.
    • Accordion coordination: Controls whether only one top-level SubMenu can be open at a time via the accordion prop.
    • Popover mode: Determines if top-level SubMenus open as floating poppers via the popover prop.
    • Transitions: Manages the slide animation duration for inline submenus via transitionDuration.
    • Icon rendering: Provides a way to override expand icons via renderExpandIcon.

    You can nest multiple Menu components inside a single Sidebar to create distinct sections (e.g., "General" and "Extras").

    import { Sidebar, Menu, MenuItem, SubMenu } from 'react-pro-sidebar';
    
    <Sidebar>
      <Menu>
        <SubMenu label="Charts">
          <MenuItem>Pie</MenuItem>
          <MenuItem>Line</MenuItem>
        </SubMenu>
        <MenuItem>Documentation</MenuItem>
      </Menu>
    </Sidebar>;
  5. Understand the semantic structure of react-pro-sidebar

    master

    react-pro-sidebar uses standard HTML5 semantic elements to ensure screen readers correctly identify the sidebar and navigation regions:

    • Sidebar renders as an <aside> element.
    • Menu renders as a <nav> containing a <ul> (internally a <menu> element).
    • MenuItem and SubMenu render as <li> elements.
    • The interactive trigger within MenuItem or SubMenu is an <a> element (or a custom element provided via the component prop).
  6. Theme the sidebar with rootStyles and menuItemStyles

    master

    react-pro-sidebar provides two complementary styling primitives for theming:

    1. rootStyles: An Emotion CSSObject applied to each component's root element. Use this for high-level styling or to target inner nodes by combining it with the exported sidebarClasses or menuClasses registries.
    2. menuItemStyles (on Menu): A structured slot system for theming MenuItem, SubMenu, and their children.

    Available slots for menuItemStyles include:

    • root
    • button
    • label
    • icon
    • prefix
    • suffix
    • subMenuContent
    • SubMenuExpandIcon

    Each slot accepts a CSSObject or a function that receives the item's state: { level, active, disabled, isSubmenu, open }.

    import { Sidebar, Menu, MenuItem, SubMenu, menuClasses, type MenuItemStyles } from 'react-pro-sidebar';
    
    const themes = {
      light: { bg: '#ffffff', text: '#0d3b66', icon: '#0098e5', hoverBg: '#cfe7ff', hoverText: '#0d3b66' },
      dark:  { bg: '#0b2948', text: '#cbd5e1', icon: '#59d0ff', hoverBg: '#00458b', hoverText: '#fff' },
      brand: { bg: '#1b1035', text: '#e9e1ff', icon: '#c084fc', hoverBg: '#4c1d95', hoverText: '#fff' },
    };
    
    export default function ThemedSidebar({ theme = 'light' }) {
      const t = themes[theme];
    
      const menuItemStyles: MenuItemStyles = {
        button: {
          color: t.text,
          [`&.${menuClasses.active}`]: {
            color: t.hoverText,
            backgroundColor: t.hoverBg,
          },
          '&:hover': {
            backgroundColor: t.hoverBg,
            color: t.hoverText,
          },
        },
        icon: { color: t.icon },
      };
    
      return (
        <Sidebar
          backgroundColor={t.bg}
          rootStyles={{ color: t.text, border: 'none' }}
        >
          <Menu menuItemStyles={menuItemStyles}>
            <MenuItem active>Dashboard</MenuItem>
            <SubMenu label="Charts">
              <MenuItem>Pie</MenuItem>
              <MenuItem>Line</MenuItem>
            </SubMenu>
          </Menu>
        </Sidebar>
      );
    }
  7. Accessibility limitations and patterns

    master

    When using react-pro-sidebar, be aware of the following architectural choices regarding accessibility:

    • Navigation Pattern: The package follows a "list of links" navigation pattern. It does not follow the WAI-ARIA menu pattern (which requires a single roving tabindex and arrow-key navigation). If your use case requires strict menu semantics (like a context menu), you must implement your own keyboard handlers.
    • Popover Mode: In popover mode, top-level submenus are rendered as floating panels via Popper.js. These panels are not constrained to the sidebar's accessible name region; they are reached in the DOM order during landmark navigation.
    • Color Contrast: While the default theme meets WCAG AA contrast, any customizations made via menuItemStyles or rootStyles must be manually verified for contrast compliance, especially for hover, active, and disabled states.
  8. Use the SubMenu component

    master

    SubMenu is an expandable container designed to hold MenuItem and other SubMenu children. It supports nesting and automatic active state cascading.

    When the sidebar is collapsed (or when Menu's popover mode is enabled), top-level SubMenu components open as floating poppers; otherwise, they slide open inline.

    Automatic Active State (v2): In version 2, a SubMenu is automatically marked as active if any of its descendants are active. You only need to use the active prop if you want to force the active visual state explicitly.

    <Menu>
      <SubMenu label="Charts" icon={<ChartIcon />} defaultOpen>
        <MenuItem>Pie</MenuItem>
        <MenuItem>Line</MenuItem>
      </SubMenu>
    </Menu>
  9. Deploy the documentation website to Netlify

    master

    The documentation website is configured for deployment via Netlify static export. The build process requires building the core library from the repository root before building the website itself to ensure the file:.. dependency is satisfied.

    Ensure your netlify.toml at the repo root contains the following configuration:

    [build]
      base    = "website"
      command = "cd .. && yarn install --frozen-lockfile && yarn build && cd website && yarn install --frozen-lockfile && yarn build"
      publish = "website/out"