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

ayudacreativa-ui

v5.5.2

Published

Design system de AC — componentes React y tokens de diseño para productos de Ayuda Creativa

Readme

ayudacreativa-ui

Sistema de diseño oficial de Ayuda Creativa — componentes React, tokens de diseño y patrones de interfaz para productos AC.

npm license


Instalación

npm install ayudacreativa-ui

Requisitos: React ≥ 18 · Node ≥ 18 · TypeScript ≥ 5.0


Inicio rápido

1. Importa los tokens CSS

En el punto de entrada de tu app (ej. main.tsx):

import "ayudacreativa-ui/tokens.css";

2. Aplica el tema en el elemento raíz

<div data-theme="light">...</div>   <!-- Claro -->
<div data-theme="dark">...</div>    <!-- Oscuro -->
<div data-theme="system">...</div>  <!-- Sigue el sistema operativo -->

3. Importa y usa los componentes

import {
  AcButton, AcBadge, AcInput, AcTextarea, AcCheckbox, AcSelect, AcDatePicker, AcToggle, AcTooltip,
  AcAccordion, AcCard, AcDynamicForm, AcTitles,
  useForm,
} from "ayudacreativa-ui";

Componentes

Átomos

<AcButton>

<AcButton variant="primary">Guardar</AcButton>
<AcButton variant="secondary">Cancelar</AcButton>
<AcButton variant="ghost">Ver más</AcButton>
<AcButton variant="danger">Eliminar</AcButton>
<AcButton variant="primary" loading>Guardando...</AcButton>
<AcButton variant="primary" size="sm">Pequeño</AcButton>

| Prop | Tipo | Default | Descripción | | --------- | ---------------------------------------------------------------- | --------- | -------------------------------------------------- | | variant | primary \| secondary \| ghost \| danger \| icon \| icon-ghost | primary | Estilo visual | | size | md \| sm | md | Tamaño | | loading | boolean | false | Muestra spinner y deshabilita | | color | string | — | Color personalizado (sobreescribe el del variant) |


<AcBadge>

<AcBadge id="b1" variant="activa">Activa</AcBadge>
<AcBadge id="b2" variant="pendiente">Pendiente</AcBadge>
<AcBadge id="b3" variant="error">Error</AcBadge>
<AcBadge id="b4" variant="borrador">Borrador</AcBadge>
<AcBadge id="b5" variant="conectado">Conectado</AcBadge>
<AcBadge id="b6" variant="pro">Pro</AcBadge>

Con ícono:

<AcBadge id="b7" variant="activa" icon="Check">Activa</AcBadge>
<AcBadge id="b8" variant="error"  icon="AlertCircle">Error</AcBadge>

Canales de distribución:

<AcBadge id="b9"  variant="whatsapp" icon="MessageCircle">WhatsApp</AcBadge>
<AcBadge id="b10" variant="email"    icon="Mail">Email</AcBadge>
<AcBadge id="b11" variant="widget"   icon="Layout">Widget</AcBadge>
<AcBadge id="b12" variant="sms"      icon="Smartphone">SMS</AcBadge>

| Prop | Tipo | Default | Descripción | | ----------- | ----------------- | ------- | ---------------------------------- | | id | string | — | Identificador único (requerido) | | variant | IBadgeVariant | — | Estilo visual | | icon | IIconName | — | Ícono del registro antes del texto | | className | string | "" | Clases adicionales |


FieldInputs

Grupo de componentes de entrada de datos: AcInput, AcSelect, AcDatePicker y AcToggle.

<AcInput>

<AcInput placeholder="Correo electrónico" />
<AcInput iconLeft="Search" placeholder="Buscar..." />
<AcInput iconRight="Eye" type="password" />
<AcInput error="Este campo es requerido" value={value} onChange={handleChange} />

| Prop | Tipo | Descripción | | ----------- | ----------- | ----------------------------------- | | iconLeft | IIconName | Ícono izquierdo | | iconRight | IIconName | Ícono derecho | | error | string | Mensaje de error — pinta borde rojo |


<AcSelect>

Dropdown personalizado con búsqueda opcional.

<AcSelect
  options={[
    { value: "co", label: "Colombia" },
    { value: "ar", label: "Argentina" },
  ]}
  value={value}
  onChange={setValue}
  placeholder="Selecciona un país"
/>

Con búsqueda interna:

<AcSelect options={options} value={value} onChange={setValue} searchable />

Con error:

<AcSelect options={options} error="Campo requerido" />

| Prop | Tipo | Default | Descripción | | ------------- | ------------------------ | ------------------ | --------------------------------------- | | options | ISelectOption[] | — | Array de { value: string, label: string } | | value | string | — | Valor seleccionado | | onChange | (value: string) => void| — | Callback al seleccionar | | searchable | boolean | false | Activa input de búsqueda en el dropdown | | placeholder | string | "Seleccionar..." | Texto cuando no hay valor | | error | string | — | Mensaje de error | | disabled | boolean | false | Deshabilita el componente |


<AcDatePicker>

Selector de fecha con cuatro modos y soporte para festivos colombianos.

Fecha individual:

<AcDatePicker value={value} onChange={setValue} />

Rango de fechas:

<AcDatePicker
  mode="range"
  valueStart={start}
  valueEnd={end}
  onRangeChange={(s, e) => { setStart(s); setEnd(e); }}
/>

Período mes/año — solo año:

<AcDatePicker mode="month" value={value} onChange={setValue} />
<AcDatePicker mode="year"  value={value} onChange={setValue} />

Con festivos de Colombia:

<AcDatePicker
  mode="range"
  valueStart={start}
  valueEnd={end}
  onRangeChange={handleRange}
  showHolidays
/>

| Prop | Tipo | Default | Descripción | | ---------------- | ---------------------------------- | -------------------- | ---------------------------------------------------- | | mode | single \| range \| month \| year | single | Modo de selección | | value | string | — | ISO para single (YYYY-MM-DD), month (YYYY-MM), year (YYYY) | | onChange | (value: string) => void | — | Callback para single, month, year | | valueStart | string | — | ISO inicio para range | | valueEnd | string | — | ISO fin para range | | onRangeChange | (start, end) => void | — | Callback para range | | showHolidays | boolean | false | Resalta festivos colombianos con punto rojo y tooltip | | placeholder | string | "Seleccionar..." | Texto cuando no hay valor | | error | string | — | Mensaje de error | | disabled | boolean | false | Deshabilita el componente |


<AcTextarea>

<AcTextarea placeholder="Escribe tu mensaje..." />
<AcTextarea value={value} onChange={(e) => setValue(e.target.value)} rows={6} />
<AcTextarea error="Mínimo 20 caracteres" />
<AcTextarea disabled />

| Prop | Tipo | Descripción | |------------|-----------|-------------------------------------| | error | string | Mensaje de error — pinta borde rojo | | rows | number | Número de filas visibles (default 4)| | disabled | boolean | Deshabilita la interacción |


<AcCheckbox>

<AcCheckbox checked={checked} onChange={setChecked} label="Acepto los términos" />
<AcCheckbox checked={false} onChange={() => {}} error="Campo requerido" />
<AcCheckbox checked={true} onChange={() => {}} disabled />

| Prop | Tipo | Descripción | |------------|------------------------------|-------------------------------------| | checked | boolean | Estado del checkbox | | onChange | (checked: boolean) => void | Callback al cambiar | | label | string | Texto descriptivo | | error | string | Mensaje de error | | disabled | boolean | Deshabilita la interacción |


<AcTooltip>

Tooltip con tres variantes, cuatro posiciones y control externo de visibilidad. Se ajusta automáticamente si el trigger está cerca del borde del viewport.

Texto plano:

<AcTooltip content="Copiar al portapapeles" placement="top">
  <AcButton variant="ghost" size="sm">Hover aquí</AcButton>
</AcTooltip>

Título y descripción (variant="rich"):

<AcTooltip variant="rich" title="Ayuda" description="Más contexto aquí." placement="bottom">
  <AcButton variant="secondary">?</AcButton>
</AcTooltip>

Con acciones — permanece abierto al hacer hover sobre el tooltip (variant="action"):

<AcTooltip
  variant="action"
  placement="right"
  title="¿Eliminar?"
  description="Esta acción no se puede deshacer."
  actions={[
    { label: "Cancelar", variant: "ghost",  onClick: () => {} },
    { label: "Eliminar", variant: "primary", onClick: handleDelete },
  ]}
>
  <AcButton variant="danger" size="sm">Eliminar</AcButton>
</AcTooltip>

Control externo — útil para onboarding y tutoriales:

<AcTooltip variant="rich" title="Paso 1" open={open}>
  <AcButton>Trigger</AcButton>
</AcTooltip>

Deshabilitado por condición de negocio:

<AcTooltip content="Acción disponible" disabled={!hasPermission}>
  <AcButton>Acción</AcButton>
</AcTooltip>

| Prop | Tipo | Default | Descripción | |-------------|-----------------------------------|----------|-----------------------------------------------------------| | variant | text \| rich \| action | text | Estilo visual | | placement | top \| bottom \| left \| right | top | Posición respecto al trigger (se invierte si no hay espacio) | | content | string | — | Texto para variant="text" | | title | string | — | Título para rich / action | | description| string | — | Descripción para rich / action | | actions | ITooltipAction[] | — | Botones para variant="action" | | disabled | boolean | false | Bloquea el tooltip completamente | | open | boolean | — | Control externo — si se define, el hover interno se ignora|


<AcToggle>

<AcToggle checked={activo} onChange={setActivo} label="Encuesta activa" />

| Prop | Tipo | Descripción | | ---------- | ---------------------------- | -------------------------- | | checked | boolean | Estado del toggle | | onChange | (checked: boolean) => void | Callback al cambiar | | label | string | Texto descriptivo | | disabled | boolean | Deshabilita la interacción |


<AcAvatar>

<AcAvatar name="Alexander Rodríguez" size="md" />
<AcAvatar src="/foto.jpg" name="Alexander Rodríguez" size="lg" />

| Prop | Tipo | Default | Descripción | | ------ | ---------------- | ------- | ---------------------------------------------- | | name | string | — | Nombre para generar iniciales y accesibilidad | | src | string | — | URL de imagen | | size | sm \| md \| lg | md | Tamaño (28 / 36 / 44 px) |


<AcThemeSwitch>

Selector de tema con opciones Light / Dark / System.

<AcThemeSwitch />

Moléculas

<AcAccordion>

Acordeón con soporte para ítems múltiples o exclusivo (solo uno abierto a la vez).

import { AcAccordion } from "ayudacreativa-ui";
import type { IAccordionItem } from "ayudacreativa-ui";

const items: IAccordionItem[] = [
  { id: "1", title: "¿Qué es Ayuda Creativa?", content: "Plataforma de diseño..." },
  { id: "2", title: "¿Cómo inicio?",           content: "Instala el paquete..." },
  { id: "3", title: "¿Tiene soporte?",          content: "Sí, escríbenos a...", disabled: true },
];

Múltiple (varios abiertos a la vez) — exclusivo — con ítem abierto por defecto:

<AcAccordion items={items} />
<AcAccordion items={items} multiple={false} />
<AcAccordion items={items} defaultOpen={["1"]} />

| Prop | Tipo | Default | Descripción | |---------------|--------------------|---------|-------------------------------------------------| | items | IAccordionItem[] | — | Lista de ítems | | multiple | boolean | true | Permite varios ítems abiertos simultáneamente | | defaultOpen | string[] | [] | IDs de ítems abiertos al montar |

IAccordionItem: { id, title, content: ReactNode, disabled? }


<AcTitles>

Encabezado de sección con ícono, título en negrita y descripción opcional.

<AcTitles
  id="config"
  icon="Settings"
  iconColor="var(--ac-brand)"
  title="Configuración"
  description="Ajusta las preferencias de tu cuenta."
/>

Sin ícono:

<AcTitles id="users" title="Usuarios" description="Gestiona el equipo." />

| Prop | Tipo | Descripción | |---------------|-------------|------------------------------------------------------| | id | string | Identificador único (requerido) | | icon | IIconName | Ícono del registro de íconos | | iconColor | string | Color de fondo del ícono (acepta cualquier valor CSS)| | title | string | Texto principal (negrita) | | description | string | Texto secundario (opcional) |


<AcDynamicForm>

Formulario completamente dinámico que consume useForm internamente.

import { AcDynamicForm } from "ayudacreativa-ui";
import type { IFormItem } from "ayudacreativa-ui";

const fields: IFormItem[] = [
  {
    type: "group",
    title: "Datos personales",
    description: "Información básica del usuario.",
    icon: "User",
    iconColor: "var(--ac-brand)",
    fields: [
      { name: "nombre", type: "text",  label: "Nombre",  rules: { required: true } },
      { name: "email",  type: "email", label: "Correo",  rules: { required: true } },
    ],
  },
  { name: "mensaje", type: "textarea", label: "Mensaje", rules: { minLength: 10 } },
  { name: "acepto",  type: "checkbox", label: "Acepto los términos", rules: { required: true } },
];

