Skip to content

TalentBricksAI usa ShadCN UI (estilo New York) con Radix UI primitives.

Los componentes estan en app/src/client/components/ui/.

ComponenteArchivoDescripcion
Buttonbutton.tsxBotones con variantes
Inputinput.tsxCampo de texto
Textareatextarea.tsxArea de texto
Selectselect.tsxSelector dropdown
Checkboxcheckbox.tsxCasilla de verificacion
Switchswitch.tsxToggle switch
Labellabel.tsxEtiqueta para inputs
Formform.tsxWrapper de formulario
ComponenteArchivoDescripcion
Cardcard.tsxContenedor con borde
Dialogdialog.tsxModal dialog
Sheetsheet.tsxPanel deslizante
Separatorseparator.tsxLinea divisora
Tabstabs.tsxNavegacion por tabs
ComponenteArchivoDescripcion
Alertalert.tsxMensaje de alerta
Toasttoaster.tsxNotificaciones toast
Progressprogress.tsxBarra de progreso
Skeletonskeleton.tsxPlaceholder de carga
ComponenteArchivoDescripcion
DropdownMenudropdown-menu.tsxMenu desplegable
NavigationMenunavigation-menu.tsxMenu de navegacion
Breadcrumbbreadcrumb.tsxMigas de pan
ComponenteArchivoDescripcion
Tabletable.tsxTabla de datos
Avataravatar.tsxAvatar de usuario
Badgebadge.tsxEtiqueta/badge
import { Button } from '../client/components/ui/button';
// Variantes
<Button variant="default">Primario</Button>
<Button variant="secondary">Secundario</Button>
<Button variant="destructive">Eliminar</Button>
<Button variant="outline">Contorno</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
// Tamanos
<Button size="sm">Pequeno</Button>
<Button size="default">Normal</Button>
<Button size="lg">Grande</Button>
// Estados
<Button disabled>Deshabilitado</Button>
<Button loading>Cargando...</Button>
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter
} from '../client/components/ui/card';
<Card>
<CardHeader>
<CardTitle>Titulo del Card</CardTitle>
<CardDescription>Descripcion opcional</CardDescription>
</CardHeader>
<CardContent>
<p>Contenido principal aqui</p>
</CardContent>
<CardFooter>
<Button>Accion</Button>
</CardFooter>
</Card>
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter
} from '../client/components/ui/dialog';
<Dialog>
<DialogTrigger asChild>
<Button>Abrir Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Titulo</DialogTitle>
<DialogDescription>
Descripcion del dialog
</DialogDescription>
</DialogHeader>
<div>Contenido...</div>
<DialogFooter>
<Button>Confirmar</Button>
</DialogFooter>
</DialogContent>
</Dialog>
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage
} from '../client/components/ui/form';
import { Input } from '../client/components/ui/input';
import { Button } from '../client/components/ui/button';
const schema = z.object({
email: z.string().email('Email invalido'),
password: z.string().min(8, 'Minimo 8 caracteres')
});
function LoginForm() {
const form = useForm({
resolver: zodResolver(schema),
defaultValues: { email: '', password: '' }
});
const onSubmit = (data) => {
console.log(data);
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="tu@email.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Contrasena</FormLabel>
<FormControl>
<Input type="password" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Iniciar Sesion</Button>
</form>
</Form>
);
}
import { useToast } from '../client/components/ui/use-toast';
function MyComponent() {
const { toast } = useToast();
const handleClick = () => {
toast({
title: 'Exito!',
description: 'La operacion se completo correctamente.',
});
};
// Toast de error
const handleError = () => {
toast({
variant: 'destructive',
title: 'Error',
description: 'Algo salio mal.',
});
};
return <Button onClick={handleClick}>Mostrar Toast</Button>;
}
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '../client/components/ui/table';
<Table>
<TableHeader>
<TableRow>
<TableHead>Nombre</TableHead>
<TableHead>Email</TableHead>
<TableHead>Rol</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{users.map((user) => (
<TableRow key={user.id}>
<TableCell>{user.name}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{user.role}</TableCell>
</TableRow>
))}
</TableBody>
</Table>

Los colores se definen con CSS variables en tailwind.config.js:

/* Variables principales */
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--secondary: 210 40% 96.1%;
--muted: 210 40% 96.1%;
--accent: 210 40% 96.1%;
--destructive: 0 84.2% 60.2%;

El modo oscuro se activa con la clase dark en el <html>:

import { DarkModeSwitcher } from '../client/components/DarkModeSwitcher';
// El componente ya esta integrado en el NavBar
<DarkModeSwitcher />

Para agregar un componente de ShadCN:

Terminal window
cd app
npx shadcn-ui@latest add [component-name]

Ejemplo:

Terminal window
npx shadcn-ui@latest add calendar
npx shadcn-ui@latest add slider