create-lexy 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +7 -2
  2. package/assets/fonts/{OFL-NotoSans.txt → LICENSE-Geist.txt} +4 -5
  3. package/assets/fonts/geist-mono-variable-italic.woff2 +0 -0
  4. package/assets/fonts/geist-mono-variable.woff2 +0 -0
  5. package/assets/fonts/geist-sans-variable-italic.woff2 +0 -0
  6. package/assets/fonts/geist-sans-variable.woff2 +0 -0
  7. package/assets/r/accordion.json +3 -3
  8. package/assets/r/alert-dialog.json +3 -3
  9. package/assets/r/app-accordion.json +1 -1
  10. package/assets/r/app-dialog.json +3 -3
  11. package/assets/r/app-header-bar.json +2 -2
  12. package/assets/r/app-sidebar.json +2 -2
  13. package/assets/r/avatar.json +3 -3
  14. package/assets/r/badge.json +3 -3
  15. package/assets/r/brand-background.json +1 -1
  16. package/assets/r/breadcrumb.json +3 -3
  17. package/assets/r/button-group.json +3 -3
  18. package/assets/r/button.json +3 -3
  19. package/assets/r/calendar.json +2 -2
  20. package/assets/r/card.json +3 -3
  21. package/assets/r/chart.json +2 -2
  22. package/assets/r/checkbox.json +2 -2
  23. package/assets/r/combobox.json +3 -3
  24. package/assets/r/command.json +3 -3
  25. package/assets/r/confirmacion.json +1 -1
  26. package/assets/r/counter-badge.json +3 -3
  27. package/assets/r/crm-desk.json +1 -1
  28. package/assets/r/crm-detalle-caso.json +5 -5
  29. package/assets/r/date-picker.json +1 -1
  30. package/assets/r/dialog.json +3 -3
  31. package/assets/r/dropdown-menu.json +3 -3
  32. package/assets/r/empty.json +2 -2
  33. package/assets/r/feature-card.json +3 -3
  34. package/assets/r/form.json +3 -3
  35. package/assets/r/header-bar.json +2 -2
  36. package/assets/r/input.json +3 -3
  37. package/assets/r/intake-wizard.json +1 -1
  38. package/assets/r/label.json +3 -3
  39. package/assets/r/logo.json +2 -2
  40. package/assets/r/menubar.json +3 -3
  41. package/assets/r/navigation-menu.json +3 -3
  42. package/assets/r/pagination.json +2 -2
  43. package/assets/r/popover.json +3 -3
  44. package/assets/r/profile-card.json +3 -3
  45. package/assets/r/progress.json +2 -2
  46. package/assets/r/radio-group.json +2 -2
  47. package/assets/r/registry.json +47 -47
  48. package/assets/r/scroll-area.json +2 -2
  49. package/assets/r/searchbox.json +3 -3
  50. package/assets/r/select.json +3 -3
  51. package/assets/r/separator.json +2 -2
  52. package/assets/r/sheet.json +2 -2
  53. package/assets/r/sidebar.json +3 -3
  54. package/assets/r/skeleton.json +2 -2
  55. package/assets/r/slider.json +3 -3
  56. package/assets/r/snippet.json +3 -3
  57. package/assets/r/spinner.json +2 -2
  58. package/assets/r/status-dot.json +3 -3
  59. package/assets/r/switch.json +3 -3
  60. package/assets/r/table.json +3 -3
  61. package/assets/r/tabs.json +3 -3
  62. package/assets/r/tag.json +3 -3
  63. package/assets/r/textarea.json +3 -3
  64. package/assets/r/toaster.json +3 -3
  65. package/assets/r/tooltip.json +3 -3
  66. package/assets/r/tree.json +3 -3
  67. package/assets/registry-version +1 -1
  68. package/assets/theme/lexy-theme.css +562 -112
  69. package/dist/index.js +590 -276
  70. package/package.json +4 -2
  71. package/templates/.claude/skills/lexy-design/SKILL.md +189 -0
  72. package/templates/.claude/skills/lexy-dev/SKILL.md +168 -0
  73. package/templates/.claude/skills/lexy-mock-data/SKILL.md +50 -0
  74. package/templates/.github/copilot-instructions.md +50 -0
  75. package/templates/.mcp.json +8 -0
  76. package/templates/AGENTS.md +243 -0
  77. package/templates/CLAUDE.md +61 -0
  78. package/templates/ai/IMPLEMENTATION-PROTOCOL.md +148 -0
  79. package/templates/ai/PRODUCTION-CLEANUP.md +17 -0
  80. package/templates/ai/PROJECT-CONTEXT.md +65 -0
  81. package/templates/ai/README.md +19 -0
  82. package/templates/ai/TECHNICAL-USAGE.md +220 -0
  83. package/templates/ai/pautas/arquitectura-informacion-ux.md +243 -0
  84. package/templates/ai/pautas/buenas-practicas.md +236 -0
  85. package/templates/ai/pautas/calidad-industria.md +109 -0
  86. package/templates/ai/pautas/diseno-cliente.md +136 -0
  87. package/templates/ai/pautas/diseno-crm-lexy.md +109 -0
  88. package/templates/ai/pautas/patrones-de-codigo.md +234 -0
  89. package/templates/ai/pautas/recetas-layout.md +419 -0
  90. package/templates/ai/pautas/sistema-visual.md +197 -0
  91. package/templates/ai/pautas/ux-writing.md +214 -0
  92. package/templates/scripts/check-geometry.mjs +139 -0
  93. package/assets/fonts/noto-sans-latin.woff2 +0 -0
@@ -3,7 +3,7 @@
3
3
  "name": "label",
4
4
  "type": "registry:ui",
5
5
  "title": "Label",
6
- "description": "Etiqueta para campos de formulario. Incluye indicador de requerido. El componente vive en tu proyecto: instálalo con `create-lexy add label` y edítalo con libertad.",
6
+ "description": "Etiqueta para campos de formulario. Incluye indicador de requerido.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-label",
9
9
  "class-variance-authority"
@@ -14,13 +14,13 @@
14
14
  "path": "components/base/Label.tsx",
15
15
  "type": "registry:ui",
16
16
  "target": "components/base/Label.tsx",
17
- "content": "import * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants> & {\n required?: boolean;\n }\n>(({ className, required, children, ...props }, ref) => (\n <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props}>\n {children}\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-destructive\">\n *\n </span>\n )}\n </LabelPrimitive.Root>\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label, labelVariants };\n"
17
+ "content": "import * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst labelVariants = cva(\n \"type-action-label text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants> & {\n required?: boolean;\n }\n>(({ className, required, children, ...props }, ref) => (\n <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props}>\n {children}\n {required && (\n <span aria-hidden=\"true\" className=\"ml-0.5 text-destructive\">\n *\n </span>\n )}\n </LabelPrimitive.Root>\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label, labelVariants };\n"
18
18
  },
