Skip to content

@imansi/ui

Componentes React accesibles y sin estilos propios para el ecosistema Imansi. Construidos sobre @imansi/tailwind y Radix UI.

npm versionLicense: MIT


¿Qué es?

@imansi/ui es la librería de componentes React del ecosistema Imansi. Contiene más de 40 componentes accesibles y sin estilos propios: toda la apariencia viene de los design tokens de @imansi/tailwind.

Cambiar el tema o el modo (light/dark) es un solo atributo en <html>. Los componentes se adaptan automáticamente sin una sola línea condicional.

Construidos sobre Radix UI para máxima accesibilidad (foco, teclado, ARIA) y estilizados exclusivamente con Tailwind CSS v4.

Parte del ecosistema Imansi — infraestructura moderna para tus apps.


Instalación

bash
npm install @imansi/ui @imansi/tailwind

Requiere:

  • React 18+ o 19
  • Tailwind CSS v4
  • @imansi/tailwind como peer dependency

Instalá Tailwind v4 y el plugin de Vite (o PostCSS):

bash
npm install -D tailwindcss @tailwindcss/vite

Configuración

1. Configurar Vite

js
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [react(), tailwindcss()],
  optimizeDeps: {
    exclude: ['@imansi/ui'],
  },
})

El optimizeDeps.exclude evita que Vite pre-empaquete la librería, permitiendo que el HMR funcione correctamente durante el desarrollo.

2. Importar estilos

En tu src/index.css:

css
@import "tailwindcss";
@import "@imansi/tailwind/styles.css";

/* Escanear las clases usadas en tu app */
@source "./**/*.jsx";
@source "./**/*.js";

/* Escanear las clases dentro de @imansi/ui */
@source "../node_modules/@imansi/ui/src/**/*.jsx";

3. Configurar tema y modo

En el <html> de tu index.html:

html
<html data-theme="modern" data-mode="light">

O dinámicamente desde JavaScript:

js
document.documentElement.dataset.theme = 'modern';
document.documentElement.dataset.mode = 'dark';

Uso básico

jsx
import {
  Button,
  Input,
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
  Alert,
} from '@imansi/ui';

export function LoginForm() {
  return (
    <Card className="max-w-md">
      <CardHeader>
        <CardTitle>Iniciar sesión</CardTitle>
        <CardDescription>Ingresá tus credenciales</CardDescription>
      </CardHeader>

      <CardContent className="space-y-4">
        <Input label="Email" type="email" placeholder="correo@ejemplo.com" />
        <Input label="Contraseña" type="password" placeholder="••••••••" />
        <Alert variant="info" title="Tip">
          Usá una contraseña segura de al menos 8 caracteres.
        </Alert>
      </CardContent>

      <CardFooter className="justify-end gap-2">
        <Button variant="ghost">Cancelar</Button>
        <Button>Entrar</Button>
      </CardFooter>
    </Card>
  );
}

Componentes disponibles

Los 40+ componentes están organizados en 6 categorías funcionales.

1. Core

Los componentes esenciales para cualquier interfaz.

ComponenteDescripción
ButtonBotón con variantes (primary, outline, ghost, destructive)
InputCampo de texto con label, hint y error
CardContenedor de superficies con header, content y footer
BadgeEtiqueta pequeña de estado
AlertMensaje destacado (info, success, warning, destructive)

2. Formularios

Campos y controles de entrada.

ComponenteDescripción
LabelEtiqueta accesible para campos
TextareaCampo de texto multilínea
CheckboxCasilla de selección
SwitchInterruptor on/off
RadioGroupGrupo de radios
SliderControl deslizante
SelectSelector desplegable

3. Overlays

Elementos flotantes y modales.

ComponenteDescripción
DialogModal centrado
AlertDialogModal de confirmación
DrawerPanel lateral deslizante
PopoverContenido flotante anclado
TooltipTexto informativo al hover
DropdownMenuMenú desplegable
ToasterNotificaciones toast

4. Datos

Componentes para mostrar información.

ComponenteDescripción
AvatarFoto de usuario con fallback
ProgressBarra de progreso
SkeletonPlaceholder de carga
TabsPestañas de contenido
AccordionSecciones plegables
TableTabla de datos

5. Layout y Navegación

ComponenteDescripción
BreadcrumbRuta de navegación
PaginationPaginación
CollapsibleSección plegable
SeparatorLínea divisoria
ScrollAreaÁrea con scroll custom

6. Avanzados

Componentes especializados para casos específicos.

