# System Instruction: Arquitetura de Layout com Sidebar Expansível **Role:** Senior React Developer & UI Specialist **Tech Stack:** React, Tailwind CSS (Sem bibliotecas de ícones ou fontes externas). **Objetivo:** Implementar um sistema de layout "Dashboard" composto por um **Menu Lateral (Sidebar)** que expande e colapsa suavemente e uma área de conteúdo principal. **Requisitos Críticos de Animação:** 1. A transição de largura da sidebar deve ser suave (transition-all duration-300). 2. O texto dos botões **não deve quebrar** ou desaparecer bruscamente. Use a técnica de transição de `max-width` e `opacity` para que o texto deslize suavemente para fora. 3. Não utilize bibliotecas de animação (Framer Motion, etc), apenas Tailwind CSS puro. --- ## 1. Componente: `DashboardLayout.tsx` (Container Principal) Este componente deve gerenciar o estado global do menu (aberto/fechado) para evitar "prop drilling" desnecessário. ```tsx import React, { useState } from 'react'; import { SidebarRail } from './SidebarRail'; interface DashboardLayoutProps { children: React.ReactNode; } export const DashboardLayout: React.FC = ({ children }) => { // Estado centralizado do layout const [isExpanded, setIsExpanded] = useState(true); const [activeTab, setActiveTab] = useState('home'); return (
{/* Sidebar controla seu próprio estado visual via props */} setIsExpanded(!isExpanded)} /> {/* Área de Conteúdo (Children) */}
{children}
); }; ``` ## 2. Componente: `SidebarRail.tsx` (Lógica de Animação) Aqui reside a lógica visual. Substitua os ícones por `Icon` ou SVGs genéricos para manter o código agnóstico. **Pontos de atenção no código abaixo:** * `w-[220px]` vs `w-[72px]`: Define a largura física. * `max-w-[150px]` vs `max-w-0`: Define a animação do texto. * `whitespace-nowrap`: Impede que o texto pule de linha enquanto fecha. ```tsx import React from 'react'; interface SidebarRailProps { activeTab: string; onTabChange: (tab: string) => void; isExpanded: boolean; onToggle: () => void; } export const SidebarRail: React.FC = ({ activeTab, onTabChange, isExpanded, onToggle }) => { return (
{/* Header / Toggle */}
Logo
{/* Título com animação de opacidade e largura */}
App Name
{/* Navegação */}
onTabChange('home')} isExpanded={isExpanded} /> onTabChange('settings')} isExpanded={isExpanded} />
{/* Footer / Toggle Button */}
); }; // Subcomponente do Botão (Essencial para a animação do texto) const RailButton = ({ label, active, onClick, isExpanded }: any) => ( ); ```