` para elementos interactivos
- - `aria-label` o `aria-labelledby` en todo componente interactivo
+ - `aria-label` en botones de solo icono
- `aria-invalid` + `aria-describedby` en inputs con error
- - `role="status"` para loading states
- Focus management en modales/popovers
7. **Discriminated unions** cuando las props cambian segun variante:
@@ -311,54 +262,19 @@ type Props = { size?: 'sm' | 'md' | 'lg'; children: React.ReactNode } & (
### Patron de archivo .tsx
```tsx
-import * as React from 'react'
-import { cva, type VariantProps } from 'class-variance-authority'
-import { cn } from '../core/cn'
+import { Select, type SelectProps } from '@mantine/core'
-const componentVariants = cva(
- 'base-classes-here', // clases base
- {
- variants: {
- variant: {
- default: 'classes...',
- secondary: 'classes...',
- },
- size: {
- sm: 'classes...',
- md: 'classes...',
- lg: 'classes...',
- },
- },
- defaultVariants: {
- variant: 'default',
- size: 'md',
- },
- }
-)
-
-interface ComponentProps
- extends React.ComponentPropsWithoutRef<'div'>,
- VariantProps
{
- // props adicionales con JSDoc
- /** Descripcion de la prop */
+// Re-export con defaults o logica adicional si necesario
+interface MySelectProps extends Omit {
customProp?: string
}
-const Component = React.forwardRef(
- ({ className, variant, size, customProp, ...props }, ref) => {
- return (
-
- )
- }
-)
-Component.displayName = 'Component'
+function MySelect({ customProp, ...props }: MySelectProps) {
+ return
+}
-export { Component, componentVariants }
-export type { ComponentProps }
+export { MySelect }
+export type { MySelectProps }
```
### Patron de archivo .md
@@ -376,12 +292,12 @@ purity: impure
signature: "ComponentName(props: ComponentProps): JSX.Element"
description: "Descripcion concisa de que hace el componente"
tags: [component, ui, ...]
-uses_functions: [cn_ts_core]
+uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
-imports: ["@base-ui/react", "class-variance-authority"]
+imports: ["@mantine/core"]
tested: false
tests: []
test_file_path: ""
@@ -391,14 +307,10 @@ props:
type: "'default' | 'secondary'"
required: false
description: "Estilo visual"
- - name: className
- type: "string"
- required: false
- description: "Clases CSS adicionales"
emits: []
has_state: false
framework: react
-variant: [default, secondary]
+variant: [default]
---
## Ejemplo
@@ -493,7 +405,7 @@ function useFeatureData() {
```tsx
import { lazy, Suspense } from 'react'
-import { Skeleton } from '@fn_library'
+import { Skeleton } from '@mantine/core'
const FeaturePage = lazy(() => import('./features/feature/components/FeaturePage'))
@@ -501,7 +413,7 @@ function AppRoutes() {
return (
}>
+ }>
} />
@@ -517,14 +429,19 @@ function AppRoutes() {
Antes de dar por terminado cualquier trabajo frontend, verificar:
### Colores y estilos
-- [ ] CERO colores hardcodeados (no hex, no rgb, no oklch inline en componentes)
-- [ ] Solo clases Tailwind mapeadas a CSS variables: `bg-primary`, `text-foreground`, `border-border`, etc.
-- [ ] `cn()` usado para merge de clases en todo componente
-- [ ] CVA usado para variantes (no condicionales manuales con ternarios)
+- [ ] CERO colores hardcodeados en componentes (no hex, no rgb inline)
+- [ ] Styling via props de Mantine (`size`, `color`, `variant`, `p`, `m`, `fw`, `gap`, etc.)
+- [ ] Si se necesitan styles inline, usar CSS variables de Mantine (`var(--mantine-color-*)`)
+- [ ] NO clases CSS manuales, NO Tailwind, NO cn(), NO CVA
### Componentes del registry
- [ ] Verificado que no se esta recreando algo que ya existe en `@fn_library` (`frontend/functions/ui/`)
-- [ ] Componentes de `@fn_library` usados donde aplica: Alert, Badge, Button, Card, Dialog, Input, Label, Select, SimpleSelect, Skeleton, Sparkline, Tabs, Tooltip, FormField, PageHeader, ProgressBar, KPICard, ThemeProvider, DashboardLayout, DataTable, charts (AreaChart, BarChart, LineChart, PieChart, ChartContainer), hooks Wails (useWailsQuery, useWailsMutation, useWailsStream, useWailsEvent)
+- [ ] Componentes de `@fn_library` usados donde aplica: Card, Select, SimpleSelect, KPICard, Sparkline, DashboardLayout, DataTable, charts, hooks Wails
+- [ ] Componentes de Mantine usados directamente donde `@fn_library` no tiene wrapper: Button, TextInput, Table, Alert, Badge, Skeleton, Tabs, Tooltip, Group, Stack, Grid, Box, Paper, AppShell, Container
+
+### Iconos
+- [ ] Usando `@phosphor-icons/react` para iconos
+- [ ] NO lucide-react, NO @tabler/icons-react
### TypeScript
- [ ] Props interfaces con `React.ComponentPropsWithoutRef` para HTML spreading
@@ -533,7 +450,7 @@ Antes de dar por terminado cualquier trabajo frontend, verificar:
- [ ] No `any` — usar `unknown` + type guards si es necesario
### Accesibilidad
-- [ ] Elementos semanticos (button, a, dialog — no div onClick)
+- [ ] Elementos semanticos (button, a — no div onClick)
- [ ] `aria-label` en botones de solo icono
- [ ] `aria-invalid` + `aria-describedby` en inputs con validacion
- [ ] Focus trap en modales y popovers
@@ -555,15 +472,15 @@ Antes de dar por terminado cualquier trabajo frontend, verificar:
## ANTI-PATRONES (nunca hacer)
-1. **``** → usar `