19
19
  {
20
20
  "path": "components/base/Label.md",
21
21
  "type": "registry:file",
22
22
  "target": "components/base/Label.md",
23
- "content": "# Label — guía de uso\n\nEtiqueta para campos de formulario. Incluye indicador de requerido. El componente vive en tu proyecto: instálalo con `create-lexy add label` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara nombrar todo campo de formulario, siempre visible — el placeholder desaparece al escribir y la memoria de la persona no es parte del sistema. Incluye indicador de requerido cuando aplica.\n\n## Composición\n\nUna sola pieza (`Label`) asociada al control por `htmlFor`/`id`. En formularios validados la pone `FormLabel`, que hereda el estado de error.\n\n## Uso básico\n\n```tsx\n<Label />\n```\n\n## Reglas\n\n- Usa Label según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Label } from \"@/components/base/Label\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Label desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
+ "content": "# Label\nEtiqueta para campos de formulario. Incluye indicador de requerido.\n\n## Cuándo usarlo\n\nPara nombrar todo campo de formulario, siempre visible — el placeholder desaparece al escribir y la memoria de la persona no es parte del sistema. Incluye indicador de requerido cuando aplica.\n\n## Composición\n\nUna sola pieza (`Label`) asociada al control por `htmlFor`/`id`. En formularios validados la pone `FormLabel`, que hereda el estado de error.\n\n## Uso básico\n\n```tsx\n<Label />\n```\n\n## Reglas\n\n- Usa Label según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Label } from \"@/components/base/Label\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Label desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
24
24
  }
25
25
  ]
26
26
  }
@@ -3,7 +3,7 @@
3
3
  "name": "logo",
4
4
  "type": "registry:ui",
5
5
  "title": "Logo",
6
- "description": "Logo de Lexy. Para marca del producto. El componente vive en tu proyecto: instálalo con `create-lexy add logo` y edítalo con libertad.",
6
+ "description": "Logo de Lexy. Para marca del producto.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [],
9
9
  "files": [
@@ -17,7 +17,7 @@
17
17
  "path": "components/base/Logo.md",
18
18
  "type": "registry:file",
19
19
  "target": "components/base/Logo.md",
20
- "content": "# Logo — guía de uso\n\nLogo de Lexy. Para marca del producto. El componente vive en tu proyecto: instálalo con `create-lexy add logo` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara la marca del producto en headers, sidebars, logins y documentos. Siempre desde el componente — nunca un PNG suelto ni un texto que lo imite.\n\n## Composición\n\nUna sola pieza (`Logo`) con layouts horizontal e isotipo; el tamaño se ajusta con clases de altura.\n\n## Uso básico\n\n```tsx\n<Logo />\n```\n\n## Reglas\n\n- Usa Logo según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Logo } from \"@/components/base/Logo\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Logo desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
20
+ "content": "# Logo\nLogo de Lexy. Para marca del producto.\n\n## Cuándo usarlo\n\nPara la marca del producto en headers, sidebars, logins y documentos. Siempre desde el componente — nunca un PNG suelto ni un texto que lo imite.\n\n## Composición\n\nUna sola pieza (`Logo`) con layouts horizontal e isotipo; el tamaño se ajusta con clases de altura.\n\n## Uso básico\n\n```tsx\n<Logo />\n```\n\n## Reglas\n\n- Usa Logo según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Logo } from \"@/components/base/Logo\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Logo desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
21
21
  },
22
22
  {
23
23
  "path": "components/base/assets/logo/lexy-dark-horizontal-slogan.svg",
@@ -3,7 +3,7 @@
3
3
  "name": "menubar",
4
4
  "type": "registry:ui",
5
5
  "title": "Menubar",
6
- "description": "Barra de menús horizontal. Para navegación de aplicación. El componente vive en tu proyecto: instálalo con `create-lexy add menubar` y edítalo con libertad.",
6
+ "description": "Barra de menús horizontal. Para navegación de aplicación.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-menubar"
9
9
  ],
@@ -13,13 +13,13 @@
13
13
  "path": "components/base/Menubar.tsx",
14
14
  "type": "registry:ui",
15
15
  "target": "components/base/Menubar.tsx",
