Componentes UI Base
Esta página documenta os componentes UI base disponíveis no APAH Assistant, todos baseados no shadcn/ui.
Button
Botão com múltiplas variantes e tamanhos.
Importação
import { Button } from "@/components/ui/button";
Variantes
<Button variant="default">Default</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
Tamanhos
<Button size="sm">Pequeno</Button>
<Button size="default">Normal</Button>
<Button size="lg">Grande</Button>
<Button size="icon"><IconComponent /></Button>
Com Ícone
import { Loader2, Mail } from "lucide-react";
<Button>
<Mail className="mr-2 h-4 w-4" />
Email
</Button>
<Button disabled>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
A carregar
</Button>
Props
| Prop | Tipo | Default | Descrição |
|---|---|---|---|
variant | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "default" | Estilo visual |
size | "default" | "sm" | "lg" | "icon" | "default" | Tamanho |
asChild | boolean | false | Renderizar como slot |
Input
Campo de entrada de texto.
Importação
import { Input } from "@/components/ui/input";
Uso Básico
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password" />
<Input disabled placeholder="Desativado" />
Com Label
import { Label } from "@/components/ui/label";
<div className="grid gap-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="nome@exemplo.com" />
</div>
Com Ícone
<div className="relative">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input className="pl-10" placeholder="Pesquisar..." />
</div>
Dialog
Modal dialog para interações focadas.
Importação
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogClose,
} from "@/components/ui/dialog";
Uso Básico
<Dialog>
<DialogTrigger asChild>
<Button>Abrir Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Título</DialogTitle>
<DialogDescription>
Descrição do que este dialog faz.
</DialogDescription>
</DialogHeader>
<div className="py-4">
{/* Conteúdo */}
</div>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancelar</Button>
</DialogClose>
<Button>Confirmar</Button>
</DialogFooter>
</DialogContent>
</Dialog>
Controlado
const [open, setOpen] = useState(false);
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
{/* ... */}
<Button onClick={() => setOpen(false)}>Fechar</Button>
</DialogContent>
</Dialog>
// Abrir programaticamente
<Button onClick={() => setOpen(true)}>Abrir</Button>
Card
Container com estilo para agrupar conteúdo.
Importação
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
Uso
<Card className="w-[350px]">
<CardHeader>
<CardTitle>Título do Card</CardTitle>
<CardDescription>Descrição ou subtítulo</CardDescription>
</CardHeader>
<CardContent>
<p>Conteúdo principal do card.</p>
</CardContent>
<CardFooter className="flex justify-between">
<Button variant="outline">Cancelar</Button>
<Button>Confirmar</Button>
</CardFooter>
</Card>
Select
Lista de seleção dropdown.
Importação
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
Uso
<Select>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Selecionar..." />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Frutas</SelectLabel>
<SelectItem value="apple">Maçã</SelectItem>
<SelectItem value="banana">Banana</SelectItem>
<SelectItem value="orange">Laranja</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
Controlado
const [value, setValue] = useState("apple");
<Select value={value} onValueChange={setValue}>
{/* ... */}
</Select>
Avatar
Imagem de perfil de utilizador.
Importação
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
Uso
<Avatar>
<AvatarImage src="https://example.com/avatar.jpg" alt="@username" />
<AvatarFallback>JD</AvatarFallback>
</Avatar>
Tamanhos Customizados
<Avatar className="h-16 w-16">
<AvatarImage src="/avatar.jpg" />
<AvatarFallback className="text-2xl">JD</AvatarFallback>
</Avatar>
DropdownMenu
Menu dropdown para ações.
Importação
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
Uso
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Ações</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => handleEdit()}>
<Edit className="mr-2 h-4 w-4" />
Editar
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleDelete()}
className="text-destructive"
>
<Trash className="mr-2 h-4 w-4" />
Eliminar
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
Tooltip
Dica contextual ao hover.
Importação
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
Uso
// TooltipProvider deve envolver a app ou a área que usa tooltips
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="icon">
<Info className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Informação adicional</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
ScrollArea
Área com scroll customizado.
Importação
import { ScrollArea } from "@/components/ui/scroll-area";
Uso
<ScrollArea className="h-[200px] w-[350px] rounded-md border p-4">
{longContent.map((item) => (
<div key={item.id} className="py-2">
{item.content}
</div>
))}
</ScrollArea>
Switch
Toggle on/off.
Importação
import { Switch } from "@/components/ui/switch";
Uso
<div className="flex items-center space-x-2">
<Switch id="airplane-mode" />
<Label htmlFor="airplane-mode">Modo avião</Label>
</div>
Controlado
const [enabled, setEnabled] = useState(false);
<Switch checked={enabled} onCheckedChange={setEnabled} />
Alert
Mensagem de alerta ou feedback.
Importação
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
Variantes
// Default
<Alert>
<Info className="h-4 w-4" />
<AlertTitle>Informação</AlertTitle>
<AlertDescription>
Esta é uma mensagem informativa.
</AlertDescription>
</Alert>
// Destructive
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Erro</AlertTitle>
<AlertDescription>
Ocorreu um erro ao processar o pedido.
</AlertDescription>
</Alert>
Separator
Linha separadora visual.
Importação
import { Separator } from "@/components/ui/separator";
Uso
<div>
<h2>Título</h2>
<Separator className="my-4" />
<p>Conteúdo abaixo do separador</p>
</div>
{/* Vertical */}
<div className="flex h-5 items-center space-x-4">
<div>Item 1</div>
<Separator orientation="vertical" />
<div>Item 2</div>
</div>