@darksnow-ui/nav-sidebar
v0.0.2
Published
Collapsible navigation sidebar component for DarkSnow UI
Readme
Sidebar Component
Componente de sidebar híbrido profissional com suporte para collapsed/expanded, submenus expansíveis, badges tipados e tooltips.
Recursos
- 🎯 Estados collapsed/expanded com transições suaves
- 📁 Submenus expansíveis com animação e caret rotativo
- 🏷️ Sistema de badges com 4 tipos (info, success, warning, danger)
- 💬 Tooltips inteligentes no modo collapsed
- 🎨 Totalmente customizável via classes CSS
- 🌓 Suporte completo para dark mode
- ♿ Acessível com suporte a teclado
- 🚀 Performance otimizada com lazy rendering
Instalação
O componente já usa dependências instaladas no projeto:
@radix-ui/react-tooltipreact-router-domclsx
Uso Básico
import { Sidebar } from "@/components/sidebar";
import { Home, Users, Settings, Menu, X } from "lucide-react";
const iconMap = {
home: Home,
users: Users,
settings: Settings,
menu: Menu,
"menu-open": X,
};
const menuItems = [
{
id: "home",
label: "Home",
icon: "home",
href: "/",
},
{
id: "users",
label: "Usuários",
icon: "users",
href: "/users",
badge: 5,
badgeType: "info", // info | success | warning | danger
},
{
id: "reports",
label: "Relatórios",
icon: "reports",
badge: "!",
badgeType: "warning",
children: [
{
id: "reports-sales",
label: "Vendas",
icon: "chart",
href: "/reports/sales",
},
{
id: "reports-analytics",
label: "Analytics",
icon: "analytics",
href: "/reports/analytics",
badge: "New",
badgeType: "success",
},
],
},
];
function App() {
const [collapsed, setCollapsed] = useState(false);
return (
<Sidebar
items={menuItems}
collapsed={collapsed}
onCollapsedChange={setCollapsed}
resolveIcon={(name) => iconMap[name as keyof typeof iconMap]}
hamburger={{
enabled: true,
icon: "menu",
expandedIcon: "menu-open",
label: "Menu Principal",
}}
/>
);
}Props
SidebarProps
| Prop | Tipo | Descrição |
| ------------------- | --------------------------------------- | ---------------------------------- |
| items | MenuItem[] | Lista de items do menu |
| collapsed | boolean? | Estado collapsed (controlado) |
| onCollapsedChange | (collapsed: boolean) => void? | Callback para mudança de estado |
| resolveIcon | (name: string) => React.ComponentType | Função para resolver ícones |
| hamburger | HamburgerConfig? | Configuração do botão hamburger |
| className | string? | Classes para o container principal |
| classNames | ClassNames? | Classes para elementos internos |
MenuItem
interface MenuItem {
id: string;
label: string;
icon: string;
href?: string;
action?: () => void;
children?: MenuItem[];
disabled?: boolean;
badge?: string | number;
badgeType?: "danger" | "info" | "success" | "warning";
}HamburgerConfig
interface HamburgerConfig {
enabled: boolean;
icon?: string; // default: "menu"
expandedIcon?: string; // default: "menu-open"
label?: string; // default: "Menu"
}ClassNames
interface ClassNames {
root?: string; // Container principal
nav?: string; // Elemento nav
item?: string; // Item do menu
itemActive?: string; // Item ativo
itemDisabled?: string; // Item desabilitado
icon?: string; // Container do ícone
label?: string; // Label do item
badge?: string; // Badge
hamburger?: string; // Botão hamburger
submenu?: string; // Dropdown submenu
}Comportamentos
Modo Collapsed (60px largura)
- Items sem children: mostram tooltip ao hover
- Items com children e href: mostram dropdown flutuante ao hover
- Items com children sem href: ao clicar, expandem o sidebar e abrem o submenu
- Badges aparecem no canto inferior direito do ícone (máx. 4 caracteres)
- Largura: 60px
Modo Expanded (256px largura)
- Items mostram ícone + label + badge (se houver)
- Items com children mostram caret que rotaciona ao expandir
- Submenus aparecem com animação slideDown
- Clicar em item com children toggle o submenu
- Largura padrão: 256px (w-64)
Sistema de Badges
- Tipos disponíveis: info (azul), success (verde), warning (amarelo), danger (vermelho)
- Modo collapsed: Badge pequeno no canto inferior direito do ícone
- Modo expanded: Badge à direita do label com cores suaves
- Suporta: números e strings (ex: "999+", "New", "!")
Navegação
- Integrado com React Router
- Detecta automaticamente item ativo baseado na URL
- Suporta tanto
href(Link) quantoaction(button) - Items ativos têm destaque visual
Exemplos Avançados
Com Actions e Badges Tipados
const items = [
{
id: "notifications",
label: "Notificações",
icon: "bell",
badge: 12,
badgeType: "info",
action: () => openNotifications(),
},
{
id: "errors",
label: "Erros",
icon: "alert",
badge: "!",
badgeType: "danger",
href: "/errors",
},
{
id: "updates",
label: "Atualizações",
icon: "download",
badge: "New",
badgeType: "success",
children: [
{
id: "update-system",
label: "Sistema",
icon: "settings",
action: () => checkUpdates(),
},
],
},
];Item Apenas Container (sem href)
const items = [
{
id: "management",
label: "Gerenciamento",
icon: "folder",
// Sem href - ao clicar quando collapsed, expande o sidebar
children: [
{
id: "users",
label: "Usuários",
icon: "users",
href: "/management/users",
},
{
id: "roles",
label: "Perfis",
icon: "shield",
href: "/management/roles",
},
],
},
];Customização de Estilos
<Sidebar
items={items}
className="shadow-lg"
classNames={{
item: "rounded-lg mx-2",
itemActive: "bg-blue-500 text-white",
itemActiveIcon: "text-white",
badge: "font-bold",
hamburger: "border-b-2 border-gray-200",
submenu: "bg-gray-50 rounded-lg",
}}
/>Estado Não Controlado
// Sidebar gerencia próprio estado
<Sidebar
items={items}
resolveIcon={resolveIcon}
hamburger={{
enabled: true,
label: "Menu",
}}
/>Separadores e Organização
const items = [
// Items principais
{ id: "home", label: "Home", icon: "home", href: "/" },
{ id: "dashboard", label: "Dashboard", icon: "chart", href: "/dashboard" },
// Separador com items de configuração
{
id: "bottom-section",
icon: "", // Sem ícone
label: "", // Sem label
children: [
{
id: "settings",
label: "Configurações",
icon: "settings",
href: "/settings",
},
{ id: "help", label: "Ajuda", icon: "help", href: "/help" },
],
},
];