<AcDynamicForm
  fields={fields}
  onSubmit={(values) => console.log(values)}
  submitLabel="Enviar"
/>

IFormItem es un discriminated union entre IFormFieldConfig y IFormFieldGroup.

IFormFieldGroup: { type: "group"; title; description?; icon?; iconColor?; fields: IFormFieldConfig[] }

Tipos de campo soportados: text | email | password | number | textarea | select | toggle | checkbox | datepicker

| Prop | Tipo | Default | Descripción | |---------------|---------------------------------|-------------|------------------------------------------| | fields | IFormItem[] | — | Definición de campos y grupos | | onSubmit | (values: IFormValues) => void | — | Callback al hacer submit válido | | submitLabel | string | "Enviar" | Texto del botón de envío | | loading | boolean | false | Deshabilita el botón durante peticiones |


<AcCard>

<AcCard>Contenido por defecto</AcCard>
<AcCard variant="metric">Widget KPI</AcCard>
<AcCard variant="accent-left">Destacado con borde brand</AcCard>
<AcCard hoverable>Hover con efecto en borde</AcCard>

| Prop | Tipo | Default | Descripción | | ----------- | ---------------------------------- | --------- | ------------------- | | variant | default \| metric \| accent-left | default | Estilo visual | | hoverable | boolean | false | Activa efecto hover |


<AcPagination>

<AcPagination
  currentPage={currentPage}
  totalPages={totalPages}
  onPageChange={goToPage}
  siblings={1}
  showInfo
/>

| Prop | Tipo | Default | Descripción | | -------------- | ------------------------ | ------- | ----------------------------------------- | | currentPage | number | — | Página activa (1-indexed) | | totalPages | number | — | Total de páginas | | onPageChange | (page: number) => void | — | Callback al cambiar página | | siblings | number | 1 | Páginas visibles a cada lado de la activa | | showInfo | boolean | false | Muestra "Página X de Y" |


Organismos

<AcTable>

Tabla con paginación, sort y skeleton integrados.

import { AcTable } from "ayudacreativa-ui";
import type { ITableColumn } from "ayudacreativa-ui";

type Survey = { id: number; nombre: string; estado: string };

const columns: ITableColumn<Survey>[] = [
  { key: "nombre", label: "Nombre", sortable: true },
  {
    key: "estado",
    label: "Estado",
    align: "center",
    render: (row) => <AcBadge id={`estado-${row.id}`} variant={row.estado}>{row.estado}</AcBadge>,
  },
];

<AcTable<Survey>
  columns={columns}
  data={surveys}
  rowKey="id"
  pageSize={10}
  titleTable="Encuestas"
  loading={isLoading}
  onRowClick={(row) => navigate(`/encuestas/${row.id}`)}
/>

| Prop | Tipo | Default | Descripción | | ------------------ | ---------------------- | ------------------ | --------------------------- | | columns | ITableColumn<T>[] | — | Definición de columnas | | data | T[] | — | Dataset completo | | rowKey | keyof T \| fn | "id" | Clave única por fila | | pageSize | number | 10 | Filas por página | | loading | boolean | false | Muestra skeleton | | titleTable | string | — | Título sobre la tabla | | descriptionTable | string | — | Descripción sobre la tabla | | emptyTitle | string | "Sin resultados" | Título en estado vacío | | onRowClick | (row, index) => void | — | Click en fila |


<AcToast> / AcToastProvider

Sistema de notificaciones flotantes con auto-dismiss.

import { AcToastProvider, useToast } from "ayudacreativa-ui";

// En la raíz de la app
<AcToastProvider position="bottom-right" maxToasts={5}>
  <App />
</AcToastProvider>

// En cualquier componente
function MiComponente() {
  const { toast } = useToast();

  return (
    <button onClick={() => toast({ variant: "success", title: "Guardado", duration: 4000 })}>
      Guardar
    </button>
  );
}

| Prop | Tipo | Default | Descripción | | ----------- | -------------------------------------------------------------------------------------- | -------------- | ---------------------------------------- | | variant | success \| danger \| warning \| info | info | Tipo de notificación | | title | string | — | Texto principal | | description| string | — | Texto secundario (opcional) | | duration | number | 4000 | ms antes de auto-cerrar (0 = sin cierre) | | position | bottom-right \| bottom-left \| top-right \| top-left \| bottom-center \| top-center | bottom-right | Posición en pantalla |