16
- "content": "import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst MenubarMenu = MenubarPrimitive.Menu;\nconst MenubarGroup = MenubarPrimitive.Group;\nconst MenubarPortal = MenubarPrimitive.Portal;\nconst MenubarSub = MenubarPrimitive.Sub;\nconst MenubarRadioGroup = MenubarPrimitive.RadioGroup;\n\nconst ChevronRightIcon = () => (\n <svg\n className=\"ml-auto h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nconst CheckIcon = () => (\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n);\n\nconst DotIcon = () => (\n <svg className=\"h-2 w-2 fill-current\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"12\" />\n </svg>\n);\n\nconst Menubar = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Root\n ref={ref}\n className={cn(\n \"flex h-10 items-center gap-1 rounded border border-border bg-background p-1\",\n className,\n )}\n {...props}\n />\n));\nMenubar.displayName = MenubarPrimitive.Root.displayName;\n\nconst MenubarTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer select-none items-center rounded px-3 py-1.5 text-sm font-medium text-foreground outline-none focus:bg-primary/15 focus:text-primary data-[state=open]:bg-primary/15 data-[state=open]:text-primary\",\n className,\n )}\n {...props}\n />\n));\nMenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nconst MenubarSubTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <MenubarPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer select-none items-center rounded px-2 py-1.5 text-sm outline-none focus:bg-primary/15 focus:text-primary data-[state=open]:bg-primary/15 data-[state=open]:text-primary\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon />\n </MenubarPrimitive.SubTrigger>\n));\nMenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;\n\nconst MenubarSubContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-32 overflow-hidden rounded border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n));\nMenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;\n\nconst MenubarContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>\n>(({ className, align = \"start\", alignOffset = -4, sideOffset = 8, ...props }, ref) => (\n <MenubarPortal>\n <MenubarPrimitive.Content\n ref={ref}\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-48 overflow-hidden rounded border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </MenubarPortal>\n));\nMenubarContent.displayName = MenubarPrimitive.Content.displayName;\n\nconst MenubarItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded px-2 py-1.5 text-sm outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nMenubarItem.displayName = MenubarPrimitive.Item.displayName;\n\nconst MenubarCheckboxItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <MenubarPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n));\nMenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;\n\nconst MenubarRadioItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <MenubarPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <DotIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n));\nMenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;\n\nconst MenubarLabel = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 text-sm font-semibold text-foreground\", inset && \"pl-8\", className)}\n {...props}\n />\n));\nMenubarLabel.displayName = MenubarPrimitive.Label.displayName;\n\nconst MenubarSeparator = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n));\nMenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;\n\nconst MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (\n <span\n className={cn(\"ml-auto text-xs tracking-widest text-muted-foreground\", className)}\n {...props}\n />\n);\nMenubarShortcut.displayName = \"MenubarShortcut\";\n\nexport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarLabel,\n MenubarMenu,\n MenubarPortal,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n};\n"
16
+ "content": "import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst MenubarMenu = MenubarPrimitive.Menu;\nconst MenubarGroup = MenubarPrimitive.Group;\nconst MenubarPortal = MenubarPrimitive.Portal;\nconst MenubarSub = MenubarPrimitive.Sub;\nconst MenubarRadioGroup = MenubarPrimitive.RadioGroup;\n\nconst ChevronRightIcon = () => (\n <svg\n className=\"ml-auto size-(--icon-size-inline)\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n);\n\nconst CheckIcon = () => (\n <svg\n className=\"size-(--icon-size-inline)\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n);\n\nconst DotIcon = () => (\n <svg className=\"h-2 w-2 fill-current\" viewBox=\"0 0 24 24\">\n <circle cx=\"12\" cy=\"12\" r=\"12\" />\n </svg>\n);\n\nconst Menubar = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Root\n ref={ref}\n className={cn(\n \"flex h-10 items-center gap-1 rounded-md border border-border bg-background p-1\",\n className,\n )}\n {...props}\n />\n));\nMenubar.displayName = MenubarPrimitive.Root.displayName;\n\nconst MenubarTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Trigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer select-none items-center rounded-menu-item px-3 py-1.5 type-action-label text-foreground outline-none focus:bg-primary/15 focus:text-primary data-[state=open]:bg-primary/15 data-[state=open]:text-primary\",\n className,\n )}\n {...props}\n />\n));\nMenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nconst MenubarSubTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean;\n }\n>(({ className, inset, children, ...props }, ref) => (\n <MenubarPrimitive.SubTrigger\n ref={ref}\n className={cn(\n \"flex cursor-pointer select-none items-center rounded-menu-item px-2 py-1.5 type-supporting outline-none focus:bg-primary/15 focus:text-primary data-[state=open]:bg-primary/15 data-[state=open]:text-primary\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon />\n </MenubarPrimitive.SubTrigger>\n));\nMenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;\n\nconst MenubarSubContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.SubContent\n ref={ref}\n className={cn(\n \"z-50 min-w-32 overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n));\nMenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;\n\nconst MenubarContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>\n>(({ className, align = \"start\", alignOffset = -4, sideOffset = 8, ...props }, ref) => (\n <MenubarPortal>\n <MenubarPrimitive.Content\n ref={ref}\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 min-w-48 overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-overlay data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </MenubarPortal>\n));\nMenubarContent.displayName = MenubarPrimitive.Content.displayName;\n\nconst MenubarItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Item\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-menu-item px-2 py-1.5 type-supporting outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n inset && \"pl-8\",\n className,\n )}\n {...props}\n />\n));\nMenubarItem.displayName = MenubarPrimitive.Item.displayName;\n\nconst MenubarCheckboxItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <MenubarPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-menu-item py-1.5 pl-8 pr-2 type-supporting outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n));\nMenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;\n\nconst MenubarRadioItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <MenubarPrimitive.RadioItem\n ref={ref}\n className={cn(\n \"relative flex cursor-pointer select-none items-center rounded-menu-item py-1.5 pl-8 pr-2 type-supporting outline-none focus:bg-primary/15 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <DotIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n));\nMenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;\n\nconst MenubarLabel = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {\n inset?: boolean;\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Label\n ref={ref}\n className={cn(\"px-2 py-1.5 type-supporting font-semibold text-foreground\", inset && \"pl-8\", className)}\n {...props}\n />\n));\nMenubarLabel.displayName = MenubarPrimitive.Label.displayName;\n\nconst MenubarSeparator = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n));\nMenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;\n\nconst MenubarShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (\n <span\n className={cn(\"ml-auto type-meta tracking-widest text-muted-foreground\", className)}\n {...props}\n />\n);\nMenubarShortcut.displayName = \"MenubarShortcut\";\n\nexport {\n Menubar,\n MenubarCheckboxItem,\n MenubarContent,\n MenubarGroup,\n MenubarItem,\n MenubarLabel,\n MenubarMenu,\n MenubarPortal,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSeparator,\n MenubarShortcut,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarTrigger,\n};\n"
17
17
  },
