Saltar al contenido
El Muestrario

@solu30/ui-kit v5.8.1 · registry privado · leído del paquete instalado

Cómo se usa el kit

Para el que va a escribir la próxima pantalla: qué hay adentro del paquete, cómo se instala en un repo nuevo, de qué subpath sale cada símbolo y con qué reglas se le agrega una pieza. Nada de esto está escrito a mano: se lee del paquete instalado en este mismo sitio cada vez que la página se construye.

Versión instalada
5.8.1
Docset declara
5.5.0
Subpaths
19
Símbolos distintos
1212
01

Qué es

Lo que sigue es docs/SCOPE.md, tal como viaja adentro del paquete publicado: qué entra a la librería, qué no, y dónde está el límite con un vertical. Sirve para decidir si la pieza que estás por escribir va acá o va en tu repo. No está resumido ni reescrito. Arranca declarando su propia versión, 4.13.0, que no es la que corre; la sección 05 dice qué partes de este texto envejecieron con ella.

SCOPE — @solu30/ui-kit

Package: @solu30/ui-kit Current version: 4.13.0 Maintainer: Luna (design systems) / Forge (executor)

What this package IS

Cross-vertical UI component library. Ships 80+ components, design tokens, Cloudflare image utils, and Tailwind CSS theming. Consumed by all SolaaS verticals (Dietaly, TCP, GS, EC, CC, PrepChat).

What this package is NOT

  • Not a vertical-specific component. Nothing in here can import from a vertical.
  • Not a data layer. No DB calls, no API routes, no Drizzle schemas.
  • Not a layout framework. It provides primitives; the vertical composes them.

Design token contract

Los estilos DEBEN usar tokens definidos por el cmpPreset (src/tailwind-preset.ts), que es el source of truth. Tokens válidos:

  • Fondos: bg-bkg, bg-container, bg-inner, bg-upper
  • Texto: text-content (+ opacity, ej. text-content/70)
  • Bordes: border-content, border (default --ui-border)
  • Accent / status: text-primary, bg-primary, text-green/red/yellow/purple/orange
  • Namespace interno ui-* (sólidos horneados, dirección 0.72) — VERIFICADOS en el preset: bg-ui-bg-secondary, text-ui-content-secondary, text-ui-content-muted, border-ui-border, text-ui-success/warning/error/info, text-ui-accent.
  • NUNCA hex inline ni hsl(var(--*)).

Deuda conocida (token migration — tarea trackeada): clases no definidas por el preset (clases muertas que no renderizan): text-foreground-muted/-subtle/-secondary, bg-background-secondary/-raised, border-border-subtle/-strong (~124 componentes), y los sufijos de status bg-ui-success-bg/border-ui-success-border (el preset define ui.success como color sólido, no las variantes -bg/-border, usadas hoy en tv.ts STATUS_COLORS success/warning/error/info y en tokens/colors.ts). Migración full = esfuerzo separado, con decisión de vocabulario pendiente (text-content/70 opacity vs sólidos text-ui-content-muted) y posible necesidad de DEFINIR tokens faltantes en el preset. Ver tareas del plan.

See docs/INSTRUCTIONS.md for the full authoring rules.

Scope boundaries

In scopeOut of scope
Generic UI primitives (Card, Button, Badge, …)Vertical business logic
Design tokens (semantic classes only)Inline alpha colors (/N)
Section-level pre-armed blocksbackdrop-blur
Cloudflare image utilitiesVertical-specific API calls

@solu30/ui-kit/geo → movido a @solu30/ui-geo (ADR-219)

El subpath ./geo (GeoMap, Leaflet + react-leaflet) se extrajo del foundation al package 2-domain @solu30/ui-geo como parte del split del god-package (ADR-219). Los peers pesados (leaflet/react-leaflet) viven ahora en ese package. Migración de import: @solu30/ui-kit/geo@solu30/ui-geo (nombres de símbolos idénticos). Guía completa: docs/migration/ui-kit-3.0.md.

02

Cómo se instala

Tres pasos, una vez por repo y una vez por máquina. El paquete se publica en GitHub Packages bajo el scope @solu30, y ese registry pide credenciales hasta para leer.

1 · El .npmrc en la raíz del repositorio, para que el scope apunte al registry privado. Una vez por repo, va commiteado.

# GitHub Packages, para todo el scope @solu30
@solu30:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

2 · El token, una vez por máquina. La instalación lo toma de la variable de entorno; no queda escrito en ningún archivo del repo. En CI y en Vercel es el mismo nombre de variable, con un token de alcance read:packages.

gh auth refresh --hostname github.com --scopes read:packages
NODE_AUTH_TOKEN=$(gh auth token) pnpm install

