componente · @solu30/ui-kit/navigation
SidebarNavGroups
Sólo la lista de ítems de la navegación lateral, sin marco, sin colapso y sin cajón móvil.
Seguir leyendo — 3 párrafos más
SidebarNavGroups — headless (chrome-less) renderer for groups/items.
Extracted from SidebarNavigation so hosts that already own their own outer shell (aside frame, collapse toggle, mobile drawer — e.g. an AdminLayout-style layout) can render ONLY the item list — same appearance="plain" styling, childGroups drill-in, badges, and roving arrow-key FOCUS across the rendered items (Enter/Space navigan; las flechas sólo mueven el foco) — without nesting a second self-contained sidebar inside their own chrome.
SidebarNavigation itself is unchanged: it uses this component internally for both its desktop and mobile-drawer bodies. Zero behavior change for existing consumers.
2 sitios de import en 1 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.
- carlosmartinpavon
La pieza, con lugar de pantalla
Cargando el espécimen…
export function SidebarNavGroupsSpecimen() {
const [activo, setActivo] = useState('blog')
const groups: SidebarNavGroup[] = [
{
label: 'Contenido',
items: [
{ id: 'blog', label: 'Blog', icon: IconClipboard, badge: 12 },
{ id: 'seo', label: 'SEO Kit', icon: IconChart },
{ id: 'comms', label: 'Comms', icon: IconInbox, badge: 3, badgePulse: true },
],
},
{
label: 'Operación',
items: [
{ id: 'agentes', label: 'Agentes', icon: IconTeam },
{ id: 'ajustes', label: 'Ajustes', icon: IconSettings },
],
},
]
return (
<Stage label="SidebarNavGroups · el sidebar del admin, dentro del marco que ya pone AdminLayout" tall wide>
<div className="flex w-full flex-wrap items-start justify-center gap-6 px-1 py-1">
<aside className="flex h-[300px] w-[230px] flex-col overflow-hidden rounded-xl border border-content/10 bg-container">
<div className="border-b border-content/10 px-3 py-2.5 text-xs font-medium text-content">
carlosmartinpavon
</div>
<div className="flex-1 overflow-y-auto p-2">
<SidebarNavGroups
groups={groups}
activeItemId={activo}
collapsed={false}
onItemClick={(item) => setActivo(item.id)}
appearance="plain"
ariaLabel="Navegación del admin, expandida"
/>
</div>
</aside>
<aside className="flex h-[300px] w-[64px] flex-col overflow-hidden rounded-xl border border-content/10 bg-container">
<div className="border-b border-content/10 px-2 py-2.5 text-center text-xs font-medium text-content">
CMP
</div>
<div className="flex-1 overflow-y-auto p-2">
<SidebarNavGroups
groups={groups}
activeItemId={activo}
collapsed
onItemClick={(item) => setActivo(item.id)}
appearance="plain"
ariaLabel="Navegación del admin, plegada"
/>
</div>
</aside>
</div>
</Stage>
)
}De specimens/navigation.tsx · SidebarNavGroupsSpecimen: el espécimen del Muestrario, no un ejemplo oficial del paquete. Muestra cómo se usa la pieza de verdad, montada contra los tipos instalados —eso es lo que vale— pero no es documentación del kit.
Cómo se usa
import { SidebarNavGroups } from '@solu30/ui-kit/navigation'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| groups | opcional | SidebarNavGroup[] | Navigation groups containing items (primary API). |
| items | opcional | SidebarNavItem[] | Flat items shorthand — automatically wrapped in a single unlabeled group. |
| activeItemId | opcional | string | ID of the currently active item (also drives childGroups auto-expand). |
| collapsed | opcional | boolean | Whether to render in collapsed (icon-only) mode. |
| onItemClick | opcional | (item: SidebarNavItem) => void | Callback when a nav item is clicked. |
| appearance | opcional | "boxed" | "plain" | Visual style variant — see {@link SidebarNavigationProps.appearance}. |
| className | opcional | string | Additional class names for the outer `<nav>` element. |
| ariaLabel | opcional | string | Accessible name for the `<nav>` landmark. Override when composing multiple instances on one page so each landmark stays uniquely named (a11y: `landmark-unique`). Defaults to `"Sidebar navigation"`. |