18
18
  {
19
19
  "path": "components/base/Menubar.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Menubar.md",
22
- "content": "# Menubar — guía de uso\n\nBarra de menús horizontal. Para navegación de aplicación. El componente vive en tu proyecto: instálalo con `create-lexy add menubar` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara barras de menús estilo aplicación de escritorio: Archivo, Edición, Ver — comandos agrupados con atajos. En productos web Lexy es raro: para navegación de sitio usa `NavigationMenu`; para acciones contextuales, `DropdownMenu`.\n\n## Composición\n\n`Menubar` contiene `MenubarMenu`s, cada uno con `MenubarTrigger` y `MenubarContent` (items, checkboxes, radios, submenús y `MenubarShortcut`).\n\n## Uso básico\n\n```tsx\n<Menubar />\n```\n\n## Reglas\n\n- Usa Menubar según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Menubar } from \"@/components/base/Menubar\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Menubar desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Menubar\nBarra de menús horizontal. Para navegación de aplicación.\n\n## Cuándo usarlo\n\nPara barras de menús estilo aplicación de escritorio: Archivo, Edición, Ver — comandos agrupados con atajos. En productos web Lexy es raro: para navegación de sitio usa `NavigationMenu`; para acciones contextuales, `DropdownMenu`.\n\n## Composición\n\n`Menubar` contiene `MenubarMenu`s, cada uno con `MenubarTrigger` y `MenubarContent` (items, checkboxes, radios, submenús y `MenubarShortcut`).\n\n## Uso básico\n\n```tsx\n<Menubar />\n```\n\n## Reglas\n\n- Usa Menubar según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Menubar } from \"@/components/base/Menubar\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Menubar desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -3,7 +3,7 @@
3
3
  "name": "navigation-menu",
4
4
  "type": "registry:ui",
5
5
  "title": "NavigationMenu",
6
- "description": "Menú de navegación con dropdowns. Para sitios web. El componente vive en tu proyecto: instálalo con `create-lexy add navigation-menu` y edítalo con libertad.",
6
+ "description": "Menú de navegación con dropdowns. Para sitios web.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-navigation-menu",
9
9
  "class-variance-authority"
@@ -14,13 +14,13 @@
14
14
  "path": "components/base/NavigationMenu.tsx",
15
15
  "type": "registry:ui",
16
16
  "target": "components/base/NavigationMenu.tsx",
17
- "content": "import * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport { cva } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst NavigationMenu = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n <NavigationMenuPrimitive.Root\n ref={ref}\n className={cn(\"relative z-10 flex max-w-max flex-1 items-center justify-center\", className)}\n {...props}\n >\n {children}\n <NavigationMenuViewport />\n </NavigationMenuPrimitive.Root>\n));\nNavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;\n\nconst NavigationMenuList = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.List\n ref={ref}\n className={cn(\"group flex flex-1 list-none items-center justify-center gap-1\", className)}\n {...props}\n />\n));\nNavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;\n\nconst NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nconst navigationMenuTriggerStyle = cva(\n \"group inline-flex h-10 w-max cursor-pointer items-center justify-center rounded bg-background px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-primary/15 hover:text-primary focus:bg-primary/15 focus:text-primary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-secondary data-[state=open]:bg-secondary\",\n);\n\nconst NavigationMenuTrigger = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, onPointerMove, onPointerLeave, ...props }, ref) => (\n <NavigationMenuPrimitive.Trigger\n ref={ref}\n className={cn(navigationMenuTriggerStyle(), \"group\", className)}\n // Desactiva la apertura por hover para evitar el conflicto hover/click de\n // Radix (el menú se cerraba al reabrirlo tras un click). Queda controlado\n // por click y teclado. Radix omite su handler si el evento está prevenido.\n onPointerMove={(event) => {\n event.preventDefault();\n onPointerMove?.(event);\n }}\n onPointerLeave={(event) => {\n event.preventDefault();\n onPointerLeave?.(event);\n }}\n {...props}\n >\n {children}{\" \"}\n <svg\n className=\"relative top-px ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </NavigationMenuPrimitive.Trigger>\n));\nNavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;\n\nconst NavigationMenuContent = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.Content\n ref={ref}\n className={cn(\n \"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out md:absolute md:w-auto\",\n className,\n )}\n {...props}\n />\n));\nNavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;\n\nconst NavigationMenuLink = NavigationMenuPrimitive.Link;\n\nconst NavigationMenuViewport = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => (\n <div className={cn(\"absolute left-0 top-full flex justify-center\")}>\n <NavigationMenuPrimitive.Viewport\n ref={ref}\n className={cn(\n \"origin-top-center relative mt-2 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]\",\n className,\n )}\n {...props}\n />\n </div>\n));\nNavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;\n\nconst NavigationMenuIndicator = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.Indicator\n ref={ref}\n className={cn(\n \"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in\",\n className,\n )}\n {...props}\n >\n <div className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl bg-border shadow-md\" />\n </NavigationMenuPrimitive.Indicator>\n));\nNavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n NavigationMenuViewport,\n};\n"
17
+ "content": "import * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport { cva } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst NavigationMenu = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n <NavigationMenuPrimitive.Root\n ref={ref}\n className={cn(\"relative z-10 flex max-w-max flex-1 items-center justify-center\", className)}\n {...props}\n >\n {children}\n <NavigationMenuViewport />\n </NavigationMenuPrimitive.Root>\n));\nNavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;\n\nconst NavigationMenuList = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.List\n ref={ref}\n className={cn(\"group flex flex-1 list-none items-center justify-center gap-1\", className)}\n {...props}\n />\n));\nNavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;\n\nconst NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nconst navigationMenuTriggerStyle = cva(\n \"group inline-flex h-10 w-max cursor-pointer items-center justify-center rounded-nav-item bg-background px-4 py-2 type-action-label text-foreground transition-colors hover:bg-primary/15 hover:text-primary focus:bg-primary/15 focus:text-primary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-secondary data-[state=open]:bg-secondary\",\n);\n\nconst NavigationMenuTrigger = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, onPointerMove, onPointerLeave, ...props }, ref) => (\n <NavigationMenuPrimitive.Trigger\n ref={ref}\n className={cn(navigationMenuTriggerStyle(), \"group\", className)}\n // Desactiva la apertura por hover para evitar el conflicto hover/click de\n // Radix (el menú se cerraba al reabrirlo tras un click). Queda controlado\n // por click y teclado. Radix omite su handler si el evento está prevenido.\n onPointerMove={(event) => {\n event.preventDefault();\n onPointerMove?.(event);\n }}\n onPointerLeave={(event) => {\n event.preventDefault();\n onPointerLeave?.(event);\n }}\n {...props}\n >\n {children}{\" \"}\n <svg\n className=\"relative top-px ml-1 h-3 w-3 transition duration-[var(--duration-normal)] ease-[var(--ease-standard)] motion-reduce:transition-none group-data-[state=open]:rotate-180\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n </NavigationMenuPrimitive.Trigger>\n));\nNavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;\n\nconst NavigationMenuContent = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.Content\n ref={ref}\n className={cn(\n \"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out md:absolute md:w-auto\",\n className,\n )}\n {...props}\n />\n));\nNavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;\n\nconst NavigationMenuLink = NavigationMenuPrimitive.Link;\n\nconst NavigationMenuViewport = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => (\n <div className={cn(\"absolute left-0 top-full flex justify-center\")}>\n <NavigationMenuPrimitive.Viewport\n ref={ref}\n className={cn(\n \"origin-top-center relative mt-2 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]\",\n className,\n )}\n {...props}\n />\n </div>\n));\nNavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;\n\nconst NavigationMenuIndicator = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.Indicator\n ref={ref}\n className={cn(\n \"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in\",\n className,\n )}\n {...props}\n >\n <div className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl bg-border shadow-overlay\" />\n </NavigationMenuPrimitive.Indicator>\n));\nNavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;\n\nexport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuIndicator,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n navigationMenuTriggerStyle,\n NavigationMenuViewport,\n};\n"
18
18
  },
19
19
  {
20
20
  "path": "components/base/NavigationMenu.md",
21
21
  "type": "registry:file",
22
22
  "target": "components/base/NavigationMenu.md",
23
- "content": "# NavigationMenu — guía de uso\n\nMenú de navegación con dropdowns. Para sitios web. El componente vive en tu proyecto: instálalo con `create-lexy add navigation-menu` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara navegación de sitio con paneles desplegables ricos: secciones con descripciones y listas de enlaces agrupadas. Es de mundo web/marketing; dentro de una app interna la sidebar ordena mejor.\n\n## Composición\n\n`NavigationMenu` > `NavigationMenuList` > `NavigationMenuItem`s, cada uno con `NavigationMenuTrigger` + `NavigationMenuContent` (o `NavigationMenuLink` directo para enlaces simples).\n\n## Uso básico\n\n```tsx\n<NavigationMenu />\n```\n\n## Reglas\n\n- Usa NavigationMenu según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { NavigationMenu } from \"@/components/base/NavigationMenu\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa NavigationMenu desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
+ "content": "# NavigationMenu\nMenú de navegación con dropdowns. Para sitios web.\n\n## Cuándo usarlo\n\nPara navegación de sitio con paneles desplegables ricos: secciones con descripciones y listas de enlaces agrupadas. Es de mundo web/marketing; dentro de una app interna la sidebar ordena mejor.\n\n## Composición\n\n`NavigationMenu` > `NavigationMenuList` > `NavigationMenuItem`s, cada uno con `NavigationMenuTrigger` + `NavigationMenuContent` (o `NavigationMenuLink` directo para enlaces simples).\n\n## Uso básico\n\n```tsx\n<NavigationMenu />\n```\n\n## Reglas\n\n- Usa NavigationMenu según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { NavigationMenu } from \"@/components/base/NavigationMenu\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa NavigationMenu desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
24
24
  }
25
25
  ]
26
26
  }
