Frontend Componente Library
Frontend Componente Library
Version: 1.0 Date: 2025-11-19 Project: Algesta Dashboard React
Tabla de Contenidos
- Descripción General del Sistema de Diseño
- Tokens de Diseño
- Catálogo de Componentes
- Patrones de Uso de Componentes
- Enfoque de Estilos
- Accesibilidad
- Personalización
- Agregar Nuevos Componentes
- Guía de Desarrollo de Componentes
Descripción General del Sistema de Diseño
El Dashboard de Algesta implementa un sistema de diseño integral basado en el patrón shadcn/ui. Este enfoque proporciona:
- Componentes Componibles: Componentes pequeños y enfocados que trabajan juntos
- Accesible por Defecto: Construido sobre primitivos Radix UI (compatible con WAI-ARIA)
- Personalizable: Los componentes se copian al proyecto y pueden modificarse
- Type-Safe: Soporte completo de TypeScript con tipos de props explícitos
Filosofía
A diferencia de las bibliotecas de componentes tradicionales (paquetes npm), los componentes shadcn/ui se copian directamente en tu proyecto. Esto te da:
- Propiedad y control total sobre el código del componente
- Sin dependencias de caja negra
- Personalización fácil sin luchar contra la biblioteca
- Capacidad de ver y modificar el código fuente del componente
Tokens de Diseño
Paleta de Colores
Todos los colores se definen como variables CSS en src/index.css usando formato HSL:
Colores Primarios
| Token | Valor | Uso |
|---|---|---|
--primary | hsla(32, 100%, 50%, 1) | Naranja - Color principal de marca para botones, enlaces, acciones primarias |
--primary-foreground | hsla(0, 0%, 100%, 1) | Blanco - Texto sobre fondo primario |
Neutral Colors (Gray Scale)
| Token | Value | Usage |
|---|---|---|
--neutral-50 | hsla(0, 0%, 98%, 1) | Lightest gray - Background |
--neutral-100 | hsla(240, 5%, 96%, 1) | Very light gray |
--neutral-200 | hsla(240, 6%, 90%, 1) | Light gray - Borders |
--neutral-300 | hsla(240, 5%, 84%, 1) | Medium-light gray |
--neutral-400 | hsla(240, 5%, 65%, 1) | Medium gray |
--neutral-500 | hsla(240, 4%, 46%, 1) | Medium-dark gray - Secondary text |
--neutral-600 | hsla(240, 5%, 34%, 1) | Dark gray |
--neutral-700 | hsla(240, 5%, 26%, 1) | Darker gray - Body text |
--neutral-800 | hsla(240, 4%, 16%, 1) | Very dark gray |
--neutral-900 | hsla(240, 6%, 10%, 1) | Almost black - Headings |
Blue (Accent)
| Token | Value | Usage |
|---|---|---|
--blue-50 to --blue-900 | Various blue shades | Informational elements, links, accents |
Success (Green)
| Token | Value | Usage |
|---|---|---|
--success-50 to --success-900 | Various green shades | Success states, positive actions, Completod Estado |
Warning (Yellow/Orange)
| Token | Value | Usage |
|---|---|---|
--warning-50 to --warning-900 | Various yellow/orange shades | Warning states, Pendiente actions |
Destructive (Red)
| Token | Value | Usage |
|---|---|---|
--destructive | Red | Error states, dangerous actions, delete buttons |
--destructive-foreground | White | Text on destructive background |
Chart Colors
| Token | Value | Usage |
|---|---|---|
--chart-1 | hsla(12, 76%, 61%, 1) | Chart data series 1 |
--chart-2 | hsla(173, 58%, 39%, 1) | Chart data series 2 |
--chart-3 | hsla(197, 37%, 24%, 1) | Chart data series 3 |
--chart-4 | hsla(43, 74%, 66%, 1) | Chart data series 4 |
--chart-5 | hsla(27, 87%, 67%, 1) | Chart data series 5 |
Typography
- Font Family: Inter Variable (
--font-inter) - Font Sizes: Tailwind defaults (text-xs, text-sm, text-base, text-lg, text-xl, etc.)
- Font Weights: 400 (normal), 500 (medium), 600 (semibold), 700 (bold)
Spacing
Tailwind spacing scale (0.25rem increments):
p-1= 0.25rem (4px)p-2= 0.5rem (8px)p-4= 1rem (16px)p-6= 1.5rem (24px)p-8= 2rem (32px)
Border Radius
| Token | Value | Usage |
|---|---|---|
--radius | 0.625rem (10px) | Default border radius |
--radius-sm | - | Small radius |
--radius-md | - | Medium radius |
--radius-lg | - | Large radius |
--radius-xl | - | Extra large radius |
Shadows
Tailwind shadow utilities:
shadow-sm- Subtle shadowshadow- Default shadowshadow-md- Medium shadowshadow-lg- Large shadowshadow-xl- Extra large shadow
Componente Catalog
Note: The Componente examples in this catalog are illustrative patterns. For the exact Componente props, types, and Implementación details, always refer to the concrete Componente source files in src/Componentes/ui/*.tsx. Import paths shown represent common patterns; verify actual imports against your barrel exports or individual Componente files.
1. Form Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Button | button.tsx | Primary action button | variant, size, disabled | Form submissions, actions |
| Input | input.tsx | Text input field | type, placeholder, disabled | Text entry |
| InputTextFormField | input-text-form-field.tsx | React Hook Form text input | name, control, label | Form text fields |
| InputNumberFormField | input-number-form-field.tsx | React Hook Form number input | name, control, label | Numeric inputs |
| InputRadio | input-radio.tsx | Radio button input | name, Valor, checked | Single selection |
| Textarea | textarea.tsx | Multi-line text input | rows, placeholder | Long text entry |
| Select | select.tsx | Dropdown select | options, Valor, onChange | Single selection from list |
| SelectMultiple | select-multiple.tsx | Multi-select dropdown | options, Valor, onChange | Multiple selections |
| ComboBox | combo-box.tsx | Searchable select | options, Valor, onSelect | Searchable dropdown |
| Checkbox | checkbox.tsx | Checkbox input | checked, onCheckedChange | Boolean selection |
| Switch | switch.tsx | Toggle switch | checked, onCheckedChange | On/off toggle |
| Calendar | calendar.tsx | Date picker calendar | selected, onSelect | Date selection |
| TimePicker | time-picker.tsx | Time selection | Valor, onChange | Time selection |
| Form | form.tsx | Form wrapper (React Hook Form) | form, onSubmit | Form container |
| Label | label.tsx | Form label | htmlFor | Input labels |
Button Variants (as defined in src/Componentes/ui/button.tsx):
default- Primary orange button with shadowdestructive- Red delete/danger buttonoutline- Outlined button with bordersecondary- Gray secondary buttonghost- Transparent button with hoverlink- Link-styled button with underlineprimary- Primary button (blue/primary color variant)success- Green success buttonwarning- Yellow/orange warning buttonaccesible- Accessible button with auto height
Button Sizes (as defined in src/Componentes/ui/button.tsx):
default- Standard size (h-9 px-4 py-2)sm- Small button (h-8)lg- Large button (h-10)icon- Icon-only button (size-9)
Button Additional Props:
fullWidth- Boolean prop to make button full width
2. Data Display Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Table | table.tsx | Basic table | - | Data tables |
| DataTable | data-table.tsx | Client-side data table | columns, data | Client-side tables |
| DataTableServer | data-table-server.tsx | Server-side data table | columns, data, pagination | Server-side tables |
| DataTablePaginationServer | data-table-pagination-server.tsx | Server pagination controls | pageCount, pageIndex | Pagination |
| Card | card.tsx | Content card | - | Content containers |
| CardInfoEstado | card-info-Estado.tsx | Estado card | Estado, label | Estado display |
| CardInfoDate | card-info-date.tsx | Date card | date, label | Date display |
| CardInfoDescripción | card-info-Descripción.tsx | Descripción card | Description | Text display |
| CardInfoRow | card-info-row.tsx | Key-Valor row | label, Valor | Info rows |
| Badge | badge.tsx | Estado badge | variant | Estado indicators |
| Avatar | avatar.tsx | User avatar | src, fallback | User images |
| Image | image.tsx | Image Componente | src, alt | Images |
| Chart | chart.tsx | Chart wrapper (Recharts) | type, data | Data visualization |
| RatingStars | rating-stars.tsx | Star rating display | rating, max | Rating display |
| Countdown | countdown.tsx | Countdown timer | date | Time countdown |
Badge Variants:
default- Gray badgesuccess- Green success badgewarning- Yellow warning badgedestructive- Red error badgeoutline- Outlined badge
3. Navigation Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Sidebar | sidebar.tsx | Main sidebar | - | App navigation |
| AppSidebar | app-sidebar.tsx | Application sidebar | - | Main sidebar |
| SidebarMenuIcon | sidebar-menu-icon.tsx | Sidebar menu icon | icon | Menu icons |
| SidebarMenuLabel | sidebar-menu-label.tsx | Sidebar menu label | label | Menu labels |
| NavMain | nav-main.tsx | Main navigation | items | Primary nav |
| NavBar | nav-bar.tsx | Top navigation bar | - | Top nav |
| NavUser | nav-user.tsx | User navigation menu | user | User menu |
| Tabs | tabs.tsx | Tab navigation | tabs | Tabbed content |
| Pagination | pagination.tsx | Pagination controls | pageCount, currentPage | Page navigation |
| PaginationCustom | pagination-custom.tsx | Custom pagination | - | Custom pagination |
4. Overlay Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Dialog | dialog.tsx | Modal dialog | open, onOpenChange | Modals |
| Sheet | sheet.tsx | Side sheet/drawer | open, onOpenChange, side | Side panels |
| Popover | popover.tsx | Popover overlay | open, onOpenChange | Contextual overlays |
| Tooltip | tooltip.tsx | Tooltip | content | Hover tooltips |
| Toast | toast.tsx | Toast notification | - | Notifications |
| Toaster | toaster.tsx | Toast container | - | Toast container |
| Sonner | sonner.tsx | Sonner toast (alternative) | - | Alternative toasts |
| ActionDialogGeneric | action-dialog-generic.tsx | Generic action dialog | title, Descripción, onConfirm | Confirmation dialogs |
5. Layout Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Container | container.tsx | Content container | maxWidth | Page containers |
| Title | title.tsx | Page title | children | Page titles |
| Separator | separator.tsx | Visual separator | orientation | Sección dividers |
6. Feedback Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Spinner | spinner.tsx | Loading spinner | size | Loading states |
| Skeleton | skeleton.tsx | Loading skeleton | - | Content placeholders |
| EmptyStateDatatable | empty-state-datatable.tsx | Empty table state | message | Empty tables |
7. Media Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Carousel | carousel.tsx | Image carousel | - | Image galleries |
| CarouselImages | carousel-images.tsx | Image carousel (specific) | images | Image galleries |
8. Utility Componentes
| Component | File | Purpose | Key Props | Usage Example |
|---|---|---|---|---|
| Command | command.tsx | Command palette | - | Command menu |
Componente Usage Patterns
Form Pattern Example
// Example from orders featureimport { useForm } from 'react-hook-form';import { zodResolver } from '@hookform/resolvers/zod';import { Form, InputTextFormField, Button } from '@/components/ui';import { createOrderSchema } from './schema';
const OrderForm = () => { const form = useForm({ resolver: zodResolver(createOrderSchema), defaultValues: { title: '', description: '', priority: 'medium', }, });
const onSubmit = form.handleSubmit((data) => { // Handle form submission console.log(data); });
return ( <Form {...form}> <form onSubmit={onSubmit} className="space-y-4"> <InputTextFormField name="title" control={form.control} label="Order Title" placeholder="Enter order title" /> <InputTextFormField name="description" control={form.control} label="Description" placeholder="Enter description" /> <Button type="submit">Create Order</Button> </form> </Form> );};Data Table Pattern Example
// Example pattern (simplified) - adapt to your specific feature// Real usage: src/features/orders/components/orders-list.tsx (or similar)import { DataTableServer } from '@/components/ui/data-table-server';import { useAssets } from './hooks/use-assets';import { assetsColumns } from './constants/list-assets-columns';
const AssetsList = () => { const { data, isLoading } = useAssets();
return ( <DataTableServer columns={assetsColumns} data={data?.items ?? []} pagination={data?.pagination} isLoading={isLoading} /> );};Note: This is a pattern example. For actual Implementación, see Componente files in feature directories (e.g., src/Funcionalidades/orders/Componentes/, src/Funcionalidades/assets/Componentes/). The DataTableServer Componente is defined in src/Componentes/ui/data-table-server.tsx.
Dialog Pattern Example
import { Dialog, DialogContent, DialogHeader, DialogTitle, Button } from '@/components/ui';
const CreateOrderDialog = ({ open, onOpenChange }: Props) => { return ( <Dialog open={open} onOpenChange={onOpenChange}> <DialogContent className="sm:max-w-[600px]"> <DialogHeader> <DialogTitle>Create New Order</DialogTitle> </DialogHeader> <div className="p-4"> {/* Dialog content */} </div> <div className="flex justify-end gap-2"> <Button variant="outline" onClick={() => onOpenChange(false)}> Cancel </Button> <Button>Create</Button> </div> </DialogContent> </Dialog> );};Card Pattern Example
// Example pattern (simplified)import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';import { CardInfoRow } from '@/components/ui/card-info-row';
const OrderSummaryCard = ({ order }: Props) => { return ( <Card> <CardHeader> <CardTitle>Order Summary</CardTitle> </CardHeader> <CardContent> <div className="space-y-2"> <CardInfoRow label="Order ID" value={order.id} /> <CardInfoRow label="Status" value={order.status} /> <CardInfoRow label="Created" value={order.createdAt} /> </div> </CardContent> </Card> );};Note: Card Componentes are defined in src/Componentes/ui/card.tsx. The CardInfoRow Componente is in src/Componentes/ui/card-info-row.tsx. For real usage examples, see feature Componentes like order or asset Resumen cards.
Button Pattern Examples
import { Button } from '@/components/ui';
// Primary button<Button>Click me</Button>
// Secondary button<Button variant="secondary">Secondary</Button>
// Destructive button<Button variant="destructive">Delete</Button>
// Outlined button<Button variant="outline">Outline</Button>
// Ghost button<Button variant="ghost">Ghost</Button>
// Link button<Button variant="link">Link</Button>
// Small button<Button size="sm">Small</Button>
// Large button<Button size="lg">Large</Button>
// Icon button<Button size="icon"> <IconName /></Button>
// Disabled button<Button disabled>Disabled</Button>
// Loading button<Button disabled> <Spinner className="mr-2" /> Loading...</Button>Styling Approach
Tailwind CSS
The dashboard uses Tailwind CSS as the primary styling solution:
- Utility-First: Compose styles using utility classes
- Responsive: Mobile-first responsive design with breakpoints
- Customizable: Extended with custom colors and design tokens
- Performance: Purges unused CSS in production
CSS Variables
Design tokens are defined as CSS variables in src/index.css:
:root { /* Primary colors */ --primary: hsla(32, 100%, 50%, 1); --primary-foreground: hsla(0, 0%, 100%, 1);
/* Neutral colors */ --neutral-50: hsla(0, 0%, 98%, 1); --neutral-900: hsla(240, 6%, 10%, 1);
/* Border radius */ --radius: 0.625rem;}cn() Utility
The cn() utility function combines Tailwind classes using clsx and tailwind-merge:
import { clsx } from 'clsx';import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}Usage:
import { cn } from '@/lib/utils';
<div className={cn( 'base-class', isActive && 'active-class', className)} />Responsive Design
Tailwind breakpoints (mobile-first):
sm:- 640px and upmd:- 768px and uplg:- 1024px and upxl:- 1280px and up2xl:- 1536px and up
Example:
<div className="w-full sm:w-1/2 lg:w-1/3"> Responsive width</div>Dark Mode Support
Dark mode is supported via CSS variables and the .dark class:
.dark { --primary: hsla(32, 100%, 40%, 1); --background: hsla(240, 10%, 3.9%, 1); /* ... other dark mode colors */}Accessibility
All Componentes are built on Radix UI primitives, ensuring:
WAI-ARIA Compliance
- Proper ARIA attributes
- Semantic HTML
- Role definitions
Keyboard Navigation
- Tab navigation support
- Arrow key navigation for menus
- Enter/Space for activation
- Escape to close dialogs/menus
Screen Reader Support
- Descriptive labels
- ARIA live regions for dynamic content
- Proper heading hierarchy
Focus Management
- Visible focus indicators
- Focus trapping in modals
- Focus restoration on close
ARIA Attributes
aria-labelfor icon buttonsaria-describedbyfor form fieldsaria-expandedfor collapsible contentaria-selectedfor tabs
Customization
Customizing Componentes via Props
Most Componentes accept standard HTML attributes and custom props:
<Button variant="primary" size="lg" className="custom-class" onClick={handleClick}> Click me</Button>Customizing via Tailwind Classes
Use the className prop to add custom Tailwind classes:
<Card className="border-2 border-primary shadow-lg"> Custom styled card</Card>Customizing via CSS Variables
Override design tokens:
:root { --primary: hsla(200, 100%, 50%, 1); /* Change primary to blue */ --radius: 0.25rem; /* Smaller border radius */}Componente Variants (class-variance-authority)
Componentes use cva for variant management:
import { cva } from 'class-variance-authority';
const buttonVariants = cva( 'inline-flex items-center justify-center rounded-md', { variants: { variant: { default: 'bg-primary text-primary-foreground', destructive: 'bg-destructive text-destructive-foreground', }, size: { default: 'h-10 px-4 py-2', sm: 'h-9 px-3', lg: 'h-11 px-8', }, }, defaultVariants: { variant: 'default', size: 'default', }, });Adding New Componentes
1. Copy from shadcn/ui
Visit shadcn/ui and copy the Componente code.
2. Create Componente File
Place in src/Componentes/ui/[Componente-name].tsx:
import * as React from 'react';import { cn } from '@/lib/utils';
export interface MyComponentProps { // Props definition}
export const MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>( ({ className, ...props }, ref) => { return ( <div ref={ref} className={cn('base-classes', className)} {...props} /> ); });
MyComponent.displayName = 'MyComponent';3. Export from Index
If feature-specific, export from Funcionalidades/[feature]/index.ts.
4. Documento in This File
Add the Componente to the appropriate category table above.
Componente Development Guíalines
From AGENTS.md:
Functional Componentes Only
- Use functional Componentes with hooks
- Avoid class Componentes
TypeScript with Explicit Types
- Define prop interfaces
- Use explicit return types
- Avoid
anytypes
Props Interface with JSDoc Comments
/** * Button component for primary actions */export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { /** Visual variant of the button */ variant?: 'default' | 'destructive' | 'outline'; /** Size of the button */ size?: 'default' | 'sm' | 'lg' | 'icon';}Composition Over Prop Drilling
- Use Componente composition
- Avoid excessive prop passing
- Use context for shared state
Keep Componentes Under 300 LOC
- Split large Componentes
- Extract logic to hooks
- Create sub-Componentes
Use Error Boundaries
- Wrap Componentes in error boundaries
- Provide fallback UI
Lazy Load When Appropriate
- Lazy load route Componentes
- Code split heavy Componentes
References:
algesta-dashboard-react/src/Componentes/ui/button.tsxalgesta-dashboard-react/src/Componentes/ui/form.tsxalgesta-dashboard-react/src/Componentes/ui/data-table-server.tsxalgesta-dashboard-react/src/index.cssalgesta-dashboard-react/AGENTS.md- All Componente files in
src/Componentes/ui/