A 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.).

pnpm add @behivetech/atoms.sidebar

This is the snapshot of v0.4.5, the current version, as recorded on 2026-11-10. The live page runs its examples →

registry/behivetech/atoms/sidebar at v0.4.5, snapshotted 2026-11-10

sidebar.tsx
1import { type HTMLAttributes, type ReactNode } from "react";
2import { getClassName } from "@behivetech/get-class-name";
3import styles from "./sidebar.module.scss";
4
5export 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}
11
12/**
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 });
22
23 return (
24 <aside {...rest} className={rootClass}>
25 {children}
26 </aside>
27 );
28};
sidebar.module.scss
1// Material Design 3 standard navigation drawer container. The background
2// previously came from `--admin-sidebar-bg`, which only the CMS admin app
3// defined.
4
5.BHT__Sidebar {
6 display: flex;
7 flex-direction: column;
8 position: sticky;
9 top: 0;
10 // 100vh is the tallest the viewport gets on iOS Safari (toolbars retracted), so it
11 // runs past the visible area; dvh follows the toolbars where it is supported.
12 height: 100vh;
13 height: 100dvh;
14 overflow-y: auto;
15 background: var(--md-sys-color-surface-container-low, var(--color-surface));
16 color: var(--md-sys-color-on-surface-variant, var(--color-text-muted));
17}
index.ts
1export { Sidebar } from "./sidebar.js";
2export type { SidebarProps } from "./sidebar.js";
sidebar.example.tsx
1import { Sidebar } from "./sidebar.js";
2
3export const BasicSidebar = () => <Sidebar>Sidebar content</Sidebar>;