@@ -16,13 +16,13 @@
16
16
  "path": "components/base/Pagination.tsx",
17
17
  "type": "registry:ui",
18
18
  "target": "components/base/Pagination.tsx",
19
- "content": "import { type VariantProps } from \"class-variance-authority\";\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nimport { buttonVariants } from \"./Button\";\n\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationContent({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<VariantProps<typeof buttonVariants>, \"size\"> &\n Omit<React.ComponentProps<\"a\">, \"size\">;\n\nfunction PaginationLink({ className, isActive, size = \"icon\", ...props }: PaginationLinkProps) {\n return (\n // eslint-disable-next-line jsx-a11y/anchor-has-content -- el contenido llega por {...props} (componente genérico de enlace)\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n \"cursor-pointer\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction PaginationPrevious({\n className,\n text = \"Anterior\",\n ...props\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\n return (\n <PaginationLink\n aria-label=\"Ir a la página anterior\"\n size=\"default\"\n className={cn(\"pl-2!\", className)}\n {...props}\n >\n <ChevronLeftIcon data-icon=\"inline-start\" className=\"cn-rtl-flip\" />\n <span className=\"hidden sm:block\">{text}</span>\n </PaginationLink>\n );\n}\n\nfunction PaginationNext({\n className,\n text = \"Siguiente\",\n ...props\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\n return (\n <PaginationLink\n aria-label=\"Ir a la página siguiente\"\n size=\"default\"\n className={cn(\"pr-2!\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">{text}</span>\n <ChevronRightIcon data-icon=\"inline-end\" className=\"cn-rtl-flip\" />\n </PaginationLink>\n );\n}\n\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\n \"flex size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <MoreHorizontalIcon />\n <span className=\"sr-only\">Más páginas</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n};\n"
19
+ "content": "import { type VariantProps } from \"class-variance-authority\";\nimport { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nimport { buttonVariants } from \"./Button\";\n\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n className={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationContent({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"pagination-content\"\n className={cn(\"flex items-center gap-1\", className)}\n {...props}\n />\n );\n}\n\nfunction PaginationItem({ ...props }: React.ComponentProps<\"li\">) {\n return <li data-slot=\"pagination-item\" {...props} />;\n}\n\ntype PaginationLinkProps = {\n isActive?: boolean;\n} & Pick<VariantProps<typeof buttonVariants>, \"size\"> &\n Omit<React.ComponentProps<\"a\">, \"size\">;\n\nfunction PaginationLink({ className, isActive, size = \"icon\", ...props }: PaginationLinkProps) {\n return (\n // eslint-disable-next-line jsx-a11y/anchor-has-content -- el contenido llega por {...props} (componente genérico de enlace)\n <a\n aria-current={isActive ? \"page\" : undefined}\n data-slot=\"pagination-link\"\n data-active={isActive}\n className={cn(\n buttonVariants({\n variant: isActive ? \"outline\" : \"ghost\",\n size,\n }),\n \"cursor-pointer\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction PaginationPrevious({\n className,\n text = \"Anterior\",\n ...props\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\n return (\n <PaginationLink\n aria-label=\"Ir a la página anterior\"\n size=\"default\"\n className={cn(\"pl-2!\", className)}\n {...props}\n >\n <ChevronLeftIcon data-icon=\"inline-start\" className=\"cn-rtl-flip\" />\n <span className=\"hidden sm:block\">{text}</span>\n </PaginationLink>\n );\n}\n\nfunction PaginationNext({\n className,\n text = \"Siguiente\",\n ...props\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\n return (\n <PaginationLink\n aria-label=\"Ir a la página siguiente\"\n size=\"default\"\n className={cn(\"pr-2!\", className)}\n {...props}\n >\n <span className=\"hidden sm:block\">{text}</span>\n <ChevronRightIcon data-icon=\"inline-end\" className=\"cn-rtl-flip\" />\n </PaginationLink>\n );\n}\n\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n aria-hidden\n data-slot=\"pagination-ellipsis\"\n className={cn(\n \"flex size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-(--icon-size-control)\",\n className,\n )}\n {...props}\n >\n <MoreHorizontalIcon />\n <span className=\"sr-only\">Más páginas</span>\n </span>\n );\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n};\n"
20
20
  },
