feat: migrar de Lucide a Tabler Icons en componentes y documentación
This commit is contained in:
parent
94ddc5cf16
commit
53a58ee0de
@ -10,7 +10,7 @@
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"iconLibrary": "tabler",
|
||||
"aliases": {
|
||||
"components": "#components",
|
||||
"ui": "@repo/shadcn-ui/components",
|
||||
|
||||
@ -56,7 +56,7 @@ contrato actual de instantáneas.
|
||||
|
||||
## Iconos de plantilla
|
||||
|
||||
Cada plantilla global o propia de compañía admite un icono opcional de la biblioteca Lucide existente. El formulario incluye un selector visual con nombres traducidos, selección marcada y opción «Sin icono». Las copias conservan el icono; las plantillas personalizadas permiten cambiarlo y retirarlo.
|
||||
Cada plantilla global o propia de compañía admite un icono opcional de la biblioteca Tabler Icons compartida. El formulario incluye un selector visual con nombres traducidos, selección marcada y opción «Sin icono». Las copias conservan el icono; las plantillas personalizadas permiten cambiarlo y retirarlo.
|
||||
|
||||
Las doce plantillas de serie incluyen iconos adecuados a cada equipo. Editar o retirar un icono conserva identidades, campos y disponibilidad; el arranque no repone los iconos retirados por el usuario.
|
||||
|
||||
|
||||
@ -13,6 +13,31 @@ El [patrón de diseño de cuadros de diálogo](patron-de-dialogos.md) es la fuen
|
||||
para componer grupos, columnas responsive, filas compactas y selectores. Esta guía describe
|
||||
los componentes que lo implementan y sus contratos.
|
||||
|
||||
## Iconografía de la aplicación
|
||||
|
||||
El código propio utiliza `@tabler/icons-react`, con versión exacta en `@repo/rdx-ui` y
|
||||
licencia MIT. La dependencia sustituye a Lucide en la biblioteca propia y amplía el
|
||||
catálogo disponible sin cargar iconos desde servicios externos. Las importaciones de
|
||||
la aplicación y de sus componentes compartidos pasan por `@repo/rdx-ui/lib/icons`
|
||||
(o `../lib/icons` dentro del paquete). No importar las bibliotecas de iconos directamente
|
||||
en módulos ni duplicar catálogos locales para acciones comunes.
|
||||
|
||||
`lib/icons.ts` exporta nombres semánticos estables, asociados a los componentes de
|
||||
contorno de Tabler. El tamaño se controla con las clases existentes y el color con
|
||||
`currentColor`; el trazo predeterminado de Tabler es 2. Para ajustar su grosor se utiliza
|
||||
la prop `stroke`. Los iconos decorativos mantienen `aria-hidden`; las acciones de icono
|
||||
conservan su nombre accesible traducido. Importar únicamente los iconos necesarios.
|
||||
|
||||
Las claves persistidas de las plantillas de activos y recursos conservan su contrato:
|
||||
`laptop`, `desktop`, `mail`, `file-key`, etc. La correspondencia visual cambia a Tabler,
|
||||
sin migraciones de datos ni cambios en DTO, historial o preferencias del usuario.
|
||||
Los selectores de plantillas usan la misma correspondencia que las fichas y listados.
|
||||
|
||||
`apps/web/components.json` declara Tabler para la generación desde la aplicación.
|
||||
`packages/shadcn-ui` conserva su implementación vendor, configuración y dependencia de
|
||||
Lucide para sus iconos internos; no modificar el código de terceros para migrar los
|
||||
iconos propios. Consultar la [API oficial de Tabler para React](https://docs.tabler.io/icons/libraries/react).
|
||||
|
||||
## Componentes actuales
|
||||
|
||||
- Button: volver a comprobar la conexión.
|
||||
@ -116,7 +141,8 @@ No añadir todo el catálogo ni crear envoltorios sin una necesidad concreta.
|
||||
|
||||
Base UI proporciona interacción accesible y gestión del foco.
|
||||
class-variance-authority define variantes del botón; cn combina clases de Tailwind.
|
||||
lucide-react aporta los iconos del selector y tw-animate-css sus transiciones.
|
||||
`@tabler/icons-react` aporta los iconos del código propio y tw-animate-css sus transiciones.
|
||||
El código vendor de shadcn/ui conserva sus dependencias e iconos internos del registro.
|
||||
shadcn es una herramienta de desarrollo; su hoja de estilos común se incorpora al compilar.
|
||||
|
||||
Guías oficiales: [monorepos](https://ui.shadcn.com/docs/monorepo) e [instalación manual](https://ui.shadcn.com/docs/installation/manual).
|
||||
@ -382,7 +408,7 @@ Los módulos conectan este componente mediante `DeleteRecordDialog`, separado de
|
||||
|
||||
## IconPicker
|
||||
|
||||
`@repo/rdx-ui/components/icon-picker` presenta un desplegable compacto mediante `Select`, `SelectTrigger`, `SelectValue` y `SelectItem` de shadcn/ui (Base UI). Muestra el icono seleccionado y su etiqueta traducida; cada opción combina icono y texto, incluida «Sin icono». Recibe opciones (valor, etiqueta e icono), valor actual, callback, estado deshabilitado y descripción opcional enlazada mediante `aria-describedby`. Su anchura máxima en escritorio es 16 rem y se adapta al espacio disponible en móvil. La etiqueta se asocia al control y los iconos se ocultan del nombre accesible. Mantiene teclado, foco y desplazamiento del desplegable mediante la primitiva existente. No conoce entidades ni endpoints. Las plantillas de activos y recursos reutilizan el mismo componente y aportan sus iconos Lucide, traducciones y validación de claves.
|
||||
`@repo/rdx-ui/components/icon-picker` presenta un desplegable compacto mediante `Select`, `SelectTrigger`, `SelectValue` y `SelectItem` de shadcn/ui (Base UI). Muestra el icono seleccionado y su etiqueta traducida; cada opción combina icono y texto, incluida «Sin icono». Recibe opciones (valor, etiqueta e icono), valor actual, callback, estado deshabilitado y descripción opcional enlazada mediante `aria-describedby`. Su anchura máxima en escritorio es 16 rem y se adapta al espacio disponible en móvil. La etiqueta se asocia al control y los iconos se ocultan del nombre accesible. Mantiene teclado, foco y desplazamiento del desplegable mediante la primitiva existente. No conoce entidades ni endpoints. Las plantillas de activos y recursos reutilizan el mismo componente y aportan sus iconos Tabler, traducciones y validación de claves.
|
||||
|
||||
## Consulta compacta de plantillas
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ presentación completa. No cambia el contrato HTTP, la persistencia ni la valida
|
||||
|
||||
## Iconos de plantillas
|
||||
|
||||
Las ocho plantillas de serie incluyen un icono Lucide: correo para buzones, llave para
|
||||
Las ocho plantillas de serie incluyen un icono Tabler: correo para buzones, llave para
|
||||
accesos, carpeta para carpetas compartidas, auriculares para asistencia, monitor para
|
||||
sistemas operativos, capas para aplicaciones, escudo para certificados y archivo con
|
||||
llave para licencias. Las plantillas globales y propias de compañía permiten elegir,
|
||||
|
||||
@ -109,6 +109,6 @@ test("las plantillas ofrecen selección visual traducida y conservan el icono al
|
||||
);
|
||||
|
||||
assert.ok(empty.includes(none));
|
||||
assert.ok(html.includes("lucide-laptop"));
|
||||
assert.ok(html.includes("tabler-icon-device-laptop"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -91,15 +91,15 @@ test("iconos de recursos: catálogo y selector traducido conservan la selección
|
||||
|
||||
for (const icon of [
|
||||
"mail",
|
||||
"key-round",
|
||||
"key",
|
||||
"folder",
|
||||
"headphones",
|
||||
"monitor",
|
||||
"layers",
|
||||
"device-desktop",
|
||||
"stack-2",
|
||||
"shield-check",
|
||||
"file-key",
|
||||
"file-certificate",
|
||||
]) {
|
||||
assert.ok(list.includes(`lucide-${icon}`));
|
||||
assert.ok(list.includes(`tabler-icon-${icon}`));
|
||||
}
|
||||
const empty = await render(
|
||||
language,
|
||||
@ -121,7 +121,7 @@ test("iconos de recursos: catálogo y selector traducido conservan la selección
|
||||
assert.ok(html.includes(label));
|
||||
assert.ok(html.includes('role="combobox"'));
|
||||
assert.ok(html.includes(mail));
|
||||
assert.ok(html.includes("lucide-mail"));
|
||||
assert.ok(html.includes("tabler-icon-mail"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -496,7 +496,7 @@ test("recursos: inventario y panel usan el icono vigente de la plantilla sin cam
|
||||
catalog,
|
||||
});
|
||||
|
||||
assert.ok(list.includes("lucide-mail"));
|
||||
assert.ok(list.includes("tabler-icon-mail"));
|
||||
const panel = await render(
|
||||
"es",
|
||||
<ResourceSelectionPanel
|
||||
@ -511,14 +511,14 @@ test("recursos: inventario y panel usan el icono vigente de la plantilla sin cam
|
||||
/>
|
||||
);
|
||||
|
||||
assert.ok(panel.includes("lucide-mail"));
|
||||
assert.ok(panel.includes("tabler-icon-mail"));
|
||||
const withoutIcon = { ...template, values: { ...template.values, icon: undefined } };
|
||||
const cleared = await render("es", <ResourcesPage companyId={companyId} />, {
|
||||
resources: [resource],
|
||||
catalog: { items: [withoutIcon] },
|
||||
});
|
||||
|
||||
assert.equal(cleared.includes("lucide-mail"), false);
|
||||
assert.equal(cleared.includes("tabler-icon-mail"), false);
|
||||
assert.equal(resource.specification.templateName, source.specification.templateName);
|
||||
assert.deepEqual(resource.history, source.history);
|
||||
});
|
||||
|
||||
@ -16,10 +16,10 @@
|
||||
"dependencies": {
|
||||
"@base-ui/react": "1.8.0",
|
||||
"@repo/shadcn-ui": "workspace:*",
|
||||
"@tabler/icons-react": "3.49.0",
|
||||
"@tanstack/react-table": "8.21.3",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"cn": "0.3.0",
|
||||
"lucide-react": "1.8.0"
|
||||
"cn": "0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { ChevronDownIcon, InfoIcon } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { ChevronDownIcon, InfoIcon } from "../lib/icons";
|
||||
|
||||
export function ContextHelp({
|
||||
title,
|
||||
description,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Menu } from "@base-ui/react/menu";
|
||||
import { Button } from "@repo/shadcn-ui/components/button";
|
||||
import { EllipsisIcon } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { ENTITY_PAGE_SIZES, entityListLabels, entityListPages } from "../lib/entity-list";
|
||||
import { EllipsisIcon } from "../lib/icons";
|
||||
|
||||
import { SelectWithAction } from "./select-with-action";
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Button } from "@repo/shadcn-ui/components/button";
|
||||
import { GripVerticalIcon } from "lucide-react";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
import { GripVerticalIcon } from "../lib/icons";
|
||||
|
||||
/** Asa con nombre traducido; el consumidor aporta los eventos de arrastre y teclado. */
|
||||
export function ReorderHandle({
|
||||
label,
|
||||
|
||||
@ -6,7 +6,8 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@repo/shadcn-ui/components/select";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
|
||||
import { PlusIcon } from "../lib/icons";
|
||||
|
||||
import { ButtonGroup } from "./button-group";
|
||||
|
||||
|
||||
@ -6,11 +6,12 @@ import {
|
||||
} from "@repo/shadcn-ui/components/collapsible";
|
||||
import { Input } from "@repo/shadcn-ui/components/input";
|
||||
import { Textarea } from "@repo/shadcn-ui/components/textarea";
|
||||
import { ArrowDownIcon, ArrowUpIcon, ChevronRightIcon, Trash2Icon } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import { useId, useState } from "react";
|
||||
import { flushSync } from "react-dom";
|
||||
|
||||
import { ArrowDownIcon, ArrowUpIcon, ChevronRightIcon, Trash2Icon } from "../lib/icons";
|
||||
|
||||
import type { FieldSection } from "./field-sections";
|
||||
import { FormLabel } from "./form-label";
|
||||
import type { SectionEditorLabels } from "./template-sections-editor";
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Button } from "@repo/shadcn-ui/components/button";
|
||||
import { ArrowDownIcon, ArrowUpIcon, PlusIcon, Trash2Icon } from "lucide-react";
|
||||
import { useId } from "react";
|
||||
|
||||
import { useDragReorder } from "../hooks/use-drag-reorder";
|
||||
import { ArrowDownIcon, ArrowUpIcon, PlusIcon, Trash2Icon } from "../lib/icons";
|
||||
|
||||
import type { FieldSection } from "./field-sections";
|
||||
import { FormLabel } from "./form-label";
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Button } from "@repo/shadcn-ui/components/button";
|
||||
import { PlusIcon } from "lucide-react";
|
||||
import { useId } from "react";
|
||||
|
||||
import { useDragReorder } from "../hooks/use-drag-reorder";
|
||||
import { PlusIcon } from "../lib/icons";
|
||||
import { removeTemplateSection } from "../lib/template-sections";
|
||||
|
||||
import type { FieldSection } from "./field-sections";
|
||||
|
||||
@ -1,45 +1,53 @@
|
||||
/** Catálogo visual propio: nombres semánticos estables y componentes SVG de Tabler. */
|
||||
export {
|
||||
BatteryChargingIcon,
|
||||
BellIcon,
|
||||
BoxIcon,
|
||||
BriefcaseIcon,
|
||||
Building2Icon,
|
||||
CameraIcon,
|
||||
ChevronDownIcon,
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
ClockIcon,
|
||||
DatabaseIcon,
|
||||
FileKeyIcon,
|
||||
FolderIcon,
|
||||
HardDriveIcon,
|
||||
HeadphonesIcon,
|
||||
HomeIcon,
|
||||
KeyRoundIcon,
|
||||
KeyboardIcon,
|
||||
LaptopIcon,
|
||||
LayersIcon,
|
||||
LayoutTemplateIcon,
|
||||
MailIcon,
|
||||
MapPinIcon,
|
||||
MonitorCogIcon,
|
||||
MonitorIcon,
|
||||
MouseIcon,
|
||||
NetworkIcon,
|
||||
PhoneIcon,
|
||||
PrinterIcon,
|
||||
RouterIcon,
|
||||
SearchIcon,
|
||||
ServerIcon,
|
||||
SettingsIcon,
|
||||
ShieldCheckIcon,
|
||||
SmartphoneIcon,
|
||||
TabletIcon,
|
||||
TicketIcon,
|
||||
TriangleAlertIcon,
|
||||
UserRoundXIcon,
|
||||
UsersIcon,
|
||||
WifiIcon,
|
||||
WrenchIcon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
IconAlertTriangle as TriangleAlertIcon,
|
||||
IconArrowDown as ArrowDownIcon,
|
||||
IconArrowUp as ArrowUpIcon,
|
||||
IconBatteryCharging as BatteryChargingIcon,
|
||||
IconBell as BellIcon,
|
||||
IconBox as BoxIcon,
|
||||
IconBriefcase as BriefcaseIcon,
|
||||
IconBuildings as Building2Icon,
|
||||
IconCamera as CameraIcon,
|
||||
IconChevronDown as ChevronDownIcon,
|
||||
IconChevronLeft as ChevronLeftIcon,
|
||||
IconChevronRight as ChevronRightIcon,
|
||||
IconClock as ClockIcon,
|
||||
IconDatabase as DatabaseIcon,
|
||||
IconDeviceDesktop as MonitorIcon,
|
||||
IconDeviceDesktopCog as MonitorCogIcon,
|
||||
IconDeviceLaptop as LaptopIcon,
|
||||
IconDeviceMobile as SmartphoneIcon,
|
||||
IconDeviceTablet as TabletIcon,
|
||||
IconDots as EllipsisIcon,
|
||||
IconFileCertificate as FileKeyIcon,
|
||||
IconFolder as FolderIcon,
|
||||
IconGripVertical as GripVerticalIcon,
|
||||
IconHeadphones as HeadphonesIcon,
|
||||
IconHome as HomeIcon,
|
||||
IconInfoCircle as InfoIcon,
|
||||
IconKey as KeyRoundIcon,
|
||||
IconKeyboard as KeyboardIcon,
|
||||
IconLayoutDashboard as LayoutTemplateIcon,
|
||||
IconMail as MailIcon,
|
||||
IconMapPin as MapPinIcon,
|
||||
IconMouse as MouseIcon,
|
||||
IconPhone as PhoneIcon,
|
||||
IconPlus as PlusIcon,
|
||||
IconPrinter as PrinterIcon,
|
||||
IconRouter as RouterIcon,
|
||||
IconSearch as SearchIcon,
|
||||
IconServer as ServerIcon,
|
||||
IconServer2 as HardDriveIcon,
|
||||
IconSettings as SettingsIcon,
|
||||
IconShieldCheck as ShieldCheckIcon,
|
||||
IconSitemap as NetworkIcon,
|
||||
IconStack2 as LayersIcon,
|
||||
IconTicket as TicketIcon,
|
||||
IconTool as WrenchIcon,
|
||||
IconTrash as Trash2Icon,
|
||||
IconUserX as UserRoundXIcon,
|
||||
IconUsers as UsersIcon,
|
||||
IconWifi as WifiIcon,
|
||||
IconX as XIcon,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
@ -493,6 +493,9 @@ importers:
|
||||
'@repo/shadcn-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../shadcn-ui
|
||||
'@tabler/icons-react':
|
||||
specifier: 3.49.0
|
||||
version: 3.49.0(react@19.2.5)
|
||||
'@tanstack/react-table':
|
||||
specifier: 8.21.3
|
||||
version: 8.21.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
||||
@ -502,9 +505,6 @@ importers:
|
||||
cn:
|
||||
specifier: 0.3.0
|
||||
version: 0.3.0
|
||||
lucide-react:
|
||||
specifier: 1.8.0
|
||||
version: 1.8.0(react@19.2.5)
|
||||
devDependencies:
|
||||
'@repo/typescript-config':
|
||||
specifier: workspace:*
|
||||
@ -1733,6 +1733,14 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^9.0.0 || ^10.0.0
|
||||
|
||||
'@tabler/icons-react@3.49.0':
|
||||
resolution: {integrity: sha512-Um59pm5RVNUaQjFUtG0r4oYJbZuBS3tGugAA2tgBg0WufMk34Eio3nsO30RUkLuL2giYPQUNdY9HvqltLLYyNA==}
|
||||
peerDependencies:
|
||||
react: '>= 16'
|
||||
|
||||
'@tabler/icons@3.49.0':
|
||||
resolution: {integrity: sha512-l+GnSkFETx0U26icxv1VUFnxxiTqXfCcVRiRAnyMwibupM2S2L/hSaZ9gmSgz01rkrsH/93NvLsxykqdanc6lw==}
|
||||
|
||||
'@tailwindcss/node@4.2.2':
|
||||
resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==}
|
||||
|
||||
@ -5120,6 +5128,13 @@ snapshots:
|
||||
estraverse: 5.3.0
|
||||
picomatch: 4.0.7
|
||||
|
||||
'@tabler/icons-react@3.49.0(react@19.2.5)':
|
||||
dependencies:
|
||||
'@tabler/icons': 3.49.0
|
||||
react: 19.2.5
|
||||
|
||||
'@tabler/icons@3.49.0': {}
|
||||
|
||||
'@tailwindcss/node@4.2.2':
|
||||
dependencies:
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
|
||||
Loading…
Reference in New Issue
Block a user