npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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

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/tiger

2. 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.