Menu

2.0.3

Es el patrón de navegación principal del panel de administración. Organiza sus accesos en un menú lateral fijo en Desktop, colapsable cuando el merchant busca más superficie de pantalla, y como drawer en Mobile.

  • Representar el menú de navegación principal del panel de administración: agrupar los accesos a sus distintas secciones (Inicio, Estadísticas, Ventas, Productos…) en un menú lateral persistente, integrado en App Shell y visible por defecto en todas las páginas. Es el uso principal del patrón: aunque el Menu puede reutilizarse en otras navegaciones, está documentado ante todo desde este enfoque.
  • Adaptar la navegación a Mobile: mostrar el Menu como drawer dentro de un Sidebar, disparado desde un botón, en vez de ocupar espacio fijo en pantallas chicas. Es la resolución mobile del mismo menú de navegación del admin.
  • Mostrar acciones puntuales sobre un elemento concreto: el Menu es para navegación persistente, no un listado de acciones contextuales (editar, duplicar, eliminar). En su lugar, usar Menu Button dentro de un Popover o Tooltip.
  • Navegar entre vistas de un mismo contenido: por ejemplo, las pestañas de un mismo registro. En su lugar, usar Nav Tabs.
  • Guiar un flujo de pasos secuenciales: un wizard necesita otro patrón. En su lugar, usar Stepper o Accordion según el caso.
  • Confirmar o advertir sobre una acción puntual que interrumpe el flujo: el Menu no reemplaza a un modal de decisión. En su lugar, usar Side Modal.

1. Header

Administrar

2. Section

3. Button

4. Button Accordion

5. Footer

  1. Header (opcional): encabezado fijo en la parte superior; muestra el logo de Tiendanube. Su contenido puede ser libre: lo define quien integra el Menu.
  2. Section: agrupa accesos relacionados dentro del cuerpo del menú (Body), con un título opcional que identifica la categoría. Ej.: "Administrar" agrupando "Ventas", "Productos" y "Clientes".
  3. Button: cada acceso de navegación individual, con ícono inicial opcional, estado active para señalar la sección actual y un elemento final opcional (Badge, Tag) para reforzarlo. Implementado con el componente Menu Button.
  4. Button Accordion: grupo expandible dentro de una Section, para anidar subaccesos que solo importan dentro de esa categoría sin saturar el nivel principal de navegación. Ej.: "Ventas" despliega "Lista de ventas" y "Exportar lista".
  5. Footer (opcional): acción fija en la parte inferior, siempre visible; reservada para un acceso de baja frecuencia pero necesario en todo momento.
  • Expanded (default): modo completo, con ícono y label visibles en cada acceso, header con marca y control de collapse, y footer con accesos de cuenta. Es el comportamiento por defecto del menú de navegación del admin — la variante Fixed — mostrado así en todas las páginas dentro del App Shell.
  • Collapsed (rail): reduce el menú a una franja angosta de solo íconos (expanded={false}), mostrando el label en un popover al pasar el cursor (según showPopoversWhenCollapsed) — pasá el cursor por cualquier ícono para verlo. Es la opción que el merchant activa en Desktop cuando prioriza superficie de pantalla por sobre la navegación visible.

Expanded

Gestión

Canales de venta

Aplicaciones

Collapsed

  • MenuExpandContext — cuando el Menu se integra dentro de App Shell, el modo expandido/colapsado puede heredarse automáticamente de este contexto, sin necesidad de pasar expanded a mano en cada Menu.

La matriz muestra el aspecto de un Menu.Button en cada estado: reposo, hover, foco y seleccionado (active).

Matriz de estados del Menu Button: reposo, hover, foco y seleccionado (active).

Al ser el menú de navegación principal del admin, su comportamiento por dispositivo resuelve los tres casos reales de uso, soportados por App Shell: Fixed y Collapsed en Desktop, Drawer en Mobile.

Comportamiento por defecto en todas las páginas del admin: el Menu se muestra fijo a la izquierda, expandido, ocupando el alto completo de la pantalla dentro de App Shell. Si la cantidad de secciones sobrepasa el alto de la pantalla, el Menu activa un scroll interno, manteniendo siempre visibles el header y el footer.

Cuando se necesita priorizar superficie de pantalla por sobre la navegación visible, se lo puede colapsar a un modo compacto (rail) que muestra solo íconos, dejando el label disponible en un popover al pasar el cursor (variante Collapsed, ver Variantes). Esta variante se puede activar a demanda del merchant, mediante un botón (Collapse), o automáticamente cuando se activa la superficie de Chat de Lumi (agente IA) dentro del admin.

Gestión

Canales de venta

Aplicaciones

Resolución mobile del mismo menú (variante Drawer): en vez de ocupar espacio fijo, se muestra dentro de un Sidebar que se abre a demanda desde un acceso en el header, y se cierra al seleccionar una opción o tocar fuera.

Gestión

Canales de venta

Aplicaciones

Administrar

Agrupar bajo un mismo título solo accesos relacionados entre sí.

Administrar

Evitar mezclar accesos sin relación temática bajo un mismo título.

Reservar el Badge para un conteo realmente accionable, como los pedidos pendientes.

Evitar saturar cada acceso con un badge o tag: pierden su capacidad de señalar lo urgente.

Marcar como active el acceso de la sección donde está el usuario.

Evitar dejar el menú sin ningún acceso activo cuando el usuario ya está dentro de una sección.

Reservar el Footer para un acceso fijo de baja frecuencia pero siempre necesario.

