@jonapin006/tiger
v1.0.55
Published
Tiger Design System - A clean, premium, and theme-driven UI library for React applications, following Clean Architecture and SOLID principles.
Downloads
5,935
Maintainers
Readme
🐅 Tiger Design System
Welcome to Tiger Design System, a high-fidelity, professional-grade UI library and framework built on Clean Architecture principles and SOLID engineering.
Tiger handles complex multi-theme token architectures and a sophisticated "Geometry-by-Size" system, optimized for the Wallet ecosystem.
🚀 Integración (Quick Start)
Sigue estos pasos para integrar Tiger en tu proyecto externo de React.
1. Instalación
npm install @jonapin006/tiger2. Configuración de Tailwind (tailwind.config.js)
Para que el Modo Oscuro (Dark Mode) y las transiciones automáticas funcionen, es obligatorio configurar el cambio por clase:
/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class', // ¡Vital para el soporte Dark Mode de Tiger!
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@jonapin006/tiger/dist/**/*.{js,ts,jsx,tsx}" // Asegura el escaneo de clases de la librería
],
theme: {
extend: {},
},
plugins: [],
}3. Configuración Raíz (src/main.tsx)
Importa los estilos globales y envuelve tu aplicación con el ThemeProvider y el TigerGlobalGlassWrapper.
import { ThemeProvider, TigerGlobalGlassWrapper } from '@jonapin006/tiger';
import '@jonapin006/tiger/styles'; // Estilos base y tokens de Tiger
import './index.css'; // Tu Tailwind local
ReactDOM.createRoot(document.getElementById('root')!).render(
<ThemeProvider>
<TigerGlobalGlassWrapper>
<App />
</TigerGlobalGlassWrapper>
</ThemeProvider>
);🌓 Dark Mode
Tiger incluye persistencia nativa en localStorage. El modo se mantiene entre sesiones sin parpadeos.
import { useTheme } from '@jonapin006/tiger';
function ThemeSwitcher() {
const { mode, toggleMode } = useTheme();
return <button onClick={toggleMode}>Modo actual: {mode}</button>;
}📦 Componentes
TigerTypography
Componente base para texto. Controla tamaño, peso, y decoración.
import { TigerTypography, TypographySize } from '@jonapin006/tiger';
// Tamaños
<TigerTypography typographySize={TypographySize.Xsmall}>Extra pequeño</TigerTypography>
<TigerTypography typographySize={TypographySize.Small}>Pequeño</TigerTypography>
<TigerTypography typographySize={TypographySize.Medium}>Medio</TigerTypography>
<TigerTypography typographySize={TypographySize.Large}>Grande</TigerTypography>
<TigerTypography typographySize={TypographySize.Xlarge}>Extra grande</TigerTypography>
// Elemento HTML
<TigerTypography variant="h1" typographySize={TypographySize.Xlarge}>Título</TigerTypography>
<TigerTypography variant="span" typographySize={TypographySize.Small}>Inline</TigerTypography>
// Peso tipográfico
<TigerTypography weight="regular">Regular</TigerTypography>
<TigerTypography weight="semibold">Semibold</TigerTypography>
<TigerTypography weight="bold">Bold</TigerTypography>
// Decoración
<TigerTypography italic>Cursiva</TigerTypography>
<TigerTypography underline>Subrayado</TigerTypography>
<TigerTypography strikethrough>Tachado</TigerTypography>
// Combinaciones
<TigerTypography typographySize={TypographySize.Large} weight="semibold" italic underline>
Texto compuesto
</TigerTypography>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| typographySize | TypographySize | Medium | Tamaño del texto |
| variant | 'h1' \| 'h2' \| 'h3' \| 'p' \| 'span' | 'p' | Elemento HTML |
| weight | 'regular' \| 'semibold' \| 'bold' | — | Peso tipográfico |
| bold | boolean | false | Shorthand de weight="bold" |
| italic | boolean | false | Cursiva |
| underline | boolean | false | Subrayado |
| strikethrough | boolean | false | Tachado |
| className | string | — | Clases CSS adicionales |
| id | string | — | Atributo id |
TigerButton
Botón principal con variantes, tamaños e íconos.
import { TigerButton, TigerButtonVariant, ComponentSize } from '@jonapin006/tiger';
import { Download, ArrowRight } from 'lucide-react';
// Variantes
<TigerButton variant={TigerButtonVariant.Primary}>Primario</TigerButton>
<TigerButton variant={TigerButtonVariant.Secondary}>Secundario</TigerButton>
<TigerButton variant={TigerButtonVariant.Ghost}>Ghost</TigerButton>
// Tamaños
<TigerButton size={ComponentSize.Small}>Pequeño</TigerButton>
<TigerButton size={ComponentSize.Medium}>Medio</TigerButton>
<TigerButton size={ComponentSize.Large}>Grande</TigerButton>
<TigerButton size={ComponentSize.Xlarge}>Extra grande</TigerButton>
// Con íconos
<TigerButton iconLeft={Download}>Descargar</TigerButton>
<TigerButton iconRight={ArrowRight}>Continuar</TigerButton>
// Ancho completo
<TigerButton fullWidth>Acción principal</TigerButton>
// Deshabilitado
<TigerButton disabled>No disponible</TigerButton>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| variant | TigerButtonVariant | Primary | Estilo visual |
| size | ComponentSize | Medium | Tamaño (excluye xsmall) |
| iconLeft | React.ElementType | — | Ícono izquierdo |
| iconRight | React.ElementType | — | Ícono derecho |
| fullWidth | boolean | false | Ocupa el ancho del contenedor |
| typographySize | TypographySize | — | Sobreescribe tamaño tipográfico |
Acepta todos los atributos nativos de <button>.
TigerIconButton
Botón exclusivamente de ícono.
import { TigerIconButton, TigerButtonVariant, ComponentSize } from '@jonapin006/tiger';
import { Settings } from 'lucide-react';
<TigerIconButton
icon={<Settings />}
variant={TigerButtonVariant.Ghost}
size={ComponentSize.Medium}
aria-label="Configuración"
onClick={() => {}}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| icon | ReactNode | — | Ícono a renderizar |
| variant | TigerButtonVariant | Primary | Estilo visual |
| size | ComponentSize | Medium | Tamaño (excluye xsmall) |
| disabled | boolean | false | Deshabilita el botón |
| aria-label | string | — | Etiqueta accesible (recomendado) |
TigerBadge
Etiqueta de estado o categoría.
import { TigerBadge, TigerBadgeVariant, ComponentSize } from '@jonapin006/tiger';
<TigerBadge variant={TigerBadgeVariant.Primary}>Nuevo</TigerBadge>
<TigerBadge variant={TigerBadgeVariant.Success}>Activo</TigerBadge>
<TigerBadge variant={TigerBadgeVariant.Warning}>Pendiente</TigerBadge>
<TigerBadge variant={TigerBadgeVariant.Error}>Error</TigerBadge>
<TigerBadge variant={TigerBadgeVariant.Accent} size={ComponentSize.Medium}>
Destacado
</TigerBadge>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| variant | TigerBadgeVariant | Primary | Color del badge |
| size | ComponentSize.Small \| .Medium | Small | Tamaño |
| typographySize | TypographySize | — | Sobreescribe tamaño tipográfico |
TigerCard
Contenedor tipo tarjeta con padding y bordes redondeados según el tema.
import { TigerCard, ComponentSize } from '@jonapin006/tiger';
// Estática
<TigerCard size={ComponentSize.Medium}>
<p>Contenido</p>
</TigerCard>
// Clickeable (aplica hover y cursor automáticamente)
<TigerCard size={ComponentSize.Large} onClick={() => navigate('/detail')}>
<h2>Título</h2>
<p>Descripción</p>
</TigerCard>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| size | ComponentSize | Medium | Padding y borde redondeado (excluye xsmall) |
| onClick | () => void | — | Si se provee, habilita estilos interactivos |
| typographySize | TypographySize | — | Sobreescribe tamaño tipográfico |
TigerStack
Layout flexbox para organizar elementos con gap y alineación uniformes.
import { TigerStack, ComponentSize } from '@jonapin006/tiger';
// Vertical (default)
<TigerStack gap={ComponentSize.Medium}>
<div>Elemento 1</div>
<div>Elemento 2</div>
</TigerStack>
// Horizontal centrado
<TigerStack direction="horizontal" gap={ComponentSize.Small} align="center">
<TigerBadge>Estado</TigerBadge>
<TigerTypography>Texto</TigerTypography>
</TigerStack>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| direction | 'vertical' \| 'horizontal' | 'vertical' | Dirección del flex |
| gap | ComponentSize | Medium | Espacio entre hijos |
| align | 'start' \| 'center' \| 'end' | 'start' | Alineación |
TigerInput
Campo de texto nativo con variantes de tamaño.
import { TigerInput, ComponentSize } from '@jonapin006/tiger';
<TigerInput placeholder="Buscar..." size={ComponentSize.Medium} />
<TigerInput
type="email"
placeholder="[email protected]"
size={ComponentSize.Large}
onChange={(e) => setValue(e.target.value)}
/>
// Con ref
const ref = useRef<HTMLInputElement>(null);
<TigerInput ref={ref} placeholder="Focus me" />| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| size | ComponentSize | Medium | Tamaño (excluye xsmall) |
Acepta todos los atributos nativos de <input> (excepto size, className y style).
TigerCheckbox
Casilla de verificación accesible.
import { TigerCheckbox, ComponentSize } from '@jonapin006/tiger';
const [checked, setChecked] = useState(false);
<TigerCheckbox checked={checked} onChange={setChecked} size={ComponentSize.Medium} />
<TigerCheckbox checked={true} onChange={() => {}} disabled />| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| checked | boolean | false | Estado |
| onChange | (checked: boolean) => void | — | Callback |
| size | ComponentSize.Small \| .Medium \| .Large | Medium | Tamaño |
| disabled | boolean | false | Deshabilita |
TigerSwitch
Toggle on/off con etiqueta y descripción opcionales.
import { TigerSwitch, TigerSwitchColor, ComponentSize } from '@jonapin006/tiger';
const [enabled, setEnabled] = useState(false);
<TigerSwitch
checked={enabled}
onChange={setEnabled}
label="Notificaciones"
description="Recibe alertas por email"
/>
<TigerSwitch
checked={enabled}
onChange={setEnabled}
color={TigerSwitchColor.Primary}
size={ComponentSize.Large}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| checked | boolean | — | Estado (requerido) |
| onChange | (checked: boolean) => void | — | Callback (requerido) |
| size | ComponentSize.Small \| .Medium \| .Large | Medium | Tamaño |
| color | TigerSwitchColor | Primary | Color |
| label | string | — | Etiqueta visible |
| description | string | — | Descripción secundaria |
| disabled | boolean | false | Deshabilita |
TigerTabs
Interfaz de pestañas con tres variantes visuales.
import { TigerTabs, TigerTabsVariant, ComponentSize } from '@jonapin006/tiger';
const tabs = [
{ id: 'general', label: 'General', content: <div>Contenido general</div> },
{ id: 'security', label: 'Seguridad', content: <div>Seguridad</div> },
{ id: 'billing', label: 'Facturación', content: <div>Pago</div>, disabled: true },
];
// Segmento
<TigerTabs items={tabs} variant={TigerTabsVariant.Segment} />
// Subrayado — ancho completo
<TigerTabs items={tabs} variant={TigerTabsVariant.Underline} fullWidth />
// Pill — controlado externamente
<TigerTabs
items={tabs}
variant={TigerTabsVariant.Pill}
activeId={activeTab}
onChange={setActiveTab}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| items | TigerTabItem[] | — | Pestañas (requerido) |
| variant | TigerTabsVariant | Segment | Estilo visual |
| size | ComponentSize | Medium | Tamaño |
| activeId | string | — | Control externo |
| defaultActiveId | string | — | Tab activo inicial |
| onChange | (id: string) => void | — | Callback |
| fullWidth | boolean | false | Ocupa el ancho completo |
TigerTabItem: id, label, content, icon?, disabled?
TigerAccordion
Secciones expandibles.
import { TigerAccordion } from '@jonapin006/tiger';
const items = [
{ id: 'q1', title: '¿Cómo funciona?', content: <p>El sistema procesa automáticamente.</p> },
{ id: 'q2', title: '¿Cuánto cuesta?', content: <p>El plan básico es gratuito.</p> },
];
// Una sección a la vez (default)
<TigerAccordion items={items} defaultExpandedId="q1" />
// Múltiples abiertas simultáneamente
<TigerAccordion items={items} allowMultiple />| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| items | TigerAccordionItemConfig[] | — | Secciones (requerido) |
| allowMultiple | boolean | false | Abre varias a la vez |
| defaultExpandedId | string | — | Sección abierta inicial |
| onExpandedChange | (id: string) => void | — | Callback |
TigerAccordionItemConfig: id, title, content, icon?, disabled?
TigerList / TigerListItem
Lista estructurada con íconos y divisores opcionales.
import { TigerList, TigerListItem, ComponentSize } from '@jonapin006/tiger';
import { User, Settings, LogOut } from 'lucide-react';
<TigerList size={ComponentSize.Medium} divided>
<TigerListItem icon={<User size={16} />}>Perfil</TigerListItem>
<TigerListItem icon={<Settings size={16} />}>Configuración</TigerListItem>
<TigerListItem icon={<LogOut size={16} />}>Cerrar sesión</TigerListItem>
</TigerList>TigerList
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| size | ComponentSize | Medium | Tamaño (excluye xsmall) |
| divided | boolean | true | Línea divisoria entre ítems |
TigerListItem
| Prop | Tipo | Descripción |
|------|------|-------------|
| icon | ReactNode | Ícono a la izquierda |
| typographySize | TypographySize | Sobreescribe tamaño tipográfico |
TigerTable
Tabla de datos con sub-componentes semánticos.
import {
TigerTable, TigerThead, TigerTbody,
TigerTr, TigerTh, TigerTd,
ComponentSize
} from '@jonapin006/tiger';
<TigerTable size={ComponentSize.Medium}>
<TigerThead>
<TigerTr isHeader>
<TigerTh>Nombre</TigerTh>
<TigerTh>Email</TigerTh>
<TigerTh>Estado</TigerTh>
</TigerTr>
</TigerThead>
<TigerTbody>
{users.map((user) => (
<TigerTr key={user.id}>
<TigerTd>{user.name}</TigerTd>
<TigerTd>{user.email}</TigerTd>
<TigerTd>
<TigerBadge variant={TigerBadgeVariant.Success}>{user.status}</TigerBadge>
</TigerTd>
</TigerTr>
))}
</TigerTbody>
</TigerTable>Todos los sub-componentes aceptan size?: ComponentSize y className?: string. TigerTr acepta isHeader?: boolean. TigerTh y TigerTd aceptan typographySize?: TypographySize.
TigerModal
Diálogo modal con overlay y pie de página.
import { TigerModal, TigerButton, TigerButtonVariant, ComponentSize } from '@jonapin006/tiger';
const [open, setOpen] = useState(false);
<TigerModal
isOpen={open}
onClose={() => setOpen(false)}
title="Confirmar acción"
size={ComponentSize.Medium}
footer={
<>
<TigerButton variant={TigerButtonVariant.Ghost} onClick={() => setOpen(false)}>
Cancelar
</TigerButton>
<TigerButton variant={TigerButtonVariant.Primary} onClick={handleConfirm}>
Confirmar
</TigerButton>
</>
}
>
<p>¿Estás seguro de que deseas continuar?</p>
</TigerModal>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| isOpen | boolean | — | Visibilidad (requerido) |
| onClose | () => void | — | Callback al cerrar (requerido) |
| title | string | — | Título del header |
| footer | ReactNode | — | Contenido del footer |
| size | ComponentSize | Medium | Ancho máximo (excluye xsmall) |
| showCloseButton | boolean | true | Muestra botón × |
TigerMessage
Alerta o mensaje con ícono, título y acciones.
import { TigerMessage, TigerMessageVariant } from '@jonapin006/tiger';
import { AlertCircle } from 'lucide-react';
// Simple
<TigerMessage
variant={TigerMessageVariant.Info}
title="Tu plan se renueva el 15 de enero."
/>
// Con descripción, ícono y cierre
<TigerMessage
variant={TigerMessageVariant.Error}
title="Error de conexión"
description="No se pudo conectar al servidor."
icon={<AlertCircle />}
onClose={() => setVisible(false)}
action={
<TigerButton size={ComponentSize.Small} onClick={retry}>
Reintentar
</TigerButton>
}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| title | string | — | Título (requerido) |
| variant | TigerMessageVariant | Info | Tipo/color |
| description | ReactNode | — | Detalle del mensaje |
| icon | ReactNode | — | Ícono personalizado |
| action | ReactNode | — | Botones o acciones |
| onClose | () => void | — | Si se provee, muestra botón de cierre |
TigerToast
Notificaciones temporales. Requiere TigerToastContainer en el layout raíz.
import { TigerToastContainer, useToast } from '@jonapin006/tiger';
// En el layout raíz (una sola vez):
<TigerToastContainer />
// En cualquier componente:
function SaveButton() {
const { addToast } = useToast();
return (
<TigerButton onClick={() =>
addToast({
title: 'Guardado',
description: 'Los cambios se guardaron correctamente.',
type: 'success',
})
}>
Guardar
</TigerButton>
);
}Opciones de addToast
| Campo | Tipo | Descripción |
|-------|------|-------------|
| title | string | Título del toast |
| description | string | Descripción (opcional) |
| type | 'info' \| 'success' \| 'warning' \| 'error' \| 'neutral' | Tipo visual |
TigerProgress
Barra de progreso o indicador de pasos.
import { TigerProgress, ComponentSize } from '@jonapin006/tiger';
// Barra de progreso (0–100)
<TigerProgress value={65} size={ComponentSize.Medium} />
// Sin porcentaje visible
<TigerProgress value={30} showValue={false} />
// Valor máximo personalizado
<TigerProgress value={750} max={1000} />
// Por pasos
<TigerProgress
variant="steps"
currentStep={3}
totalSteps={5}
size={ComponentSize.Large}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| variant | 'bar' \| 'steps' | 'bar' | Tipo de indicador |
| value | number | 0 | Valor actual (para bar) |
| max | number | 100 | Valor máximo (para bar) |
| currentStep | number | 0 | Paso actual (para steps) |
| totalSteps | number | 5 | Total de pasos (para steps) |
| size | ComponentSize | Medium | Tamaño (excluye xsmall) |
| showValue | boolean | true | Muestra el porcentaje |
TigerDropdown
Menú desplegable composable.
import {
TigerDropdown,
TigerDropdownTrigger,
TigerDropdownContent,
TigerDropdownItem,
ComponentSize,
} from '@jonapin006/tiger';
<TigerDropdown size={ComponentSize.Medium}>
<TigerDropdownTrigger label="Opciones" value="Selecciona una opción" />
<TigerDropdownContent>
<TigerDropdownItem value="edit" onClick={handleEdit}>Editar</TigerDropdownItem>
<TigerDropdownItem value="duplicate" onClick={handleDuplicate}>Duplicar</TigerDropdownItem>
<TigerDropdownItem value="delete" onClick={handleDelete} disabled>Eliminar</TigerDropdownItem>
</TigerDropdownContent>
</TigerDropdown>TigerDropdown
| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| size | ComponentSize | Medium | Ancho mínimo del contenido |
| defaultOpen | boolean | false | Estado abierto inicial |
TigerDropdownTrigger: label?: string, value?: ReactNode
TigerDropdownItem: value?: string, onClick, disabled?: boolean
TigerSidebar
Barra de navegación lateral con soporte para subelementos.
import { TigerSidebar } from '@jonapin006/tiger';
import { Home, Users, Settings, BarChart } from 'lucide-react';
const items = [
{ id: 'dashboard', label: 'Dashboard', icon: Home },
{
id: 'users',
label: 'Usuarios',
icon: Users,
children: [
{ id: 'users-list', label: 'Lista', icon: Users },
{ id: 'users-roles', label: 'Roles', icon: Users },
],
},
{ id: 'analytics', label: 'Analíticas', icon: BarChart },
{ id: 'settings', label: 'Configuración', icon: Settings },
];
<TigerSidebar
items={items}
activeId="dashboard"
onItemSelect={(id) => navigate(id)}
header={<Logo />}
footer={<UserProfile />}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| items | SidebarItem[] | — | Ítems de navegación (requerido) |
| activeId | string | — | ID del ítem activo (requerido) |
| onItemSelect | (id: string) => void | — | Callback de selección (requerido) |
| header | ReactNode | — | Encabezado (ej: logo) |
| footer | ReactNode | — | Pie (ej: perfil de usuario) |
SidebarItem: id, label, icon: React.ElementType, children?: SidebarItem[]
TigerTopBar
Encabezado de página con título, descripción y acciones.
import { TigerTopBar, ComponentSize } from '@jonapin006/tiger';
<TigerTopBar
title="Panel de Control"
description="Resumen general del sistema"
size={ComponentSize.Large}
actions={
<TigerButton variant={TigerButtonVariant.Primary} iconLeft={Plus}>
Nueva entrada
</TigerButton>
}
/>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| title | ReactNode | — | Título principal |
| description | ReactNode | — | Descripción secundaria |
| actions | ReactNode | — | Área derecha (botones, etc.) |
| size | ComponentSize.Medium \| .Large \| .Xlarge | Large | Tamaño tipográfico del título |
| titleTypographySize | TypographySize | — | Sobreescribe tamaño del título |
| descriptionTypographySize | TypographySize | — | Sobreescribe tamaño de la descripción |
TigerThumbnail
Avatar o imagen miniatura con forma y estilo configurables.
import { TigerThumbnail, TigerThumbnailVariant, ThumbnailShape, ComponentSize } from '@jonapin006/tiger';
// Con imagen
<TigerThumbnail
src="/avatars/user.jpg"
alt="Avatar"
size={ComponentSize.Medium}
shape={ThumbnailShape.Circle}
/>
// Inicial sin imagen
<TigerThumbnail
size={ComponentSize.Large}
variant={TigerThumbnailVariant.Soft}
shape={ThumbnailShape.Squircle}
>
JD
</TigerThumbnail>| Prop | Tipo | Default | Descripción |
|------|------|---------|-------------|
| src | string | — | URL de la imagen |
| alt | string | — | Texto alternativo |
| size | ComponentSize | Medium | Tamaño |
| shape | ThumbnailShape | Squircle | Forma |
| variant | TigerThumbnailVariant | Soft | Estilo cuando no hay imagen |
| bgColor | string | — | Color de fondo personalizado |
TigerGlassContainer
Contenedor con efecto glassmorphism del tema activo.
import { TigerGlassContainer } from '@jonapin006/tiger';
// Estático
<TigerGlassContainer>
<TigerTypography>Contenido en vidrio</TigerTypography>
</TigerGlassContainer>
// Interactivo (aplica hover automáticamente)
<TigerGlassContainer onClick={() => openDetail()}>
<TigerTypography weight="bold">Tarjeta</TigerTypography>
</TigerGlassContainer>| Prop | Tipo | Descripción |
|------|------|-------------|
| onClick | () => void | Si se provee, aplica estilos interactivos |
| className | string | Clases CSS adicionales |
Acepta todos los atributos nativos de <div>.
TigerDashboardLayout
Layout principal de la aplicación: sidebar + topbar + contenido.
import { TigerDashboardLayout } from '@jonapin006/tiger';
<TigerDashboardLayout
sidebar={
<TigerSidebar
items={navItems}
activeId={activeRoute}
onItemSelect={navigate}
header={<Logo />}
/>
}
topbar={
<TigerTopBar title={pageTitle} actions={<UserMenu />} />
}
>
<Outlet />
</TigerDashboardLayout>| Prop | Tipo | Descripción |
|------|------|-------------|
| sidebar | ReactNode | Navegación lateral (requerido) |
| topbar | ReactNode | Encabezado (requerido) |
| children | ReactNode | Contenido de la página (requerido) |
| className | string | Clases CSS adicionales |
🎨 Crear un tema personalizado
Cada tema implementa la interfaz ThemeDefinition. Los tamaños de cada componente definen sus propiedades de forma independiente para sobreescritura granular.
import type { ThemeDefinition } from '@jonapin006/tiger';
import { TypographySize, ThemeMode } from '@jonapin006/tiger';
export const myTheme: ThemeDefinition = {
name: 'Mi Tema',
subName: '',
pageTitle: 'Mi App',
websiteUrl: 'https://miapp.com',
defaultMode: ThemeMode.Light,
geometry: {
typography: {
xsmall: 'text-[10px] font-medium',
small: 'text-[12px] font-medium',
medium: 'text-[14px] font-semibold',
large: 'text-[18px] font-bold',
xlarge: 'text-[32px] font-black',
weights: {
bold: 'font-black',
semibold: 'font-semibold',
normal: 'font-medium',
},
styles: {
italic: 'italic',
normal: '',
underline: 'underline',
strikethrough: 'line-through',
},
},
buttons: {
small: { height: 'h-8', padding: 'px-4', corner: 'rounded-md', typography: TypographySize.Small },
medium: { height: 'h-10', padding: 'px-5', corner: 'rounded-lg', typography: TypographySize.Medium },
large: { height: 'h-12', padding: 'px-6', corner: 'rounded-xl', typography: TypographySize.Large },
xlarge: { height: 'h-14', padding: 'px-8', corner: 'rounded-2xl', typography: TypographySize.Xlarge },
none: { height: 'h-0 overflow-hidden', padding: 'px-0', corner: 'rounded-none', typography: TypographySize.Small },
baseTypography: 'text-inherit leading-none font-bold whitespace-nowrap',
baseStyles: 'transition-all duration-300 active:scale-95 disabled:opacity-50 inline-flex items-center justify-center shrink-0',
layout: {
container: 'inline-flex items-center justify-center gap-2',
icon: 'w-[1.2em] h-[1.2em] shrink-0',
fullWidth: 'w-full',
},
},
// ... resto de la geometría
},
modes: {
light: { /* ThemeModeConfig */ },
dark: { /* ThemeModeConfig */ },
},
};🏗️ Excelencia Arquitectónica
- Zero-Override Architecture: Ningún componente de Tiger tiene clases de estilo hardcoded que necesiten ser "pisadas". El componente es una estructura pura que se viste con los tokens del tema activo.
- Clean Architecture: Separación estricta entre Domain (Tipos/Enums), Application (Theme Context), Infrastructure (Temas Físicos) y Presentation (UI Components).
- SOLID Principles: Componentes desacoplados, abiertos a extensión pero cerrados a modificación, cumpliendo con responsabilidad única (SRP).
- Scale System: Sistema de 4 niveles de tamaño (S, M, L, XL) que sincroniza espaciado, tipografía y elevación en toda la librería.
- Theme Agnostic: El componente no sabe cómo se ve; simplemente consume un contrato de tokens de geometría. Cambia el archivo del tema (Glassmorphism, Mandala, MisPuntos) y la UI se transformará por completo sin tocar el componente.
📄 Licencia
Tiger Design System es propiedad intelectual privada de jonapin006.
