Sidebar
Um componente de sidebar componível, com suporte a temas e personalizável.
Uso
Primeiro, crie um componente Sidebar na sua aplicação.
Provider
Depois, adicione SidebarProvider, SidebarTrigger e AppSidebar na raiz da sua aplicação.
import { SidebarProvider, SidebarTrigger } from "@medway-ui/core"
import { AppSidebar } from "@/components/AppSidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger
showTooltip
enableHover
tooltipContent={{
open: "Esconder sidebar",
closed: "Mostrar sidebar"
}}
/>
{children}
</main>
</SidebarProvider>
)
}Mobile
Com a janela abaixo de 768px de largura, a Sidebar vira um sheet que abre pelo SidebarTrigger (exceto com collapsible="none"), e o useSidebar passa a usar o openMobile. Quem decide é o hook useIsMobile.
Esse limite é diferente do breakpoint tablet do DS, de 600px (o md: do Tailwind). Ele fica em 768px por compatibilidade com o test-prep-web, que monta o layout de celular nesse valor, e passa para 600px na próxima versão major.
Exemplos
Sidebar com tooltip e efeitos de hover
O componente Sidebar oferece tooltips e efeitos de hover:
- SidebarTrigger: use
enableHoverpara trocar o ícone no hover (ChevronLeft quando aberta, ChevronRight quando fechada) - SidebarMenuButton: use a prop
tooltippara exibir tooltips quando a sidebar está recolhida - Conteúdo personalizado do tooltip: use a prop
tooltipContentno SidebarTrigger para personalizar as mensagens do tooltip
Sidebar com switcher no cabeçalho, efeito de hover no trigger e tooltip
Para ativar o efeito de hover no SidebarTrigger, defina enableHover como true: no hover, ele mostra ChevronLeft quando a sidebar está aberta e ChevronRight quando está fechada. Você também pode personalizar o conteúdo do tooltip passando em tooltipContent mensagens próprias para os estados aberto e fechado.
API
Estrutura da Sidebar
| Componente | Descrição | Uso |
|---|---|---|
| SidebarProvider | Componente raiz que gerencia o estado da sidebar | Deve envolver toda a aplicação onde a Sidebar será usada |
| Sidebar | Componente principal que renderiza a sidebar | Container principal de toda a estrutura da sidebar |
| SidebarContent | Container do conteúdo da sidebar | Cuida do layout e da rolagem do conteúdo principal |
| SidebarHeader | Seção superior da sidebar | Ideal para logos, títulos ou controles principais |
| SidebarFooter | Seção inferior da sidebar | Útil para informações de status, controles do usuário ou ações secundárias |
| SidebarGroup | Agrupa itens relacionados | Container para grupos de itens com um título em comum |
| SidebarGroupLabel | Título do grupo | Define o cabeçalho de um grupo de itens |
| SidebarGroupContent | Container do conteúdo do grupo | Envolve os itens de um grupo |
| SidebarGroupAction | Botão de ação de um grupo | Ações contextuais relacionadas ao grupo |
| SidebarMenu | Lista de itens de menu | Container dos itens de navegação |
| SidebarMenuItem | Item de menu individual | Container de um item de navegação |
| SidebarMenuButton | Botão de menu clicável | Elemento interativo de navegação |
| SidebarMenuItemTitle | Título e ícone do item | Exibe o conteúdo visual do item de menu |
| SidebarMenuItemCollapse | Indicador de recolhimento do item de menu | Exibe o item de menu com um ícone de recolher |
| SidebarMenuAction | Botão de ação do item | Ações contextuais de um item específico |
| SidebarMenuBadge | Badge ou contador | Exibe informações adicionais sobre o item. O SidebarMenuButton reserva espaço à direita para um contador de até 3 caracteres (ex.: "128" ou "99+"), e o título longo é truncado antes dele |
| SidebarMenuSub | Container do submenu | Agrupa os itens aninhados do submenu |
| SidebarMenuSubItem | Item do submenu | Container de um item do submenu |
| SidebarMenuSubButton | Botão do submenu | Elemento interativo de navegação no submenu |
| SidebarTrigger | Botão de alternância | Controla a visibilidade da sidebar |
| SidebarRail | Alça clicável na borda da sidebar | Botão que recolhe ou expande a sidebar (mesma ação do SidebarTrigger), fora da ordem de Tab. O nome acessível vem da prop label. Para uma linha divisória, use o SidebarSeparator |
| SidebarSeparator | Linha divisória | Separa seções dentro da sidebar |
| SidebarInput | Campo de entrada | Campo de texto estilizado para a sidebar |
| SidebarInset | Container de conteúdo | Ajusta o conteúdo principal à sidebar |
| SidebarMenuSkeleton | Componente de carregamento | Exibe o estado de carregamento dos itens de menu |
SidebarProvider
O estado de abertura fica no provider, então estas props vão no SidebarProvider (e não na Sidebar). Ele também aceita todas as props de div e alterna a sidebar com Cmd/Ctrl + B.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| defaultOpen | boolean | true, false | true | Estado inicial de abertura quando a sidebar não é controlada. |
| open | boolean | true, false | - | Controla o estado de abertura da sidebar (modo controlado). |
| onOpenChange | (open: boolean) => void | - | - | Função chamada quando o estado de abertura muda. |
Sidebar
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| side | "left" | "right" | "left", "right" | "left" | Define de que lado a sidebar será exibida. |
| variant | "sidebar" | "floating" | "inset" | "sidebar", "floating", "inset" | "sidebar" | Define o estilo visual da sidebar. |
| collapsible | "offcanvas" | "icon" | "none" | "offcanvas", "icon", "none" | "offcanvas" | Define o comportamento de recolhimento da sidebar. |
| containerClassName | string | Qualquer string de classe CSS | - | Classes CSS adicionais para o elemento container da sidebar. |
| mobileTitle | string | - | "Menu lateral" | Título visualmente oculto, anunciado por leitores de tela quando a sidebar abre como sheet no mobile. |
| mobileDescription | string | - | "Navegação principal da aplicação." | Descrição visualmente oculta do sheet no mobile. |
SidebarMenuButton
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| variant | "default" | "section" | "outline" | "default", "section", "outline" | "default" | Define o estilo visual do botão de menu. |
| size | "md" | "sm" | "lg" | "md", "sm", "lg" | "md" | Define o tamanho do botão de menu. |
| isActive | boolean | true, false | false | Define se o botão de menu está ativo. |
| tooltip | string | TooltipContentProps | - | - | Define o texto ou as configurações do tooltip do botão. Quando recebe uma string, ela é convertida em TooltipContentProps com a string como children. |
| asChild | boolean | true, false | false | Permite renderizar o botão como um elemento filho personalizado. |
SidebarMenuSubButton
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| size | "sm" | "md" | "sm", "md" | "md" | Define o tamanho do botão do submenu. |
| isActive | boolean | true, false | false | Define se o botão do submenu está ativo. Quando ativo, aplica o estilo de ativo com peso de fonte semibold e a cor de texto secundária. |
| asChild | boolean | true, false | false | Permite renderizar o botão como um elemento filho personalizado. |
SidebarTrigger
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| icon | React.ReactNode | Qualquer nó React | <HamburgerMd /> | Ícone do trigger, com a sidebar aberta ou fechada. Com enableHover, vira ChevronLeft/ChevronRight no hover. |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
| onClick | (event: React.MouseEvent) => void | - | - | Função chamada quando o trigger é clicado. |
| showTooltip | boolean | true, false | false | Define se um tooltip aparece no hover do trigger. |
| tooltipContent | { open?: string; closed?: string } | - | { open: "Esconder", closed: "Mostrar" } | Conteúdo personalizado do tooltip para os estados aberto e fechado. |
| sizeIcon | string | Qualquer string de classe CSS | "size-4" | Tamanho do ícone padrão e dos chevrons do hover. Não vale para um icon customizado, que traz o próprio tamanho. |
| enableHover | boolean | true, false | false | Define se o efeito de hover (troca de ícone) está ativo. Quando ativo, mostra no hover ChevronLeft com a sidebar aberta e ChevronRight com ela fechada. |
| label | string | - | "Alternar barra lateral" | Label acessível do trigger. O SidebarRail aceita a mesma prop. |
SidebarMenuItem
Item (li) de um SidebarMenu. Aceita as props nativas de li.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| isActive | boolean | true, false | - | Quando true, mostra uma barra vertical à esquerda do item para marcar a seção ativa. Não altera o estilo do SidebarMenuButton, que tem o próprio isActive. |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
SidebarMenuAction
Botão de ação posicionado à direita de um SidebarMenuButton, dentro do mesmo SidebarMenuItem. Fica oculto quando a sidebar está recolhida em modo ícone. Aceita as props nativas de button.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| showOnHover | boolean | true, false | false | Quando true, em telas médias ou maiores a ação fica invisível e só aparece com hover ou foco no item, ou quando o menu associado está aberto (data-state="open"). |
| asChild | boolean | true, false | false | Renderiza o filho passado no lugar do button padrão, repassando classes e props (por exemplo, para usar um link). |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
SidebarMenuSkeleton
Placeholder de carregamento para um item de menu, com a largura do texto variando entre os itens. Aceita as props nativas de div.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| showIcon | boolean | true, false | false | Quando true, mostra também um skeleton quadrado no lugar do ícone, antes do texto. |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
SidebarGroupLabel
Título de um SidebarGroup. Aceita as props nativas de div.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| asChild | boolean | true, false | false | Renderiza o filho passado no lugar do div padrão, repassando classes e props (por exemplo, para usar um link). |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
SidebarGroupAction
Botão de ação no canto do título de um SidebarGroup. Aceita as props nativas de button.
| Propriedade | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| asChild | boolean | true, false | false | Renderiza o filho passado no lugar do button padrão, repassando classes e props (por exemplo, para usar um link). |
| className | string | Qualquer string de classe CSS | - | Classes CSS adicionais para personalizar o estilo. |
useSidebar
Hook que dá acesso ao estado e às ações da sidebar. Só pode ser usado dentro de um SidebarProvider; fora dele, lança um erro.
import { useSidebar } from "@medway-ui/core";
const { state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar } = useSidebar();| Retorno | Tipo | Valores possíveis | Padrão | Descrição |
|---|---|---|---|---|
| state | "expanded" | "collapsed" | "expanded", "collapsed" | - | Estado visual da sidebar no desktop, derivado de open. |
| open | boolean | true, false | - | Se a sidebar está aberta no desktop. |
| setOpen | (open: boolean) => void | - | - | Abre ou fecha a sidebar no desktop. Também chama o onOpenChange do provider e salva o estado no cookie sidebar_state. |
| openMobile | boolean | true, false | - | Se a sidebar está aberta no mobile. |
| setOpenMobile | (open: boolean) => void | - | - | Abre ou fecha a sidebar no mobile. |
| isMobile | boolean | true, false | - | Se a janela tem menos de 768px de largura (veja Mobile). |
| toggleSidebar | () => void | - | - | Alterna a sidebar, usando o estado do mobile ou do desktop conforme a tela. É a mesma ação do atalho Ctrl/Cmd + B. |
useIsMobile
Hook que a Sidebar e o DropdownMenuContent usam para decidir o layout de celular. Retorna true com a janela abaixo de 768px de largura e acompanha o redimensionamento. No servidor, retorna false.
import { useIsMobile } from "@medway-ui/core";
const isMobile = useIsMobile();O limite de 768px é diferente do breakpoint tablet do DS (600px) e fica assim por compatibilidade com o test-prep-web. Ele passa para 600px na próxima versão major.