Evitar poner en el Footer un acceso de uso frecuente: ese tipo de accesos va en el Body.

  • Navegación por teclado: cada Menu.Button renderiza un <button> nativo (o un <a> vía as), así que recibe foco con Tab y se activa con Enter o Espacio; el orden de foco sigue el orden real de Secciones y Botones en el documento.
  • Acordeón accesible: Menu.ButtonAccordion aplica aria-expanded sobre su disparador para reflejar si el grupo está abierto o cerrado; el prop contentid (obligatorio) es el que vincula ese disparador con el contenido que despliega, así que siempre debe ser único dentro de la página.
  • Foco visible: al renderizar un <button>/<a> real, hereda el mismo anillo de foco (:focus-visible) que el resto de los componentes interactivos de Nimbus.
  • Label accesible en modo colapsado: cuando el Menu está expanded={false} (rail) y el Button muestra solo el ícono, el label sigue disponible mediante un popover al pasar el cursor (controlado por showPopoversWhenCollapsed), para que el significado del acceso no dependa solo del ícono.

Instalá el componente via terminal.

npm install @nimbus-ds/menu

Uso básico del Menu, sin el layout de la interfaz alrededor.

import React from "react";
import { Menu } from "@nimbus-ds/patterns";
import { Badge, Box, Icon, IconButton, Tag, Text } from "@nimbus-ds/components";
import {
  TiendanubeIcon,
  ExternalLinkIcon,
  HomeIcon,
  StatsIcon,
  CashIcon,
  TagIcon,
  UserIcon,
  DiscountCircleIcon,
  ToolsIcon,
  AppsIcon,
  EcosystemIcon,
  CogIcon,
} from "@nimbus-ds/icons";

const Example: React.FC = () => (
  <Menu>
    <Menu.Header>
      <Box display="flex" gap="2" alignItems="center" width="100%">
        <Icon
          color="neutral-textHigh"
          source={<TiendanubeIcon size="medium" />}
        />
        <Box display="inline-flex" flex="1">
          <Text fontSize="base" color="neutral-textHigh" fontWeight="bold">
            Tienda demo
          </Text>
        </Box>
        <IconButton source={<ExternalLinkIcon />} size="2rem" />
      </Box>
    </Menu.Header>
    <Menu.Body>
      <Menu.Section>
        <Menu.Button startIcon={HomeIcon} label="Inicio" />
        <Menu.Button startIcon={StatsIcon} label="Estadísticas" />
      </Menu.Section>
      <Menu.Section title="Administrar">
        <Menu.ButtonAccordion
          contentid="content-1"
          menuButton={{
            id: "control-1",
            startIcon: CashIcon,
            label: "Ventas",
            children: <Badge appearance="primary" count="1299" />,
            "aria-controls": "content-1",
          }}
        >
          <Menu.Button label="Lista de ventas" active />
          <Menu.Button label="Exportar lista" />
        </Menu.ButtonAccordion>
        <Menu.Button startIcon={TagIcon} label="Productos" />
        <Menu.Button startIcon={UserIcon} label="Clientes">
          <Tag appearance="primary">¡Nuevo!</Tag>
        </Menu.Button>
        <Menu.Button startIcon={DiscountCircleIcon} label="Marketing" />
      </Menu.Section>
      <Menu.Section title="Personalizar">
        <Menu.Button startIcon={ToolsIcon} label="Mi Tiendanube" />
      </Menu.Section>
      <Menu.Section title="Potenciar">
        <Menu.Button startIcon={AppsIcon} label="Mis aplicaciones" />
        <Menu.Button startIcon={EcosystemIcon} label="Canales de venta" />
      </Menu.Section>
    </Menu.Body>
    <Menu.Footer label="Configuración" startIcon={CogIcon} />
  </Menu>
);

export default Example;

Las propiedades adicionales se pasan al elemento <Menu>. Consultá la documentación del elemento div para ver la lista de atributos aceptados.

  • Menu Button — implementa cada acceso individual dentro del Menu.
  • App Shell — define el layout general de la aplicación e integra el Menu como sidebar, compartiendo el estado de expansión.
  • Sidebar — panel lateral usado para mostrar el Menu como drawer en pantallas chicas.
  • Nav Tabs — alternativa para navegar entre vistas de un mismo contenido, no entre secciones de la aplicación.

Menu

NameTypeDefaultDescription

children*

React.ReactNode

Content of the menu.

expanded

boolean

Whether the menu should render in expanded mode. If `undefined`, it follows `MenuExpandContext` value. If provided, it overrides the context.

showPopoversWhenCollapsed

boolean

Whether to show popover for buttons when the menu is collapsed. Defaults to true.

popoverPosition

'bottom'
'bottom-end'
'bottom-start'
'left'
'left-end'
'left-start'
'right'
'right-end'
'right-start'
'top'
'top-end'
'top-start'

Position of the popovers for buttons when the menu is collapsed. Defaults to "right".

Menu.Section

NameTypeDefaultDescription

title

string

Optional title of the section.

children*

React.ReactNode

Content of the menu section.

Menu.Header

NameTypeDefaultDescription

children*

React.ReactNode

Content of the menu header.

Menu.Body

NameTypeDefaultDescription

children*

React.ReactNode

Content of the menu body.

Menu.Footer

NameTypeDefaultDescription

onClick

() => void;

Function executed when clicking the button.

label

string

Text label for the button.

expanded

boolean

Controlled override for menu expansion state. This prop does not manage internal state and is not forwarded to the DOM as an attribute. It is used only for layout and visual state determination. If not provided, the expanded state will be determined by the context.

active

boolean

Sets the state of the button as active/inactive.

startIcon

React.FC<IconProps>

Sets an icon element on the left of the button.

showPopoversWhenCollapsed

boolean

Whether to show popovers when the button is collapsed. Defaults to true.

Ayudanos a mejorar la documentación

¿Encontraste un problema o tenés una sugerencia? Contanos.