ComponenteDescripción
AspectRatioContenedor con relación de aspecto
CalendarCalendario de selección de fecha
CommandPaleta de comandos tipo ⌘K
ComboboxSelector con búsqueda
ContextMenuMenú contextual (click derecho)
HoverCardCard al hover
InputOTPCampo de código OTP
MenubarBarra de menú de aplicación
NavigationMenuMenú de navegación complejo
ResizablePaneles redimensionables
SheetPanel lateral tipo drawer
ToggleBotón de estado on/off
ToggleGroupGrupo de toggles

Temas y modos

@imansi/ui funciona con los 6 temas de @imansi/tailwind:

TemaPersonalidad
minimalMonocromo editorial, sin color de marca
modernÍndigo vibrante, radios generosos
compactVerde esmeralda, denso, ideal para dashboards
warmSerif + paleta cálida (crema, terracota, ámbar)
redRojo intenso, bold, energético
yellowÁmbar brillante, soleado

Y los 2 modos:

  • light — Colores claros
  • dark — Colores oscuros

Cambiar de tema o modo es instantáneo y no requiere recargar. Los componentes se adaptan automáticamente porque todos usan tokens semánticos (bg-primary, text-muted-foreground).


Convenciones de la API

Todos los componentes de @imansi/ui siguen las mismas convenciones:

1. Props en español

Los nombres de las props usan español cuando tiene sentido:

jsx
<Input label="Email" hint="Usá tu correo principal" error={error} />
<Alert variant="info" title="Tip">...</Alert>

2. Variantes con variant

Los componentes con múltiples estilos aceptan la prop variant:

jsx
<Button variant="primary">Primario</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Eliminar</Button>

Valores comunes: primary, secondary, outline, ghost, link, destructive.

3. Tamaños con size

jsx
<Button size="sm">Pequeño</Button>
<Button size="md">Mediano</Button>
<Button size="lg">Grande</Button>
<Button size="icon">🔔</Button>

4. className para estilos propios

Todos los componentes aceptan className y se mergea con tailwind-merge:

jsx
<Button className="w-full mt-4">Ancho completo</Button>

5. Accesibilidad por defecto

  • aria-label cuando no hay texto visible
  • role correcto en cada elemento
  • Navegación por teclado completa
  • Focus visible consistente

Composición

Los componentes están diseñados para componerse entre sí. Por ejemplo, Card tiene subcomponentes:

jsx
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from '@imansi/ui';

<Card>
  <CardHeader>
    <CardTitle>Título</CardTitle>
    <CardDescription>Descripción corta</CardDescription>
  </CardHeader>
  <CardContent>Contenido principal</CardContent>
  <CardFooter>Acciones al pie</CardFooter>
</Card>

Lo mismo pasa con:

  • Alert + AlertTitle + AlertDescription
  • Select + SelectTrigger + SelectContent + SelectItem
  • Tabs + TabsList + TabsTrigger + TabsContent
  • Accordion + AccordionItem + AccordionTrigger + AccordionContent
  • Table + TableHeader + TableBody + TableRow + TableCell
  • Breadcrumb + BreadcrumbList + BreadcrumbItem + BreadcrumbLink

Personalización avanzada

Cambiar colores de un componente puntual

jsx
<Button className="bg-green-600 hover:bg-green-700">
  Botón verde custom
</Button>

Cambiar colores globalmente

Editá los tokens de @imansi/tailwind:

css
:root {
  --color-primary: oklch(0.55 0.24 155);
}

O en modo oscuro:

css
.dark {
  --color-primary: oklch(0.70 0.22 155);
}

Extender un componente

jsx
import { Button } from '@imansi/ui';

export function BotonPeligroso({ children, ...props }) {
  return (
    <Button variant="destructive" {...props}>
      ⚠️ {children}
    </Button>
  );
}

Arquitectura

@imansi/ui es la segunda capa del ecosistema Imansi. Consume @imansi/tailwind sin modificarlo.

@imansi/tailwind              ← Tokens + 6 temas + base

@imansi/ui                    ← Este paquete (componentes)

@imansi/templates             ← Páginas completas

create-imansi-app             ← CLI de scaffolding

Reglas arquitectónicas:

  1. @imansi/ui no define colores propios. Todo sale de @imansi/tailwind.
  2. Nunca usa colores crudos (bg-blue-500). Solo tokens semánticos (bg-primary).
  3. Sin estilos propios: cada componente es un wrapper de Radix UI con clases Tailwind semánticas.
  4. La accesibilidad viene de Radix: foco, teclado, ARIA, roles, estados — todo incluido.

Próximos pasos

Hecho con ❤️ en Argentina