Componentes
Base — shadcn
Sección titulada «Base — shadcn»Componentes shadcn instalados en src/components/ui/. Estilo radix-nova, base color neutral, CSS variables activas.
| Componente | Archivo | Uso típico |
|---|---|---|
Button | button.tsx | CTA, acciones primarias/secundarias. Variants: default, outline, ghost, link, destructive |
Card | card.tsx | Contenedor de info (listings, sets, cartas). Header/Content/Footer |
Badge | badge.tsx | Estados (Activo/Pausado), idiomas, condiciones, kind de listing |
Input | input.tsx | Campos de texto, número, email |
Textarea | textarea.tsx | Texto largo (descripción de listing, mensajes en disputas) |
Label | label.tsx | Labels accesibles para inputs |
Checkbox | checkbox.tsx | Filtros (idiomas en /challa), tickboxes en bulk actions |
Dialog | dialog.tsx | Modales (BuyOrderModal, confirmaciones) |
AlertDialog | alert-dialog.tsx | Confirmaciones destructivas (eliminar listing) |
Sheet | sheet.tsx | Drawers laterales (filtros móviles, carrito mobile) |
DropdownMenu | dropdown-menu.tsx | Menús contextuales (perfil, acciones de admin) |
Sonner (Toaster) | sonner.tsx | Toasts. Config: richColors, position="top-center" |
Para agregar un componente shadcn nuevo:
npx shadcn@latest add <componente>. Respeta elcomponents.jsonpara mantener consistencia de estilo.
Librería única: lucide-react. Importar iconos individualmente:
import { ShoppingCart, Heart, MoreHorizontal } from 'lucide-react';- No instalar otras librerías de iconos (Heroicons, Phosphor, etc.).
- No usar emojis en UI core. Aceptable solo en copy de marketing puntual.
- Tamaño default:
size-4(16px) osize-5(20px) en contextos grandes.
Único sistema: Sonner (montado en layout.tsx).
import { toast } from 'sonner';
toast.success('Listing publicado.');toast.error('No pudimos cargar las cartas.');toast.info('Tu sesión expira en 5 minutos.');Reglas:
richColorsestá activo → usarsuccess/error/info/warningpara que aplique el color semántico correcto.- Posición fija: top-center. No cambiar.
- Copy: tono español neutro/chileno (ver Copy y tono).
Componentes propios
Sección titulada «Componentes propios»Categorías principales en src/components/:
Marketplace
Sección titulada «Marketplace»FeaturedListingBlock— bloque destacado en/cards/[id]con el listing de menor precio.SellersList— lista paginada de vendedores con sus precios.RecentSalesCard— últimas ventas para referencia de precio.CardDetailImage— imagen grande de la carta con zoom hover.
Listings
Sección titulada «Listings»MobileSellFab— FAB flotante “Vender” visible en mobile. Montado global enlayout.tsx.
Carrito y órdenes
Sección titulada «Carrito y órdenes»CartAbandonedTracker— track de carritos abandonados (PostHog). Mounted global.BuyOrderModal— modal de compra con resumen + dirección + método de pago.
Catalog
Sección titulada «Catalog»- Componentes de grilla de cartas, filtros de set/rareza, paginación.
ThemeProvider/ThemeScript/ThemeToggle/useTheme— ver Patrones.
JsonLd— wrapper para insertar JSON-LD estructurado.- Helpers en
src/lib/seo/para construir Product, Breadcrumb, etc.
ShareButton— botón compartir con Web Share API + fallback.
Convenciones
Sección titulada «Convenciones»Imports:
import { Button } from '@/components/ui/button';import { FeaturedListingBlock } from '@/components/marketplace/FeaturedListingBlock';Usar alias @/ siempre. Configurado en tsconfig.json.
Naming:
- PascalCase para componentes (
FeaturedListingBlock). - camelCase para hooks (
useTheme,useCart). - kebab-case para archivos de shadcn (
alert-dialog.tsx) — convención propia de shadcn que respetamos. - PascalCase para archivos de componentes propios.
Server vs Client:
- Default: Server Component.
'use client'solo cuando el componente usa estado, efectos, eventos o hooks de cliente.- Patrón SessionProvider + useSession para sesión: leerla en cliente, no en Server Header (ver Patrones).
Algunos componentes tienen test colocado (.test.tsx). No es obligatorio para todo componente, pero sí para lógica con bordes (parseo, formato de fechas, theme switching).
Stack: Vitest + Testing Library. Correr con npm test.