<AcModal>

import { AcModal } from "ayudacreativa-ui";

<AcModal
  isOpen={open}
  onClose={() => setOpen(false)}
  title="¿Eliminar encuesta?"
  subtitle="Esta acción no se puede deshacer."
  variant="danger"
  showCloseButton
  closeOnOverlay
  buttons={[
    { label: "Cancelar", variant: "ghost", onClick: () => setOpen(false) },
    { label: "Eliminar", variant: "danger", onClick: handleDelete },
  ]}
/>

| Prop | Tipo | Default | Descripción | | ----------------- | ---------------------------- | --------- | --------------------------- | | isOpen | boolean | — | Controla visibilidad | | title | string | — | Título principal | | subtitle | string | — | Texto secundario | | variant | default \| danger \| info | default | Estilo visual | | size | default \| wide \| compact | default | Ancho (420 / 560 / 320 px) | | showCloseButton | boolean | false | Muestra botón ✕ | | closeOnOverlay | boolean | false | Cierra al hacer clic fuera | | buttons | IModalButton[] | [] | Acciones del modal | | onClose | () => void | — | Callback al cerrar |


Hooks

useForm

Hook para formularios con validación reactiva. Gestiona estado, errores y submit.

import { useForm } from "ayudacreativa-ui";
import type { IFormFieldConfig } from "ayudacreativa-ui";

const fields: IFormFieldConfig[] = [
  {
    name: "email",
    type: "email",
    label: "Correo",
    rules: {
      required: "El correo es obligatorio",
      pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "Formato inválido" },
    },
  },
  {
    name: "mensaje",
    type: "textarea",
    label: "Mensaje",
    rules: { required: true, minLength: { value: 10, message: "Mínimo 10 caracteres" } },
  },
  { name: "acepto", type: "checkbox", label: "Acepto términos", rules: { required: true } },
];

const { values, errors, touched, isValid, setValue, setTouched, handleSubmit, reset } =
  useForm({
    fields,
    onSubmit: async (vals) => { /* guardar */ },
  });

| Retorno | Tipo | Descripción | |-----------------|------------------------------------------------|----------------------------------------------------------| | values | IFormValues | Estado actual de todos los campos | | errors | IFormErrors | Errores calculados reactivamente (via useMemo) | | touched | IFormTouched | Qué campos han sido tocados (para mostrar errores) | | isValid | boolean | true cuando no hay ningún error | | isSubmitting | boolean | true mientras onSubmit está en curso | | setValue | (name, value) => void | Actualiza el valor de un campo | | setTouched | (name) => void | Marca un campo como tocado | | handleSubmit | (e?) => void | Marca todos como tocados y llama onSubmit si es válido | | reset | () => void | Restaura valores y touched a su estado inicial |

Reglas de validación (IFormFieldRules):

rules: {
  required: true | "mensaje personalizado",
  minLength: 3 | { value: 3, message: "Mínimo 3" },
  maxLength: 100 | { value: 100, message: "Máximo 100" },
  min: 0 | { value: 0, message: "Debe ser ≥ 0" },
  max: 100 | { value: 100, message: "Debe ser ≤ 100" },
  pattern: /regex/ | { value: /regex/, message: "Formato inválido" },
  validate: (value) => string | undefined,
}

useTheme

Gestiona el tema de la aplicación escribiendo en data-theme del elemento <html>.

import { useTheme } from "ayudacreativa-ui";
import type { IThemeMode } from "ayudacreativa-ui";

const { theme, changeTheme, readCurrentTheme } = useTheme();
// theme: "light" | "dark" | "system"

changeTheme("dark");        // actualiza estado + DOM
readCurrentTheme();         // lee data-theme del DOM directamente

| Retorno | Tipo | Descripción | | ------------------ | --------------------------- | -------------------------------------------------- | | theme | IThemeMode | Estado React del tema activo | | changeTheme(mode)| void | Cambia el tema y escribe data-theme en <html> | | readCurrentTheme() | IThemeMode | Lee data-theme del DOM en tiempo real |


usePagination

Paginación cliente para usar junto con <AcTable> o cualquier lista.

