Sidebar
v0.4.0A dumb, styled sidebar shell — sticky, full-height, scrollable flex container. It renders an `<aside>` and applies no internal structure; the consumer is responsible for composing whatever goes inside (logo, nav, `NavItem`s, etc.).
registry/behivetech/atoms/sidebar · depends on @behivetech/get-class-name
sidebar.tsx
1import { type HTMLAttributes, type ReactNode } from "react";2import { getClassName } from "@behivetech/get-class-name";3import styles from "./sidebar.module.scss";45export interface SidebarProps extends HTMLAttributes<HTMLElement> {6 /** Additional class names to merge with the component root element */7 className?: string;8 /** Content to render inside the sidebar */9 children?: ReactNode;10}1112/**13 * Dumb, styled sidebar shell — sticky, full-height, scrollable container.14 * Composition of logo, nav, links, etc. is left entirely to the consumer.15 */16export const Sidebar = ({ className, children, ...rest }: SidebarProps) => {17 const [rootClass] = getClassName({18 className,19 rootClass: "BHT__Sidebar",20 styles,21 });2223 return (24 <aside {...rest} className={rootClass}>25 {children}26 </aside>27 );28};
sidebar.module.scss
1// Material Design 3 standard navigation drawer container. The background2// previously came from `--admin-sidebar-bg`, which only the CMS admin app3// defined.45.BHT__Sidebar {6 display: flex;7 flex-direction: column;8 position: sticky;9 top: 0;10 height: 100vh;11 overflow-y: auto;12 background: var(--md-sys-color-surface-container-low, var(--color-surface));13 color: var(--md-sys-color-on-surface-variant, var(--color-text-muted));14}
index.ts
1export { Sidebar } from "./sidebar.js";2export type { SidebarProps } from "./sidebar.js";
sidebar.composition.tsx
1import { Sidebar } from "./sidebar.js";23export const BasicSidebar = () => <Sidebar>Sidebar content</Sidebar>;
sidebar.spec.tsx
1import { render, screen } from "@testing-library/react";2import { Sidebar } from "./sidebar.js";34describe("Sidebar", () => {5 it("renders children", () => {6 render(<Sidebar>Hello</Sidebar>);7 expect(screen.getByText("Hello")).toBeTruthy();8 });910 it("applies additional className", () => {11 render(<Sidebar className="custom">Content</Sidebar>);12 expect(screen.getByText("Content").className).toContain("custom");13 });14});