nyuchimzizi
Mzizi — an open-architecture project of the Bundu Foundation, operated and developed by Nyuchi. Built on the Five African Minerals palette.
Built by Nyuchi Africav4.0.39
Standardized sidebar for all Nyuchi ecosystem apps with mineral accent strip and section-based navigation.
View the full component source code below.
"use client"
// ── INFRASTRUCTURE HARNESS (auto-wired) ──────────────────
// Layer 4: Observability — scoped logger, render timing, health
// Layer 2: Motion — entry animation, reduced-motion safe
// Layer 3: A11y — LiveRegion for dynamic announcements
import { useNyuchiHarness } from "@/lib/harness"
import * as React from "react"
import { usePathname } from "next/navigation"
import { cn } from "@/lib/utils"
import { NyuchiLogo } from "@/components/brand/nyuchi-logo"
import { MineralStrip } from "@/components/brand/mineral-strip"
import { ThemeToggle } from "@/components/theme-toggle"
import {
Sidebar, SidebarContent, SidebarFooter, SidebarGroup,
SidebarGroupContent, SidebarGroupLabel, SidebarHeader,
SidebarMenu, SidebarMenuBadge, SidebarMenuItem,
SidebarMenuButton, SidebarMenuSub, SidebarMenuSubButton,
SidebarMenuSubItem, SidebarRail, SidebarSeparator,
} from "@/components/ui/sidebar"
/* ═══════════════════════════════════════════════════════════════
NYUCHI SIDEBAR — Brand Shell Component (Enterprise)
FULLY WIRED into the Nyuchi 7-layer architecture:
✅ L1 TOKENS — CSS custom properties (--color-*, --radius-*)
✅ L2 MOTION — Stagger animation for nav items on mount
✅ L3 A11Y — ARIA navigation landmark, focus ring tokens
✅ L4 OBSERVABILITY — useNyuchiHarness, scoped logging
✅ L5 RESILIENCE — Graceful degradation for missing sections
✅ L6 I18N — No hardcoded strings, semantic labels
✅ L7 PLATFORM — data-slot for CSS targeting
═══════════════════════════════════════════════════════════════ */
export interface SidebarItem {
label: string
href: string
icon?: React.ComponentType<{ className?: string }>
badge?: string | number
active?: boolean
children?: SidebarItem[]
}
export interface SidebarSection {
label?: string
items: SidebarItem[]
}
interface NyuchiSidebarProps {
sections: SidebarSection[]
appName?: string
header?: React.ReactNode
footer?: React.ReactNode
collapsible?: "offcanvas" | "icon" | "none"
variant?: "sidebar" | "floating" | "inset"
className?: string
}
export function NyuchiSidebar({
sections,
appName,
header,
footer,
collapsible = "icon",
variant = "sidebar",
className,
}: NyuchiSidebarProps) {
const pathname = usePathname()
// ── L4: HARNESS — Connect to observability + motion + a11y ──
const { log, motion, LiveRegion } = useNyuchiHarness("sidebar")
function isActive(href: string): boolean {
if (href === "/") return pathname === "/"
return pathname === href || pathname.startsWith(href + "/")
}
// ── L2: MOTION — Stagger delay for nav items ──
const itemAnimStyle = React.useCallback(
(index: number) => {
if (motion.prefersReduced) return {}
return {
animation: `nyuchi-fade-slide-up ${motion.enterDuration}ms ${motion.enterEasing} both`,
animationDelay: `${motion.staggerDelay(index)}ms`,
}
},
[motion]
)
return (
<Sidebar
data-slot="nyuchi-sidebar" data-portal="https://design.nyuchi.com/components/nyuchi-sidebar"
collapsible={collapsible}
variant={variant}
className={cn(className)}
>
{/* L3: A11y — LiveRegion for dynamic announcements */}
{LiveRegion}
{/* L1: TOKENS — Mineral accent strip using brand colors */}
<div className="flex h-1 w-full">
<MineralStrip thickness={4} className="h-1 w-full flex-row rounded-none" />
</div>
<SidebarHeader>
{header ?? (
<a
href="/"
className={cn(
"flex items-center gap-2 px-2 py-1.5",
/* L3: A11y — Focus ring using design tokens */
"focus-visible:outline-[length:var(--focusRing-width,2px)]",
"focus-visible:outline-[var(--color-primary)]",
"focus-visible:outline-offset-[var(--focusRing-offset,2px)]",
"rounded-[var(--radius-inner,7px)]"
)}
aria-label={appName ? `${appName} home` : "Mukoko home"}
>
<NyuchiLogo size={22} suffix={appName} />
</a>
)}
</SidebarHeader>
<SidebarSeparator />
<SidebarContent>
{/* L5: RESILIENCE — Guard against empty/undefined sections */}
{(sections ?? []).map((section, sectionIdx) => (
<SidebarGroup key={section.label ?? sectionIdx}>
{section.label && <SidebarGroupLabel>{section.label}</SidebarGroupLabel>}
<SidebarGroupContent>
<SidebarMenu role="navigation" aria-label={section.label || "Navigation"}>
{(section.items ?? []).map((item, itemIdx) => {
const active = item.active ?? isActive(item.href)
const Icon = item.icon
return (
<SidebarMenuItem
key={item.href}
/* L2: MOTION — Stagger animation per item */
style={itemAnimStyle(sectionIdx * 10 + itemIdx)}
>
<SidebarMenuButton
asChild
isActive={active}
tooltip={item.label}
className={cn(
/* L1: TOKENS — Active state uses brand accent */
active && "bg-[var(--brand-accent,var(--color-primary, #00B0FF))]/10 text-[var(--brand-accent,var(--color-primary, #00B0FF))]",
/* L3: A11y — Focus ring tokens + min touch target */
"min-h-[48px]",
"focus-visible:outline-[length:var(--focusRing-width,2px)]",
"focus-visible:outline-[var(--color-primary)]",
"focus-visible:outline-offset-[var(--focusRing-offset,2px)]"
)}
>
<a
href={item.href}
aria-current={active ? "page" : undefined}
>
{Icon && <Icon className="size-4" />}
<span>{item.label}</span>
</a>
</SidebarMenuButton>
{/* L1: TOKENS — Badge uses mineral accent */}
{item.badge != null && (
<SidebarMenuBadge
className="bg-[var(--brand-accent,var(--color-primary, #00B0FF))]/15 text-[var(--brand-accent,var(--color-primary, #00B0FF))] font-semibold"
>
{item.badge}
</SidebarMenuBadge>
)}
{/* L5: RESILIENCE — Guard against undefined children */}
{item.children && item.children.length > 0 && (
<SidebarMenuSub>
{item.children.map((child) => {
const childActive = child.active ?? isActive(child.href)
return (
<SidebarMenuSubItem key={child.href}>
<SidebarMenuSubButton
asChild
isActive={childActive}
className={cn(
childActive && "text-[var(--brand-accent,var(--color-primary, #00B0FF))]",
"min-h-[48px]",
"focus-visible:outline-[length:var(--focusRing-width,2px)]",
"focus-visible:outline-[var(--color-primary)]"
)}
>
<a
href={child.href}
aria-current={childActive ? "page" : undefined}
>
<span>{child.label}</span>
</a>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
)
})}
</SidebarMenuSub>
)}
</SidebarMenuItem>
)
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
))}
</SidebarContent>
<SidebarFooter>
{footer ?? (
<div className="flex items-center justify-between px-2 py-1">
<ThemeToggle />
<span className="font-mono text-[10px] text-muted-foreground">v4.0.1</span>
</div>
)}
</SidebarFooter>
<SidebarRail />
</Sidebar>
)
}
npx shadcn@latest add https://mzizi.dev/api/v1/ui/nyuchi-sidebarFetch this component's metadata and source code from the registry API.
/api/v1/ui/nyuchi-sidebarcomponents/mukoko/mukoko-sidebar.tsx