componente · @solu30/ui-kit/navigation
SidebarUserMenu
Menú de usuario para el pie de la barra lateral, con avatar, ítems propios y cierre de sesión.
Seguir leyendo — 2 párrafos más
SidebarUserMenu — cross-vertical standard user menu for sidebar footers.
ADR-087: new public export — additive, no breaking changes.
4 sitios de import en 4 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.
- dietaly
- gestorsalon
- luigi
- zentrya
La pieza, con lugar de pantalla
Cargando el espécimen…
export function SidebarUserMenuSpecimen() {
const [lang, setLang] = useState('es')
return (
<Stage label="SidebarUserMenu · expandido con los dos slots (GestorSalón) y colapsado al avatar (Luigi)" tall wide>
<div className="flex w-full flex-wrap items-start justify-center gap-8 px-1 py-1">
<div className="flex flex-col gap-1.5">
<span className="text-[10px] uppercase tracking-wide text-content/50">
expandido · themeToggle variant="menu" + languageSwitcher menuRow
</span>
<div className="w-[260px] rounded-xl border border-content/10 bg-container p-2">
<SidebarUserMenu
user={{ name: 'Milagros Ruiz', email: 'milagros@salonlasacacias.com.ar' }}
items={[
{
id: 'credits',
label: '3.480 de 5.000 créditos',
icon: <IconSparkles className="h-4 w-4" />,
},
{ id: 'account', label: 'Mi cuenta', icon: <IconUser className="h-4 w-4" /> },
]}
onLogout={() => {}}
logoutLabel="Cerrar sesión"
collapsed={false}
themeToggle={<ThemeToggle variant="menu" />}
languageSwitcher={
<LanguageSwitcher
menuRow
languages={[
{ code: 'es', name: 'Español', shortName: 'ES', flag: '🇦🇷' },
{ code: 'en', name: 'English', shortName: 'EN', flag: '🇺🇸' },
]}
currentLanguage={lang}
onLanguageChange={setLang}
/>
}
/>
</div>
</div>
<div className="flex flex-col gap-1.5">
<span className="text-[10px] uppercase tracking-wide text-content/50">
colapsado · el rail de 64px — themeToggle variant="full"
</span>
<div className="w-[64px] rounded-xl border border-content/10 bg-container p-2">
<SidebarUserMenu
user={{ name: 'Rocío Peralta', email: 'rocio@luigi.com.ar' }}
items={[
{ id: 'perfil', icon: <IconUser className="h-4 w-4" />, label: 'Perfil' },
{ id: 'seguridad', icon: <IconShield className="h-4 w-4" />, label: 'Seguridad' },
]}
onLogout={() => {}}
collapsed
themeToggle={<ThemeToggle variant="full" />}
/>
</div>
</div>
</div>
</Stage>
)
}De specimens/navigation.tsx · SidebarUserMenuSpecimen: 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 { SidebarUserMenu } from '@solu30/ui-kit/navigation'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| user | sí | SidebarUserMenuUser | Authenticated user data |
| items | opcional | SidebarUserMenuItem[] | Custom action items shown above the separator before logout. Omit or pass empty array for logout-only mode (Dietaly v1). |
| onLogout | sí | () => void | Callback for the logout action |
| logoutLabel | opcional | string | Label for the logout button. Defaults to "Cerrar sesión". |
| themeToggle | opcional | ReactNode | Optional theme-toggle slot. Pass a ReactNode to render it. Omit or pass false for verticals without dark-mode support (e.g. Dietaly v1). |
| languageSwitcher | opcional | ReactNode | Optional language-switcher slot. Pass a ReactNode to render it. Omit or pass false for verticals without i18n (e.g. Dietaly v1). |
| onNavigate | opcional | (item: SidebarUserMenuItem) => void | Optional navigation callback for href items (SPA routing). When omitted, href items render as plain <a> tags. |
| collapsed | opcional | boolean | Override collapsed state. When omitted, reads from NavigationProvider. Useful for rendering outside AdminLayout or in tests. |
| showChevron | opcional | boolean | Show a chevron affordance on the trigger indicating it opens a panel. Rotates 180° when open. Never shown in collapsed (avatar-only) mode. Defaults to `true` — the chevron is a universal affordance improvement. |
Ejemplo del paquete
// Dietaly v1 — avatar + name → Cerrar sesión only
<SidebarUserMenu
user={{ name: user.name, email: user.email ?? undefined }}
onLogout={logout}
/>
// Full vertical — custom items + extras
<SidebarUserMenu
user={{ name: user.name, email: user.email, avatar: user.avatarUrl }}
items={[{ id: "profile", icon: <UserIcon />, label: "Mi perfil", href: "/profile" }]}
onLogout={logout}
// variant="menu" / menuRow align these rows to the same left indent as
// items/logout (px-2.5 py-2) — see ADR-087 addendum.
themeToggle={<ThemeToggle variant="menu" />}
languageSwitcher={<LanguageSwitcher menuRow {...langProps} />}
/>Del @example del JSDoc de @solu30/ui-kit, sin editar: son 65 de los 541 símbolos. La sangría y los renglones en blanco son los del paquete.