21
21
  {
22
22
  "path": "components/base/Pagination.md",
23
23
  "type": "registry:file",
24
24
  "target": "components/base/Pagination.md",
25
- "content": "# Pagination — guía de uso\n\nNavegación de paginación para listados, tablas y resultados de búsqueda.\nCompuesta por sub-componentes que permiten construir distintas configuraciones. El componente vive en tu proyecto: instálalo con `create-lexy add pagination` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara dividir listados largos en páginas con posición visible: tablas de desk, resultados de búsqueda. Si el contexto es exploración continua (un feed), considera “cargar más” en su lugar.\n\n## Composición\n\n`Pagination` > `PaginationContent` > `PaginationItem`s con `PaginationPrevious`, `PaginationLink` (los números), `PaginationEllipsis` y `PaginationNext`.\n\n## Uso básico\n\n```tsx\n<Pagination>\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious href=\"/items?page=1\" />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=1\" isActive>1</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=2\">2</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=3\">3</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=10\">10</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationNext href=\"/items?page=2\" />\n </PaginationItem>\n </PaginationContent>\n</Pagination>\n```\n\n## Con muchas páginas\n\n```tsx\n<Pagination>\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious href=\"#\" />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">1</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">4</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\" isActive>5</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">6</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">20</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationNext href=\"#\" />\n </PaginationItem>\n </PaginationContent>\n</Pagination>\n```\n\n## Reglas\n\n- Muestra máximo 5–7 números de página visibles.\n- Usa `PaginationEllipsis` para ocultar páginas intermedias.\n- Marca la página actual con `isActive`.\n- Deshabilita u oculta \"Anterior\" en la primera página.\n- Deshabilita u oculta \"Siguiente\" en la última página.\n- No uses paginación para menos de 2 páginas.\n- No mezcles paginación con scroll infinito en la misma vista.\n\n## Import\n\n```tsx\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"@/shared/components/base/Pagination\"; // o @/components/base/Pagination\n```\n\n## Props\n\n### Sub-componentes\n\n| Componente | Props | Descripción |\n|---|---|---|\n| `Pagination` | `className?` | Contenedor `nav` con `aria-label=\"pagination\"`. |\n| `PaginationContent` | `className?` | Lista `ul` que contiene los items. |\n| `PaginationItem` | — | Item `li` de la lista. |\n| `PaginationLink` | `isActive?: boolean`, `size?`, `className?` | Link de página. `isActive` aplica estilo outline. |\n| `PaginationPrevious` | `text?: string`, `className?` | Botón \"Anterior\" con icono. |\n| `PaginationNext` | `text?: string`, `className?` | Botón \"Siguiente\" con icono. |\n| `PaginationEllipsis` | `className?` | Indicador de páginas omitidas (\"...\"). |\n\n## Para IA\n\n1. Identifica si el listado tiene más de una página de resultados.\n2. Si es paginable → usa `Pagination`.\n3. Calcula el rango de páginas visibles (máximo 5–7 items).\n4. Usa `PaginationEllipsis` para ocultar páginas intermedias.\n5. Marca la página actual con `isActive` en `PaginationLink`.\n6. Deshabilita/oculta los botones de navegación en los extremos.\n7. Considera scroll infinito si la navegación por página no aporta valor.\n"
25
+ "content": "# Pagination\nNavegación de paginación para listados, tablas y resultados de búsqueda.\nCompuesta por sub-componentes que permiten construir distintas configuraciones.\n\n## Cuándo usarlo\n\nPara dividir listados largos en páginas con posición visible: tablas de desk, resultados de búsqueda. Si el contexto es exploración continua (un feed), considera “cargar más” en su lugar.\n\n## Composición\n\n`Pagination` > `PaginationContent` > `PaginationItem`s con `PaginationPrevious`, `PaginationLink` (los números), `PaginationEllipsis` y `PaginationNext`.\n\n## Uso básico\n\n```tsx\n<Pagination>\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious href=\"/items?page=1\" />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=1\" isActive>1</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=2\">2</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=3\">3</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"/items?page=10\">10</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationNext href=\"/items?page=2\" />\n </PaginationItem>\n </PaginationContent>\n</Pagination>\n```\n\n## Con muchas páginas\n\n```tsx\n<Pagination>\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious href=\"#\" />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">1</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">4</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\" isActive>5</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">6</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationEllipsis />\n </PaginationItem>\n <PaginationItem>\n <PaginationLink href=\"#\">20</PaginationLink>\n </PaginationItem>\n <PaginationItem>\n <PaginationNext href=\"#\" />\n </PaginationItem>\n </PaginationContent>\n</Pagination>\n```\n\n## Reglas\n\n- Muestra máximo 5–7 números de página visibles.\n- Usa `PaginationEllipsis` para ocultar páginas intermedias.\n- Marca la página actual con `isActive`.\n- Deshabilita u oculta \"Anterior\" en la primera página.\n- Deshabilita u oculta \"Siguiente\" en la última página.\n- No uses paginación para menos de 2 páginas.\n- No mezcles paginación con scroll infinito en la misma vista.\n\n## Import\n\n```tsx\nimport {\n Pagination,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"@/shared/components/base/Pagination\"; // o @/components/base/Pagination\n```\n\n## Props\n\n### Sub-componentes\n\n| Componente | Props | Descripción |\n|---|---|---|\n| `Pagination` | `className?` | Contenedor `nav` con `aria-label=\"pagination\"`. |\n| `PaginationContent` | `className?` | Lista `ul` que contiene los items. |\n| `PaginationItem` | — | Item `li` de la lista. |\n| `PaginationLink` | `isActive?: boolean`, `size?`, `className?` | Link de página. `isActive` aplica estilo outline. |\n| `PaginationPrevious` | `text?: string`, `className?` | Botón \"Anterior\" con icono. |\n| `PaginationNext` | `text?: string`, `className?` | Botón \"Siguiente\" con icono. |\n| `PaginationEllipsis` | `className?` | Indicador de páginas omitidas (\"...\"). |\n\n## Para IA\n\n1. Identifica si el listado tiene más de una página de resultados.\n2. Si es paginable → usa `Pagination`.\n3. Calcula el rango de páginas visibles (máximo 5–7 items).\n4. Usa `PaginationEllipsis` para ocultar páginas intermedias.\n5. Marca la página actual con `isActive` en `PaginationLink`.\n6. Deshabilita/oculta los botones de navegación en los extremos.\n7. Considera scroll infinito si la navegación por página no aporta valor.\n"
26
26
  }
27
27
  ]
28
28
  }
@@ -3,7 +3,7 @@
3
3
  "name": "popover",
4
4
  "type": "registry:ui",
5
5
  "title": "Popover",
6
- "description": "Panel flotante que se ancla a un elemento. Para contenido interactivo. El componente vive en tu proyecto: instálalo con `create-lexy add popover` y edítalo con libertad.",
6
+ "description": "Panel flotante que se ancla a un elemento. Para contenido interactivo.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-popover"
9
9
  ],
@@ -13,13 +13,13 @@
13
13
  "path": "components/base/Popover.tsx",
14
14
  "type": "registry:ui",
15
15
  "target": "components/base/Popover.tsx",
16
- "content": "import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };\n"
16
+ "content": "import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nconst Popover = PopoverPrimitive.Root;\nconst PopoverTrigger = PopoverPrimitive.Trigger;\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\nconst PopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-overlay outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };\n"
17
17
  },