3 · Recién ahí, el paquete.

pnpm add @solu30/ui-kit

Si falla

Sin credenciales no hay camino alternativo: no existe copia pública en npm, ni tarball descargable, ni una versión recortada del paquete. Un error de autenticación del registry en @solu30/* casi siempre es el token —vencido, sin read:packages, o sin la variable exportada en esa terminal—, no el paquete: se rehace el paso 2 y se reinstala.

Los @solu30/* se consumen siempre pre-compilados, como dependencia externa. Si estás por agregar el paquete a transpilePackages para resolver algo, ese es el síntoma de otro problema.

03

Cómo se importa

La regla es una sola: se importa del subpath, no de la raíz. La raíz junta la mayoría de los barriles en un único especificador, así que entrar por ahí arrastra vocabulario que no pediste. El caso caro está documentado en el propio paquete: el mapa completo de iconos de Lucide son unos 665 KB, así que la raíz reexporta una versión sin el mapa y lo que lo necesita entra por @solu30/ui-kit/dynamic-icon, a propósito.

import { Button } from '@solu30/ui-kit/input'   // sí
import { Button } from '@solu30/ui-kit'         // no

La tabla sale del exports map del paquete instalado y de las declaraciones compiladas que ese mapa apunta. El orden es el del mapa, no uno elegido acá. Los nombres de cada subpath están en el índice de componentes; acá está de dónde sale cada uno y qué tamaño tiene esa superficie.

Se importa deSímbolosDe los cuales tipos
@solu30/ui-kit raíz11660
@solu30/ui-kit/preset20
@solu30/ui-kit/hooks1152
@solu30/ui-kit/images60
@solu30/ui-kit/forms1910
@solu30/ui-kit/editor122
@solu30/ui-kit/icons731
@solu30/ui-kit/batch-processor20
@solu30/ui-kit/markdown21
@solu30/ui-kit/tokens655
@solu30/ui-kit/utils938
@solu30/ui-kit/display24090
@solu30/ui-kit/feedback13360
@solu30/ui-kit/navigation9463
@solu30/ui-kit/data-display6232
@solu30/ui-kit/input239121
@solu30/ui-kit/providers104
@solu30/ui-kit/animation4523
@solu30/ui-kit/dynamic-icon92

La columna no se suma: la raíz reexporta casi todos los barriles, así que sumarla con ellos cuenta cada símbolo dos veces. Nombres distintos en todo el paquete: 1212.

04

Convenciones

Las reglas de autoría que viajan adentro del paquete, en docs/INSTRUCTIONS.md, sin editar. Son las que aplican al agregar o modificar un componente del kit. La primera viene anulada por su propio autor: la tabla de tokens que proponía apunta a clases que el preset nunca definió, así que no renderizan. El aviso está en el documento y se conserva — el vocabulario de reemplazo todavía no está decidido, y hasta que lo esté esa tabla no es contrato.

INSTRUCTIONS — @solu30/ui-kit

Authoring rules (MANDATORY)

1. Tokens del cmpPreset — DECISIÓN DE VOCABULARIO PENDIENTE

⚠️ Esta sección estaba ROTA y se neutralizó (task 3159). Mapeaba text-content/70text-foreground-secondary, bg-content/5bg-background-secondary, border-content/10border-border-subtle, etc. Esos tokens target NO están definidos en el cmpPreset (src/tailwind-preset.ts) — son clases muertas que no renderizan. La migración "solid colors" (dietaly/docs/plans/ui-kit-solid-colors-spec.md) se aplicó a ~124 componentes pero su vocabulario destino nunca se agregó al preset. NO sigas esta tabla.

Tokens VERIFICADOS (definidos en el preset, usar estos):

  • Fondos: bg-bkg, bg-container, bg-inner, bg-upper
  • Texto: text-content (+ opacity: text-content/70)
  • Bordes: border-content, border (default)
  • Accent/status: text-primary, text-green/red/yellow/purple/orange
  • Namespace ui-* (definidos): bg-ui-bg-secondary, text-ui-content-secondary, text-ui-content-muted, border-ui-border, text-ui-success/warning/error/info, text-ui-accent
  • NUNCA hex inline ni hsl(var(--*)).

No verificados / probablemente muertos (no usar hasta confirmar en el preset): text-foreground-*, bg-background-*, border-border-*, y los sufijos de status bg-ui-success-bg/border-ui-success-border (el preset define ui.success como string, no success-bg/success-border).

Decisión pendiente (task trackeada): elegir el vocabulario canónico — opacity (text-content/70, permitido por CLAUDE.md global) vs sólidos horneados (text-ui-content-*, dirección 0.72 del kit) — definir en el preset los tokens que falten, y migrar los ~124 componentes. Hasta entonces, esta tab NO es contrato autoritativo.

2. No hex inline, no CSS vars con /N arbitrario
text-[var(--ui-content)]/60   ← PROHIBIDO
bg-[var(--ui-primary)]/10     ← PROHIBIDO (usar token semántico o clase utilitaria)
3. tsc limpio antes de cualquier PR

pnpm --filter @solu30/ui-kit tsc --noEmit debe pasar en cero errores.

4. Modificar un componente existente
  • Leer el componente completo antes de editar.
  • Usar SOLO tokens verificados del cmpPreset (sección 1). NO migrar a text-foreground-*/bg-background-* (muertos).
  • Si encontrás clases con esos tokens muertos → es la deuda trackeada (task migración tokens), NO improvisar el reemplazo hasta que se decida el vocabulario.
