# /frontend — Skill para proyectos frontend Eres un arquitecto frontend experto. Esta skill se activa cuando el usuario pide crear un proyecto frontend, una app con UI, un componente nuevo, o una feature frontend. Tu trabajo es garantizar que TODO el frontend se construya usando el sistema de funciones reutilizables del registry y las mejores practicas actuales. ## Stack - **pnpm** — gestor de paquetes - **React 19** — UI library - **Vite 8** — build tool - **Mantine v9** — component library + styling (props, no CSS manual) - **Phosphor Icons** — `@phosphor-icons/react` - **Recharts** — charts (via `@mantine/charts`) **NO usar:** Tailwind, shadcn, CVA, clsx, cn(), lucide-react, styled-components, emotion, CSS-in-JS runtime. --- ## PASO 1: Consultar el registry (OBLIGATORIO) Antes de escribir una sola linea de codigo, consulta registry.db para saber que componentes, funciones y tipos frontend ya existen: ```bash # Componentes y funciones frontend disponibles sqlite3 registry.db "SELECT id, kind, description FROM functions WHERE lang IN ('ts','typescript') ORDER BY domain, name;" # Tipos frontend disponibles sqlite3 registry.db "SELECT id, algebraic, description FROM types WHERE lang IN ('ts','typescript') ORDER BY domain, name;" # Busqueda FTS5 si buscas algo especifico sqlite3 registry.db "SELECT id, kind, description FROM functions WHERE id IN (SELECT id FROM functions_fts WHERE functions_fts MATCH 'name:chart* OR description:chart*') ORDER BY name;" ``` Tambien lista los archivos reales en disco ya que no todos estan indexados aun: ```bash ls frontend/functions/ui/ # Componentes React ls frontend/functions/core/ # Utilidades TS puras ls frontend/types/ # Tipos ``` **REGLA:** Si un componente ya existe en `frontend/functions/ui/` (alias `@fn_library`), USALO. Nunca recrear lo que ya existe. --- ## PASO 2: Determinar el tipo de trabajo ### A) App nueva en `apps/` Ir a → Seccion SCAFFOLD APP ### B) Componente nuevo para el registry Ir a → Seccion CREAR COMPONENTE ### C) Feature en app existente Ir a → Seccion CREAR FEATURE --- ## SCAFFOLD APP Crear la estructura completa de una app frontend nueva en `apps/{nombre}/frontend/`. ### Estructura obligatoria ``` apps/{nombre}/ frontend/ package.json vite.config.ts tsconfig.json postcss.config.cjs index.html src/ main.tsx # Entry point con MantineProvider App.tsx # Root con Router app.css # Minimal (font-smoothing solo) features/ # Feature-based co-location {feature}/ components/ # Componentes del feature hooks/ # Hooks del feature types.ts # Tipos del feature index.ts # Barrel export publico components/ # Componentes compartidos de esta app (no reutilizables) hooks/ # Hooks compartidos lib/ # Utilidades, API client types/ # Tipos globales de la app ``` ### package.json base ```json { "name": "{nombre}", "private": true, "version": "0.0.1", "type": "module", "scripts": { "dev": "vite --host", "build": "tsc -b && vite build", "preview": "vite preview --host" }, "dependencies": { "@mantine/core": "^9.0.0", "@mantine/hooks": "^9.0.0", "@mantine/notifications": "^9.0.0", "@phosphor-icons/react": "^2.1.10", "react": "^19.2.4", "react-dom": "^19.2.4" }, "devDependencies": { "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.0", "postcss": "^8.5.8", "postcss-preset-mantine": "^1.18.0", "postcss-simple-vars": "^7.0.1", "typescript": "~5.9.3", "vite": "^8.0.0" } } ``` Agregar dependencias extras segun necesidad: - **Charts**: `@mantine/charts`, `recharts` - **Tablas**: `@tanstack/react-table` - **Forms**: `react-hook-form`, `@hookform/resolvers`, `zod` - **Dates**: `@mantine/dates`, `dayjs` - **Router**: `react-router` o `@tanstack/react-router` - **State**: `zustand` (client state), `@tanstack/react-query` (server state) - **Wails**: los hooks de Wails ya estan en `@fn_library` (useWailsQuery, useWailsMutation, useWailsStream, useWailsEvent, WailsProvider) ### vite.config.ts base ```ts import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { resolve } from 'path' export default defineConfig({ plugins: [react()], resolve: { alias: { '@': resolve(__dirname, './src'), '@fn_library': resolve(__dirname, '../../../frontend/functions/ui'), }, dedupe: ['react', 'react-dom'], }, css: { postcss: resolve(__dirname, './postcss.config.cjs'), }, build: { target: 'es2022', rollupOptions: { output: { manualChunks: { 'react-vendor': ['react', 'react-dom'], }, }, }, }, }) ``` ### postcss.config.cjs base ```js module.exports = { plugins: { 'postcss-preset-mantine': {}, 'postcss-simple-vars': { variables: { 'mantine-breakpoint-xs': '36em', 'mantine-breakpoint-sm': '48em', 'mantine-breakpoint-md': '62em', 'mantine-breakpoint-lg': '75em', 'mantine-breakpoint-xl': '88em', }, }, }, }; ``` ### app.css base ```css /* Minimal — Mantine handles all theming via MantineProvider */ html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } ``` ### main.tsx base ```tsx import '@mantine/core/styles.css' import '@mantine/notifications/styles.css' import './app.css' import React from 'react' import ReactDOM from 'react-dom/client' import { MantineProvider, createTheme } from '@mantine/core' import { Notifications } from '@mantine/notifications' import App from './App' const theme = createTheme({ primaryColor: 'blue', defaultRadius: 'md', // Customize colors, fonts, etc. here }) ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` ### Despues del scaffold ```bash cd apps/{nombre}/frontend && pnpm install ``` --- ## CREAR COMPONENTE Para componentes nuevos que van al registry en `frontend/functions/`. ### Reglas de implementacion 1. **Mantine first**: wrappear componentes de Mantine. Solo crear desde cero si Mantine no tiene equivalente. 2. **Styling via props**: usar props de Mantine (`size`, `color`, `variant`, `p`, `m`, `fw`, `gap`, etc.) y el style system. NUNCA clases CSS manuales ni Tailwind. 3. **CSS variables de Mantine**: si necesitas styles inline, usar `var(--mantine-color-*)`, `var(--mantine-spacing-*)`, etc. 4. **Iconos**: usar `@phosphor-icons/react`, no lucide-react ni @tabler/icons-react. 5. **Props tipadas**: usar `React.ComponentPropsWithoutRef<"element">` para HTML props spreading. 6. **Accesibilidad**: - Elementos semanticos: `