18
18
  {
19
19
  "path": "components/base/Popover.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Popover.md",
22
- "content": "# Popover — guía de uso\n\nPanel flotante que se ancla a un elemento. Para contenido interactivo. El componente vive en tu proyecto: instálalo con `create-lexy add popover` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara contenido interactivo anclado a un elemento: un filtro rápido, un mini-formulario, un picker. Más que un tooltip (que solo informa), menos que un modal (que interrumpe).\n\n## Composición\n\n`PopoverTrigger` abre `PopoverContent` anclado al disparador (o a `PopoverAnchor` si el ancla es otro elemento); dentro va contenido libre.\n\n## Uso básico\n\n```tsx\n<Popover />\n```\n\n## Reglas\n\n- Usa Popover según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Popover } from \"@/components/base/Popover\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Popover desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Popover\nPanel flotante que se ancla a un elemento. Para contenido interactivo.\n\n## Cuándo usarlo\n\nPara contenido interactivo anclado a un elemento: un filtro rápido, un mini-formulario, un picker. Más que un tooltip (que solo informa), menos que un modal (que interrumpe).\n\n## Composición\n\n`PopoverTrigger` abre `PopoverContent` anclado al disparador (o a `PopoverAnchor` si el ancla es otro elemento); dentro va contenido libre.\n\n## Uso básico\n\n```tsx\n<Popover />\n```\n\n## Reglas\n\n- Usa Popover según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Popover } from \"@/components/base/Popover\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Popover desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -3,7 +3,7 @@
3
3
  "name": "profile-card",
4
4
  "type": "registry:ui",
5
5
  "title": "ProfileCard",
6
- "description": "Tarjeta de perfil. Para mostrar información de usuario. El componente vive en tu proyecto: instálalo con `create-lexy add profile-card` y edítalo con libertad.",
6
+ "description": "Tarjeta de perfil. Para mostrar información de usuario.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
9
  "@lexy/avatar",
@@ -14,13 +14,13 @@
14
14
  "path": "components/base/ProfileCard.tsx",
15
15
  "type": "registry:ui",
16
16
  "target": "components/base/ProfileCard.tsx",
17
- "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"./Avatar\";\nimport { Button } from \"./Button\";\n\nexport interface ProfileCardProps extends React.HTMLAttributes<HTMLDivElement> {\n name: string;\n role?: string;\n initials?: string;\n src?: string;\n primaryAction?: string;\n secondaryAction?: string;\n onPrimary?: () => void;\n onSecondary?: () => void;\n /** Oculta la fila de acciones cuando es `false`. */\n showActions?: boolean;\n}\n\nexport const ProfileCard = React.forwardRef<HTMLDivElement, ProfileCardProps>(\n (\n {\n name,\n role,\n initials,\n src,\n primaryAction = \"Ver perfil\",\n secondaryAction = \"Mensaje\",\n onPrimary,\n onSecondary,\n showActions = true,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <article\n ref={ref}\n className={cn(\n \"flex w-70 flex-col gap-4 rounded-lg border border-border bg-background p-6 transition-shadow hover:shadow-md\",\n className,\n )}\n {...props}\n >\n <Avatar className=\"h-16 w-16\">\n {src && <AvatarImage src={src} alt={name} />}\n <AvatarFallback>{initials ?? name.slice(0, 2)}</AvatarFallback>\n </Avatar>\n <div className=\"flex flex-col gap-0.5\">\n <h3 className=\"text-sm font-medium text-foreground\">{name}</h3>\n {role && <p className=\"text-xs text-muted-foreground\">{role}</p>}\n </div>\n {showActions && (\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={onPrimary}>\n {primaryAction}\n </Button>\n <Button size=\"sm\" variant=\"secondary\" onClick={onSecondary}>\n {secondaryAction}\n </Button>\n </div>\n )}\n </article>\n );\n },\n);\n\nProfileCard.displayName = \"ProfileCard\";\n"
17
+ "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils/cn\";\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"./Avatar\";\nimport { Button } from \"./Button\";\n\nexport interface ProfileCardProps extends React.HTMLAttributes<HTMLDivElement> {\n name: string;\n role?: string;\n initials?: string;\n src?: string;\n primaryAction?: string;\n secondaryAction?: string;\n onPrimary?: () => void;\n onSecondary?: () => void;\n /** Oculta la fila de acciones cuando es `false`. */\n showActions?: boolean;\n}\n\nexport const ProfileCard = React.forwardRef<HTMLDivElement, ProfileCardProps>(\n (\n {\n name,\n role,\n initials,\n src,\n primaryAction = \"Ver perfil\",\n secondaryAction = \"Mensaje\",\n onPrimary,\n onSecondary,\n showActions = true,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <article\n ref={ref}\n className={cn(\n \"flex w-70 flex-col gap-4 rounded-lg border border-border bg-background p-6 transition-shadow hover:shadow-raised\",\n className,\n )}\n {...props}\n >\n <Avatar className=\"h-16 w-16\">\n {src && <AvatarImage src={src} alt={name} />}\n <AvatarFallback>{initials ?? name.slice(0, 2)}</AvatarFallback>\n </Avatar>\n <div className=\"flex flex-col gap-0.5\">\n <h3 className=\"type-supporting font-medium text-foreground\">{name}</h3>\n {role && <p className=\"type-meta text-muted-foreground\">{role}</p>}\n </div>\n {showActions && (\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={onPrimary}>\n {primaryAction}\n </Button>\n <Button size=\"sm\" variant=\"secondary\" onClick={onSecondary}>\n {secondaryAction}\n </Button>\n </div>\n )}\n </article>\n );\n },\n);\n\nProfileCard.displayName = \"ProfileCard\";\n"
18
18
  },
19
19
  {
20
20
  "path": "components/base/ProfileCard.md",
21
21
  "type": "registry:file",
22
22
  "target": "components/base/ProfileCard.md",
23
- "content": "# ProfileCard — guía de uso\n\nTarjeta de perfil. Para mostrar información de usuario. El componente vive en tu proyecto: instálalo con `create-lexy add profile-card` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara presentar a una persona con su contexto: nombre, rol, contacto — en paneles de equipo, asignaciones o directorios.\n\n## Composición\n\nUna sola pieza (`ProfileCard`) que compone `Avatar` con nombre, rol y metadatos.\n\n## Uso básico\n\n```tsx\n<ProfileCard />\n```\n\n## Reglas\n\n- Usa ProfileCard según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { ProfileCard } from \"@/components/base/ProfileCard\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa ProfileCard desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
+ "content": "# ProfileCard\nTarjeta de perfil. Para mostrar información de usuario.\n\n## Cuándo usarlo\n\nPara presentar a una persona con su contexto: nombre, rol, contacto — en paneles de equipo, asignaciones o directorios.\n\n## Composición\n\nUna sola pieza (`ProfileCard`) que compone `Avatar` con nombre, rol y metadatos.\n\n## Uso básico\n\n```tsx\n<ProfileCard />\n```\n\n## Reglas\n\n- Usa ProfileCard según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { ProfileCard } from \"@/components/base/ProfileCard\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa ProfileCard desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
24
24
  }
25
25
  ]
26
26
  }
@@ -3,7 +3,7 @@
3
3
  "name": "progress",
4
4
  "type": "registry:ui",
5
5
  "title": "Progress",
6
- "description": "Barra de progreso. Para mostrar avance. El componente vive en tu proyecto: instálalo con `create-lexy add progress` y edítalo con libertad.",
6
+ "description": "Barra de progreso. Para mostrar avance.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-progress"
9
9
  ],
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/Progress.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/Progress.md",
22
- "content": "# Progress — guía de uso\n\nBarra de progreso. Para mostrar avance. El componente vive en tu proyecto: instálalo con `create-lexy add progress` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara avance determinado — cuando sabes cuánto falta: pasos de un wizard, una carga con porcentaje. Si no puedes estimar el total, usa `Spinner` o `Skeleton`; una barra que salta a ciegas genera desconfianza.\n\n## Composición\n\nUna sola pieza (`Progress`) con `value` de 0 a 100. En wizards va arriba, acompañada del paso actual en texto.\n\n## Uso básico\n\n```tsx\n<Progress />\n```\n\n## Reglas\n\n- Usa Progress según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Progress } from \"@/components/base/Progress\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Progress desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
22
+ "content": "# Progress\nBarra de progreso. Para mostrar avance.\n\n## Cuándo usarlo\n\nPara avance determinado — cuando sabes cuánto falta: pasos de un wizard, una carga con porcentaje. Si no puedes estimar el total, usa `Spinner` o `Skeleton`; una barra que salta a ciegas genera desconfianza.\n\n## Composición\n\nUna sola pieza (`Progress`) con `value` de 0 a 100. En wizards va arriba, acompañada del paso actual en texto.\n\n## Uso básico\n\n```tsx\n<Progress />\n```\n\n## Reglas\n\n- Usa Progress según el propósito descrito.\n- No abuses de este componente en contexts donde no aplica.\n\n## Import\n\n```tsx\nimport { Progress } from \"@/components/base/Progress\";\n```\n\n## Props\n\nConsulta la story en Storybook para ver las props disponibles.\n\n## Para IA\n\n1. Identifica el contexto de uso del componente.\n2. Importa Progress desde el path correcto.\n3. Configura las props según la necesidad.\n4. Verifica que el componente se integre correctamente en el layout.\n5. Solo usa variantes documentadas.\n"
23
23
  }