import { usePagination } from "ayudacreativa-ui";

const {
  pageData,     // T[] — slice de datos de la página actual
  currentPage,  // number — página activa (1-indexed)
  totalPages,   // number
  totalItems,   // number
  from, to,     // índices visibles para "Mostrando X–Y de Z"
  goToPage,     // (page: number) => void — clampea automáticamente
  nextPage,     // () => void
  prevPage,     // () => void
  reset,        // () => void — vuelve a página 1 (útil al filtrar)
} = usePagination({ data, pageSize: 10, initialPage: 1 });

useColombiaHolidays

Hook y utilidades para consultar los festivos colombianos (Ley 51/1983). Calcula festivos de fecha fija, "puentes" y los basados en Pascua (algoritmo Meeus/Jones/Butcher).

import {
  useColombiaHolidays,
  isColombiaHoliday,
  getColombiaHolidayName,
  getColombiaHolidaysByMonth,
  getColombiaHolidaysByYearList,
} from "ayudacreativa-ui";

// Hook (con memoización)
const { holidays, isHoliday, getHolidayName } = useColombiaHolidays({ year: 2026 });
const { holidays } = useColombiaHolidays({ year: 2026, month: 5 }); // solo mayo

isHoliday("2026-05-01")       // → true
getHolidayName("2026-05-01")  // → "Día del Trabajo"

// Funciones puras (sin React — útiles en scripts, tests, SSR)
isColombiaHoliday("2026-07-20")          // → true
getColombiaHolidayName("2026-12-25")     // → "Navidad"
getColombiaHolidaysByMonth(12, 2026)     // → [{ date, name }, ...]
getColombiaHolidaysByYearList(2026)      // → ColombiaHoliday[] ordenado

| Prop / Retorno | Tipo | Descripción | | ------------------- | ------------------------------- | ------------------------------------------------------- | | year | number | Año a consultar (default: año actual) | | month | number (1–12) | Si se pasa, filtra solo ese mes | | holidays | IColombiaHoliday[] | Lista ordenada de festivos del período | | holidayMap | Map<string, string> | Map ISO→nombre para acceso O(1) | | isHoliday(iso) | boolean | ¿Es festivo la fecha ISO indicada? | | getHolidayName(iso) | string \| null | Nombre del festivo o null |

interface IColombiaHoliday {
  date: string; // "YYYY-MM-DD"
  name: string; // nombre oficial del festivo
}

Tokens de diseño

Los tokens se cargan automáticamente al importar cualquier componente. También puedes importarlos directamente:

import "ayudacreativa-ui/tokens.css";

Colores de marca

| Variable | Valor | Uso | | ------------------ | --------- | ---------------------- | | --ac-brand | #039be5 | Color principal | | --ac-brand-dark | #0277b0 | Hover brand | | --ac-brand-light | #e3f5fd | Fondos sutiles (light) | | --ac-success | #0f7b33 | Estados positivos | | --ac-danger | #ab1707 | Errores y destructivos | | --ac-warning | #f5a623 | Advertencias |

Variables semánticas por tema

| Variable | Light | Dark | | ------------ | --------- | --------------------------- | | --ac-bg1 | #ffffff | #1a1f2e | | --ac-bg2 | #f0f1f4 | #242938 | | --ac-t1 | #1a1f2e | #f0f1f4 | | --ac-t2 | #5c6380 | #9da5bc | | --ac-t3 | #9da5bc | #5c6380 | | --ac-bdc | #e2e4e9 | rgba(255, 255, 255, 0.08) |


Storybook

Explora todos los componentes y hooks de forma interactiva:

npm run dev   # http://localhost:6006

Contribuir

  1. Haz fork del repositorio
  2. Crea una rama: git checkout -b feature/nombre-componente
  3. Asegúrate de que npm run lint y npm run build pasen
  4. Crea un PR — incluye screenshots de Storybook

Commits con formato automático

npm run commit  # asistente interactivo (commitizen)

# O manualmente:
git commit -m "feat(select): agregar componente Select con búsqueda"
git commit -m "fix(datepicker): corregir cálculo primer día de la semana"

Publicar nueva versión

npm run release        # bump automático basado en commits
npm run release:patch  # 4.0.1 → 4.0.2
npm run release:minor  # 4.0.1 → 4.1.0
git push --follow-tags # dispara el GitHub Action de publicación en npm

Desarrollado por Ayuda Creativa