@asemh/design-system
v1.1.1
Published
Sistema de diseño modular para CRMs de alto rendimiento. Componentes React con estética Glass UI, Tailwind CSS y TypeScript.
Downloads
260
Readme
@asemh/design-system
Sistema de diseño modular y temático especializado para interfaces CRM y aplicaciones administrativas con alta densidad de datos. Construido con React, TypeScript, Tailwind CSS v4 y Radix UI.
✨ Características
- 🎨 Sistema de temas completo con modo claro/oscuro
- 🧩 50+ componentes organizados en Atomic Design
- 🔒 TypeScript estricto con tipos exportados
- ♿ Accesibilidad WCAG 2.1 via Radix UI primitives
- 🚀 Tree-shakeable - importa solo lo que necesitas
- 💅 Glass morphism utilities incluidas
- 📦 Zero config - funciona out of the box con Tailwind v4
🚀 Guías de Instalación
Este sistema de diseño es una biblioteca de componentes para proyectos React existentes.
👉 Guía de Instalación para Astro (Recomendada)
Si estás usando Astro, consulta nuestra guía detallada para configurar SSR, Tailwind v4 y evitar errores comunes.
Instalación General (Vite / Next.js / React)
1. Instalar dependencias
pnpm add @asemh/design-system react react-dom lucide-react react-datepicker date-fnsPeer dependencies requeridas:
lucide-react— provee los íconos del design system.react-datepicker+date-fns— requeridas para los componentesDatePicker,DateRangePickeryCalendar.
2. Configurar Tailwind CSS v4
En tu archivo CSS principal (donde importas tailwind), añade la directiva @source apuntando a node_modules.
@import "tailwindcss";
/* 👇 Indica a Tailwind que escanee las clases de los componentes compilados */
@source "../../node_modules/@asemh/design-system/dist/**/*.js";
/* 👇 Importa tokens de diseño y estilos base (variables CSS, datepicker, glass) */
@import "@asemh/design-system/styles.css";Nota: Ajusta la ruta en
@sourcesegún la ubicación de tu archivo CSS.
3. Configurar Layout Base (Dark Mode + Sidebar)
Para evitar el "flash" de contenido sin estilo (FOUC) y asegurar que el layout y el tema carguen instantáneamente, usa los scripts pre-empaquetados en tu Layout principal (Layout.astro, layout.tsx o index.html).
Ejemplo en Astro:
---
import { THEME_INIT_SCRIPT, CRITICAL_CSS, Toaster } from '@asemh/design-system';
---
<head>
<!-- Inicializa tema y estado del sidebar antes de la hidratación -->
<script is:inline set:html={THEME_INIT_SCRIPT} />
<!-- Previene layout shifts del sidebar -->
<style is:inline set:html={CRITICAL_CSS} />
</head>
<body>
<slot />
<Toaster client:load />
</body>(Opcional) Script manual para HTML puro:
<script>
(function() {
var d = document.documentElement;
var saved = localStorage.getItem('theme');
var isDark = saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches);
d.classList.toggle('dark', isDark);
})();
</script>📚 Componentes
Atoms (Primitivos)
| Componente | Descripción |
|------------|-------------|
| Avatar | Imagen de perfil con fallback |
| Badge | Etiquetas de estado y categorías |
| Breadcrumb | Navegación jerárquica |
| Button | Botón con múltiples variantes |
| Calendar | Calendario interactivo |
| Card | Contenedor con header, content, footer |
| Checkbox | Casilla de verificación |
| DropdownMenu | Menú desplegable contextual |
| Input | Campo de texto |
| Label | Etiqueta para formularios |
| List | Listas estructuradas |
| Media | Imágenes y videos responsivos |
| PasswordInput | Input con toggle de visibilidad |
| Progress | Barra de progreso |
| Radio | Botones de radio |
| ScrollArea | Área de scroll personalizada |
| Select | Selector desplegable |
| Separator | Divisor visual |
| Skeleton | Placeholder de carga |
| Slider | Control deslizante |
| SpecializedInput | Inputs especializados (moneda, porcentaje) |
| Spinner | Indicador de carga |
| Switch | Toggle on/off |
| Table | Tabla de datos |
| Tabs | Navegación por pestañas |
| Textarea | Área de texto multilínea |
| Tooltip | Información emergente |
| Zoom | Zoom de imágenes |
Molecules (Compuestos)
| Componente | Descripción |
|------------|-------------|
| DatePicker | Selector de fecha |
| DateRangePicker | Selector de rango de fechas |
| FormField | Campo de formulario con label y error |
| ThemeToggle | Toggle de tema claro/oscuro |
Organisms (Complejos)
| Componente | Descripción |
|------------|-------------|
| Header | Header de aplicación |
| DocsHeader | Header para documentación |
| Sidebar | Barra lateral de navegación |
| GlassHeader | Header con efecto glass morphism |
🎨 Temas y Personalización
Variables CSS
El sistema usa variables CSS nativas que puedes sobrescribir en tu archivo CSS global.
Copia este bloque en tu src/styles/global.css para tener control total sobre el tema.
@layer base {
:root {
/* 🎨 COLORES PRINCIPALES (HSL) */
--background: hsl(210 20% 98%);
--foreground: hsl(215 15% 10%);
--card: hsl(210 15% 96%);
--card-foreground: hsl(215 15% 10%);
--popover: hsl(210 20% 99%);
--popover-foreground: hsl(215 15% 10%);
--primary: hsl(212 100% 50%);
--primary-foreground: hsl(0 0% 100%);
--secondary: hsl(210 15% 92%);
--secondary-foreground: hsl(215 15% 20%);
--muted: hsl(210 15% 88%);
--muted-foreground: hsl(212 12% 35%);
--accent: hsl(212 90% 45%);
--accent-foreground: hsl(0 0% 100%);
--destructive: hsl(0 72% 51%);
--destructive-foreground: hsl(0 0% 100%);
--border: hsl(210 15% 82%);
--input: hsl(210 15% 82%);
--ring: hsl(212 100% 50%);
/* 📐 GEOMETRÍA */
--radius: 0.6rem;
/* 🪟 GLASS SYSTEM (Base) */
--glass-surface-bg: rgba(255, 255, 255, 0.7);
--glass-card-bg: rgba(255, 255, 255, 0.8);
--glass-border: rgba(0, 0, 0, 0.08);
}
.dark {
--background: hsl(215 20% 6%);
--foreground: hsl(210 15% 93%);
--card: hsl(215 15% 10%);
--card-foreground: hsl(210 15% 93%);
--popover: hsl(215 18% 8%);
--popover-foreground: hsl(210 15% 93%);
--primary: hsl(212 100% 55%);
--primary-foreground: hsl(0 0% 100%);
--secondary: hsl(215 12% 18%);
--secondary-foreground: hsl(210 15% 90%);
--muted: hsl(215 10% 20%);
--muted-foreground: hsl(212 12% 60%);
--accent: hsl(212 90% 55%);
--accent-foreground: hsl(0 0% 100%);
--destructive: hsl(0 65% 50%);
--destructive-foreground: hsl(0 0% 100%);
--border: hsl(215 12% 22%);
--input: hsl(215 12% 18%);
--ring: hsl(212 100% 55%);
/* 🪟 GLASS SYSTEM (Dark) */
--glass-surface-bg: rgba(18, 22, 30, 0.4);
--glass-card-bg: rgba(20, 25, 35, 0.65);
--glass-border: rgba(255, 255, 255, 0.08);
}
}Glass Morphism
Utilidades incluidas para efectos glass:
// Clases disponibles
<div className="glass-surface">...</div> // Superficie amplia (Nivel 1)
<div className="glass-card">...</div> // Tarjeta principal (Nivel 2)
<div className="glass-elevated">...</div> // Elevación fuerte (Nivel 3)
<div className="glass-solid">...</div> // Casi opaco (Nivel 4)Solo Tokens CSS
Si solo necesitas las variables CSS sin los componentes:
import '@asemh/design-system/tokens.css';⚙️ Configuración Avanzada
Estado Global (Tema)
El paquete exporta un store de tema basado en nanostores. El store es un atom llamado theme:
import { theme, useStore } from '@asemh/design-system';
function ThemeButton() {
const $theme = useStore(theme);
return (
<button onClick={() => theme.set($theme === 'dark' ? 'light' : 'dark')}>
Tema actual: {$theme}
</button>
);
}
// O establece un tema específico
theme.set('dark');Valores válidos:
'light','dark','system'.
Notificaciones Toast
import { toast, Toaster } from '@asemh/design-system';
// En tu layout
function Layout({ children }) {
return (
<>
{children}
<Toaster client:load />
</>
);
}
// En cualquier componente
function SaveButton() {
const handleSave = () => {
toast.success('Guardado exitosamente');
// toast.error('Error al guardar');
// toast.info('Información');
// toast.warning('Advertencia');
};
return <Button onClick={handleSave}>Guardar</Button>;
}📖 Ejemplos
Dashboard KPI Card
import {
Card, CardHeader, CardTitle, CardContent,
Badge, Progress
} from '@asemh/design-system';
function KPICard({ title, value, target, trend }) {
const percentage = (value / target) * 100;
return (
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">
{title}
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-baseline justify-between">
<span className="text-2xl font-bold">{value}</span>
<Badge variant={trend > 0 ? 'success' : 'destructive'}>
{trend > 0 ? '+' : ''}{trend}%
</Badge>
</div>
<Progress value={percentage} className="mt-3" />
<p className="text-xs text-muted-foreground mt-1">
{percentage.toFixed(0)}% del objetivo
</p>
</CardContent>
</Card>
);
}Formulario de Contacto
import {
Card, CardHeader, CardTitle, CardContent, CardFooter,
Input, Label, Textarea, Button, toast
} from '@asemh/design-system';
function ContactForm() {
const handleSubmit = (e) => {
e.preventDefault();
toast.success('Mensaje enviado correctamente');
};
return (
<Card className="max-w-md">
<form onSubmit={handleSubmit}>
<CardHeader>
<CardTitle>Contáctanos</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="name">Nombre</Label>
<Input id="name" placeholder="Tu nombre" required />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="[email protected]" required />
</div>
<div className="space-y-2">
<Label htmlFor="message">Mensaje</Label>
<Textarea id="message" placeholder="Escribe tu mensaje..." rows={4} />
</div>
</CardContent>
<CardFooter>
<Button type="submit" className="w-full">
Enviar mensaje
</Button>
</CardFooter>
</form>
</Card>
);
}📜 Scripts disponibles
| Script | Descripción |
|--------|-------------|
| pnpm dev | Inicia el entorno de desarrollo con Astro |
| pnpm build | Construye el sitio de documentación estático |
| pnpm build:lib | Compila la librería para distribución (JS/DTS/CSS) |
| pnpm preview | Vista previa local del build de documentación |
| pnpm release:patch | Incrementa versión patch + build + publish + git push |
| pnpm release:minor | Incrementa versión minor + build + publish + git push |
| pnpm release:major | Incrementa versión major + build + publish + git push |
🤝 Contribuir
Las contribuciones son bienvenidas. Por favor, abre un issue primero para discutir los cambios que te gustaría hacer.
📄 Licencia
MIT © CCisneros-Grupo Asemh
¿Encontraste útil este paquete? ⭐ Dale una estrella en GitHub