24
24
  ]
25
25
  }
@@ -3,7 +3,7 @@
3
3
  "name": "radio-group",
4
4
  "type": "registry:ui",
5
5
  "title": "RadioGroup",
6
- "description": "Selección **única** entre opciones visibles (Radix). Usa `RadioGroup` como contenedor y `RadioGroupItem` por opción. El componente vive en tu proyecto: instálalo con `create-lexy add radio-group` y edítalo con libertad.",
6
+ "description": "Selección **única** entre opciones visibles (Radix). Usa `RadioGroup` como contenedor y `RadioGroupItem` por opción.",
7
7
  "dependencies": [
8
8
  "@radix-ui/react-radio-group"
9
9
  ],
@@ -19,7 +19,7 @@
19
19
  "path": "components/base/RadioGroup.md",
20
20
  "type": "registry:file",
21
21
  "target": "components/base/RadioGroup.md",
22
- "content": "# RadioGroup — guía de uso\n\nSelección **única** entre opciones visibles (Radix). Usa `RadioGroup` como contenedor y `RadioGroupItem` por opción. El componente vive en tu proyecto: instálalo con `create-lexy add radio-group` y edítalo con libertad.\n\n## Cuándo usarlo\n\nPara elegir una sola opción entre pocas visibles (2–5): tipo de documento, modalidad. Todas las opciones a la vista permiten comparar de un vistazo. Con más opciones, ahorra pantalla con `Select` o `Combobox`.\n\n## Composición\n\n`RadioGroup` (estado y navegación por teclado) contiene un `RadioGroupItem` por opción, cada uno con su `Label`.\n\n## Uso básico\n\n```tsx\n<fieldset>\n <legend className=\"mb-2 text-sm font-medium\">Plan</legend>\n <RadioGroup defaultValue=\"mensual\">\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"mensual\" id=\"r-mensual\" />\n <Label htmlFor=\"r-mensual\">Mensual</Label>\n </div>\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"anual\" id=\"r-anual\" />\n <Label htmlFor=\"r-anual\">Anual</Label>\n </div>\n </RadioGroup>\n</fieldset>\n```\n\n## Reglas\n\n- Cada `RadioGroupItem` necesita `value` único y un `Label` con `id`/`htmlFor`.\n- Envuelve el grupo en `fieldset` + `legend` que nombre la decisión.\n- Conceptualmente siempre hay una sola opción activa.\n- Mantén el orden estable; no reordenes opciones entre renders.\n\n## Cuándo NO usar\n\n- **Selección múltiple** → `Checkbox`.\n- **Muchas opciones (>5–7) o con búsqueda** → `Select` / `Combobox` (ahorra espacio vertical).\n- **Dos estados opuestos on/off de un ajuste** → `Switch`.\n\n## Import\n\n```tsx\nimport { RadioGroup, RadioGroupItem } from \"@/components/base/RadioGroup\";\n```\n\n## Props\n\n### `RadioGroup`\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `value` / `defaultValue` | `string` | — | Opción seleccionada (controlado / inicial). |\n| `onValueChange` | `(value) => void` | — | Cambio de selección. |\n| `disabled` | `boolean` | `false` | Deshabilita todo el grupo. |\n\n### `RadioGroupItem`\n| Prop | Tipo | Descripción |\n|---|---|---|\n| `value` | `string` | **Requerido.** Valor de la opción. |\n| `id` | `string` | Para asociar el `Label`. |\n| `disabled` | `boolean` | Deshabilita esa opción. |\n\n## Para IA\n\n1. Confirma que es \"una sola entre varias\" y que ver todas a la vez ayuda a decidir.\n2. Si son demasiadas o necesitan búsqueda, prefiere `Select`/`Combobox`.\n3. Empareja cada opción con un `Label`; envuelve en `fieldset`/`legend`.\n4. Controla con `value` + `onValueChange` cuando dependa del estado del formulario.\n"
22
+ "content": "# RadioGroup\nSelección **única** entre opciones visibles (Radix). Usa `RadioGroup` como contenedor y `RadioGroupItem` por opción.\n\n## Cuándo usarlo\n\nPara elegir una sola opción entre pocas visibles (2–5): tipo de documento, modalidad. Todas las opciones a la vista permiten comparar de un vistazo. Con más opciones, ahorra pantalla con `Select` o `Combobox`.\n\n## Composición\n\n`RadioGroup` (estado y navegación por teclado) contiene un `RadioGroupItem` por opción, cada uno con su `Label`.\n\n## Uso básico\n\n```tsx\n<fieldset>\n <legend className=\"mb-2 text-sm font-medium\">Plan</legend>\n <RadioGroup defaultValue=\"mensual\">\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"mensual\" id=\"r-mensual\" />\n <Label htmlFor=\"r-mensual\">Mensual</Label>\n </div>\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"anual\" id=\"r-anual\" />\n <Label htmlFor=\"r-anual\">Anual</Label>\n </div>\n </RadioGroup>\n</fieldset>\n```\n\n## Reglas\n\n- Cada `RadioGroupItem` necesita `value` único y un `Label` con `id`/`htmlFor`.\n- Envuelve el grupo en `fieldset` + `legend` que nombre la decisión.\n- Conceptualmente siempre hay una sola opción activa.\n- Mantén el orden estable; no reordenes opciones entre renders.\n\n## Cuándo NO usar\n\n- **Selección múltiple** → `Checkbox`.\n- **Muchas opciones (>5–7) o con búsqueda** → `Select` / `Combobox` (ahorra espacio vertical).\n- **Dos estados opuestos on/off de un ajuste** → `Switch`.\n\n## Import\n\n```tsx\nimport { RadioGroup, RadioGroupItem } from \"@/components/base/RadioGroup\";\n```\n\n## Props\n\n### `RadioGroup`\n| Prop | Tipo | Default | Descripción |\n|---|---|---|---|\n| `value` / `defaultValue` | `string` | — | Opción seleccionada (controlado / inicial). |\n| `onValueChange` | `(value) => void` | — | Cambio de selección. |\n| `disabled` | `boolean` | `false` | Deshabilita todo el grupo. |\n\n### `RadioGroupItem`\n| Prop | Tipo | Descripción |\n|---|---|---|\n| `value` | `string` | **Requerido.** Valor de la opción. |\n| `id` | `string` | Para asociar el `Label`. |\n| `disabled` | `boolean` | Deshabilita esa opción. |\n\n## Para IA\n\n1. Confirma que es \"una sola entre varias\" y que ver todas a la vez ayuda a decidir.\n2. Si son demasiadas o necesitan búsqueda, prefiere `Select`/`Combobox`.\n3. Empareja cada opción con un `Label`; envuelve en `fieldset`/`legend`.\n4. Controla con `value` + `onValueChange` cuando dependa del estado del formulario.\n"
23
23
  }
24
24
  ]
25
25
  }