5. Agregar un componente nuevo
  • Sólo clases semánticas desde el inicio.
  • Exportar desde el subpath-barrel que corresponda (src/subpath-barrels/display.ts, feedback.ts, …); el barrel raíz src/index.ts los re-exporta a todos (ADR-227), no se edita por componente.
  • Test co-locado *.test.tsx con renderKit (ver README § Tests).
  • Crear un changeset (.changeset/<slug>.md) en la misma unidad de trabajo. CHANGELOG.md se GENERA (pnpm changeset version) — nunca se edita a mano ni lleva sección [Unreleased].
6. Clases con gaps conocidos (pendientes de resolución por Natura)

Las siguientes clases con /N NO tienen mapeo determinístico en la tabla aún y requieren decisión de Natura antes de convertir:

  • bg-ui-success/10, bg-ui-error/10 (trend badges en StatCard)
  • bg-primary/20 (default prop iconBg en StatCard — es un prop caller-controlled)
  • hover:bg-upper/50bg-upper no figura en la tabla semántica
  • [var(--ui-*)]/N en SectionCard — patrón CSS-var-con-alpha, fuera del mapeo actual
7. RSC boundary — pasar iconos a componentes "use client" (ADR-192)

EmptyState es un Client Component. Pasar icon={LucideComponent} desde un Server Component causa crash ("Only plain objects can be passed…"). Usar iconName en su lugar:

// Server Component (RSC) — CORRECTO
import { EmptyState } from "@solu30/ui-kit";
<EmptyState iconName="package" title="Sin paquetes" />

// Client Component — sigue funcionando igual
import { PackageIcon } from "lucide-react";
<EmptyState icon={PackageIcon} title="Sin paquetes" />

iconName acepta cualquier LucideIconName (re-exportado desde @solu30/ui-kit). El icono se resuelve lazy con lucide-react/dynamic — no bundlea el set completo. EmptyStateAction.iconName funciona igual para botones de acción.

Otros componentes con icon?: ComponentType (StatCard, MetricCard, SectionHeader) son también "use client" pero sus callers típicos son client — no requieren migración aún. Evaluar caso por caso cuando aparezca necesidad concreta desde RSC.

05

Versión

Un paquete y tres archivos que declaran una versión. Los tres se leen de la misma instalación: la que sirve esta página.

Qué diceVersiónSale de
La que corre5.8.1package.json del paquete instalado
La del índice de exports5.5.0docs/EXPORTS.md, generado el 2026-08-16
La de la prosa4.13.0docs/SCOPE.md, el texto de la sección 01

Cuál es la fuente confiable

Confiable: las declaraciones compiladas de la versión instalada. De ahí sale la tabla de la sección 03 y de ahí sale el índice de componentes. No confiable hasta que se regenere: docs/EXPORTS.md, que viaja adentro del paquete 5.8.1 declarando ser de la 5.5.0. Si abriste ese archivo para buscar un símbolo, verificá contra la sección 03 antes de escribir el import.

El desfasaje no está repartido parejo, que es lo que lo hace traicionero: de 19 subpaths, 17 coinciden exactamente con el índice y 2 no: @solu30/ui-kit figura con 1126 y exporta 1166; @solu30/ui-kit/animation figura con 5 y exporta 45. Un índice que acierta en casi todo es el que más fácil se cree.

Ninguno de los tres archivos está mal escrito: los tres eran ciertos el día que se generaron. Lo que falta es que se muevan juntos. El changelog sí tiene quien lo vigile —un control corre antes de cada commit de este repositorio, compara su release más nuevo contra la versión instalada y no deja pasar el commit si se separaron—; el índice de exports no tiene el suyo, y por eso pudo quedarse atrás sin que nada avisara.

Prosa leída de docs/SCOPE.md y docs/INSTRUCTIONS.md del paquete instalado · superficie leída de los .d.ts compilados que declara su exports map · versión 5.8.1.