@eduardoalvarez/arrecife 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +124 -2
- package/dist/brand/index.cjs +9 -8
- package/dist/brand/index.js +4 -2
- package/dist/chart/index.cjs +287 -0
- package/dist/chart/index.d.cts +127 -0
- package/dist/chart/index.d.ts +127 -0
- package/dist/chart/index.js +103 -0
- package/dist/chunk-KPZNNMV5.js +83 -0
- package/dist/chunk-MLKGABMK.js +7 -0
- package/dist/chunk-NHS7ETKJ.js +27 -0
- package/dist/{chunk-ZL5X6XO7.js → chunk-TB3IYPOD.js} +4 -25
- package/dist/{chunk-DHF63QNM.js → chunk-TSPJOM6K.js} +10 -12
- package/dist/chunk-UOWIDFCB.js +81 -0
- package/dist/{chunk-22OXRTAL.js → chunk-VPT32GPG.js} +2 -1
- package/dist/chunk-ZEOQKRQ7.js +19 -0
- package/dist/form/index.cjs +301 -0
- package/dist/form/index.d.cts +86 -0
- package/dist/form/index.d.ts +86 -0
- package/dist/form/index.js +84 -0
- package/dist/index.cjs +832 -332
- package/dist/index.d.cts +332 -29
- package/dist/index.d.ts +332 -29
- package/dist/index.js +746 -445
- package/dist/label-DuTvJGxD.d.cts +14 -0
- package/dist/label-DuTvJGxD.d.ts +14 -0
- package/dist/og/index.js +2 -1
- package/dist/shiki/index.js +2 -1
- package/dist/tema/index.cjs +94 -0
- package/dist/tema/index.d.cts +110 -0
- package/dist/tema/index.d.ts +110 -0
- package/dist/tema/index.js +2 -0
- package/dist/tokens/index.cjs +11 -5
- package/dist/tokens/index.d.cts +65 -11
- package/dist/tokens/index.d.ts +65 -11
- package/dist/tokens/index.js +3 -2
- package/dist/tokens/theme.css +21 -5
- package/llms.txt +329 -24
- package/package.json +35 -4
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
3
|
+
import { Legend, Tooltip } from 'recharts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* El chasis de las gráficas: contenedor, tooltip y leyenda con el vocabulario
|
|
7
|
+
* del sistema. Recharts pinta; esto decide cómo se ve.
|
|
8
|
+
*
|
|
9
|
+
* Se publica en `@eduardoalvarez/arrecife/chart` y NO en la raíz. Recharts pesa,
|
|
10
|
+
* y solo uno de los cinco proyectos dibuja métricas: colgarlo del índice
|
|
11
|
+
* principal obligaría a los otros cuatro a instalarlo para que su bundler
|
|
12
|
+
* resolviera un import que nunca ejecutan. Es dependencia de pares OPCIONAL, por
|
|
13
|
+
* el mismo criterio con el que `./og` y `./shiki` se mantienen sin React.
|
|
14
|
+
*
|
|
15
|
+
* Lo que esta capa aporta —y lo que se perdía copiando el `chart.tsx` de shadcn
|
|
16
|
+
* en cada proyecto— son tres cosas que se desincronizan solas:
|
|
17
|
+
*
|
|
18
|
+
* 1. La paleta de series sale de `tokens.series` y sigue el modo. Son cuatro
|
|
19
|
+
* y se distinguen por tono, no por luminosidad.
|
|
20
|
+
* 2. La rejilla, los ejes y el cursor usan `hairline` y `textMuted`, no los
|
|
21
|
+
* grises por defecto de Recharts, que no son de esta identidad.
|
|
22
|
+
* 3. El tooltip aparece donde va a quedarse: `isAnimationActive` apagado en
|
|
23
|
+
* todas partes, porque el sistema no anima posición.
|
|
24
|
+
*
|
|
25
|
+
* Las piezas de datos —`BarChart`, `Line`, `XAxis`— NO se reexportan. Son la API
|
|
26
|
+
* de Recharts, el proyecto ya la conoce y envolverlas sería una capa de nombres
|
|
27
|
+
* que hay que mantener sincronizada con la versión de la librería.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* El color de la serie `indice`, como custom property.
|
|
31
|
+
*
|
|
32
|
+
* Devuelve `var(--color-serie-N)` y no el hexadecimal: leído en JS, el hex sería
|
|
33
|
+
* el del modo que había cuando se montó el componente y no cambiaría al alternar
|
|
34
|
+
* el tema. La variable la resuelve el navegador en cada pintura.
|
|
35
|
+
*
|
|
36
|
+
* Da la vuelta pasadas las cuatro. Que dos series compartan color es un fallo
|
|
37
|
+
* visible, y es la señal correcta: la gráfica tiene más categorías de las que
|
|
38
|
+
* esta identidad sabe distinguir, y lo que toca es agrupar en «otros».
|
|
39
|
+
*/
|
|
40
|
+
declare function colorDeSerie(indice: number): string;
|
|
41
|
+
/** Las cuatro, en orden, para pasárselas de golpe a un `Pie` con `Cell`. */
|
|
42
|
+
declare const COLORES_DE_SERIE: string[];
|
|
43
|
+
type ChartContainerProps = Omit<ComponentPropsWithoutRef<'figure'>, 'title'> & {
|
|
44
|
+
/**
|
|
45
|
+
* Qué muestra la gráfica, en una frase. Obligatorio, como el `label` de
|
|
46
|
+
* `Progress`: un `<svg>` de barras sin nombre accesible no es «una gráfica sin
|
|
47
|
+
* etiqueta», es una región vacía.
|
|
48
|
+
*/
|
|
49
|
+
label: string;
|
|
50
|
+
/**
|
|
51
|
+
* Lo que la gráfica dice, en palabras. Va en un `figcaption` oculto
|
|
52
|
+
* visualmente.
|
|
53
|
+
*
|
|
54
|
+
* No sustituye a la gráfica: la capa de accesibilidad de Recharts ya permite
|
|
55
|
+
* recorrer los puntos con el teclado. Es el titular —«sube de 24 a 52 con una
|
|
56
|
+
* caída en mayo»— que ningún recorrido punto a punto da.
|
|
57
|
+
*/
|
|
58
|
+
summary?: ReactNode;
|
|
59
|
+
/** Alto en píxeles. Recharts necesita uno concreto para medir. */
|
|
60
|
+
height?: number;
|
|
61
|
+
children: ReactNode;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Envuelve la gráfica en un `<figure>` con nombre accesible y le da a Recharts
|
|
65
|
+
* el alto concreto que necesita para medirse.
|
|
66
|
+
*
|
|
67
|
+
* El `<figure>` NO lleva `role`: ya tiene el suyo implícito, y ponerle `group`
|
|
68
|
+
* encima es un rol no permitido para el elemento —axe lo señala—. Lo que sí
|
|
69
|
+
* lleva es `aria-label`, que es lo que lo nombra.
|
|
70
|
+
*
|
|
71
|
+
* Y el contenido NO va `aria-hidden`. Fue lo primero que se intentó, con el
|
|
72
|
+
* argumento de que anunciar cada tick no cuenta lo que la gráfica cuenta, y está
|
|
73
|
+
* mal por dos motivos: la capa de accesibilidad de Recharts hace la gráfica
|
|
74
|
+
* recorrible con el teclado, y esconder un subárbol que contiene elementos
|
|
75
|
+
* enfocables es una violación por sí misma —el foco entra en algo que no existe
|
|
76
|
+
* para quien escucha—. El resumen se suma a eso, no lo reemplaza.
|
|
77
|
+
*/
|
|
78
|
+
declare function ChartContainer({ label, summary, height, className, children, ...props }: ChartContainerProps): react.JSX.Element;
|
|
79
|
+
/**
|
|
80
|
+
* El `Tooltip` de Recharts con los defectos del sistema: sin animación y con el
|
|
81
|
+
* cursor teñido de `surfaceRaised`.
|
|
82
|
+
*
|
|
83
|
+
* Se pasa `content={<ChartTooltipContent />}` para la caja.
|
|
84
|
+
*/
|
|
85
|
+
declare function ChartTooltip(props: ComponentPropsWithoutRef<typeof Tooltip>): react.JSX.Element;
|
|
86
|
+
declare function ChartLegend(props: ComponentPropsWithoutRef<typeof Legend>): react.JSX.Element;
|
|
87
|
+
/**
|
|
88
|
+
* Lo que Recharts le pasa a un `content`, declarado aquí en corto.
|
|
89
|
+
*
|
|
90
|
+
* Los tipos de Recharts para esto son abiertos y arrastran genéricos que no
|
|
91
|
+
* aportan nada al sitio de uso; `any` está prohibido en el repo, así que se
|
|
92
|
+
* declara lo que de verdad se lee y el valor se trata como `unknown`.
|
|
93
|
+
*/
|
|
94
|
+
type ChartPayloadItem = {
|
|
95
|
+
name?: string | number | undefined;
|
|
96
|
+
value?: unknown;
|
|
97
|
+
color?: string | undefined;
|
|
98
|
+
dataKey?: string | number | undefined;
|
|
99
|
+
};
|
|
100
|
+
type ChartTooltipContentProps = {
|
|
101
|
+
active?: boolean | undefined;
|
|
102
|
+
payload?: readonly ChartPayloadItem[] | undefined;
|
|
103
|
+
label?: ReactNode;
|
|
104
|
+
/** Formatea el valor. Sin ella se imprime tal cual: la librería no impone locale. */
|
|
105
|
+
formatter?: ((valor: unknown, item: ChartPayloadItem) => ReactNode) | undefined;
|
|
106
|
+
/** Oculta el encabezado, para una gráfica de una sola categoría. */
|
|
107
|
+
hideLabel?: boolean;
|
|
108
|
+
className?: string;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* La caja del tooltip. Es una tarjeta del sistema —`surface`, borde de control,
|
|
112
|
+
* sombra estándar— y no la caja blanca de Recharts, que en modo oscuro es un
|
|
113
|
+
* rectángulo blanco encima de un panel oscuro.
|
|
114
|
+
*
|
|
115
|
+
* El punto de color es un cuadrado de 8px, no un círculo: es la misma marca que
|
|
116
|
+
* usa la leyenda, y en 8 píxeles un círculo y un cuadrado se distinguen peor
|
|
117
|
+
* entre sí que dos colores de la paleta.
|
|
118
|
+
*/
|
|
119
|
+
declare function ChartTooltipContent({ active, payload, label, formatter, hideLabel, className, }: ChartTooltipContentProps): react.JSX.Element | null;
|
|
120
|
+
type ChartLegendContentProps = {
|
|
121
|
+
payload?: readonly ChartPayloadItem[] | undefined;
|
|
122
|
+
className?: string;
|
|
123
|
+
};
|
|
124
|
+
/** La leyenda con la misma marca cuadrada del tooltip y la escala `label`. */
|
|
125
|
+
declare function ChartLegendContent({ payload, className }: ChartLegendContentProps): react.JSX.Element | null;
|
|
126
|
+
|
|
127
|
+
export { COLORES_DE_SERIE, ChartContainer, type ChartContainerProps, ChartLegend, ChartLegendContent, type ChartLegendContentProps, type ChartPayloadItem, ChartTooltip, ChartTooltipContent, type ChartTooltipContentProps, colorDeSerie };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Text } from '../chunk-UOWIDFCB.js';
|
|
2
|
+
import { cn } from '../chunk-NHS7ETKJ.js';
|
|
3
|
+
import '../chunk-TSPJOM6K.js';
|
|
4
|
+
import '../chunk-MLKGABMK.js';
|
|
5
|
+
import { ResponsiveContainer, Tooltip, Legend } from 'recharts';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function colorDeSerie(indice) {
|
|
9
|
+
return `var(--color-serie-${Math.abs(indice) % 4 + 1})`;
|
|
10
|
+
}
|
|
11
|
+
var COLORES_DE_SERIE = [0, 1, 2, 3].map(colorDeSerie);
|
|
12
|
+
function ChartContainer({
|
|
13
|
+
label,
|
|
14
|
+
summary,
|
|
15
|
+
height = 320,
|
|
16
|
+
className,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}) {
|
|
20
|
+
return /* @__PURE__ */ jsxs(
|
|
21
|
+
"figure",
|
|
22
|
+
{
|
|
23
|
+
"aria-label": label,
|
|
24
|
+
className: cn(
|
|
25
|
+
"w-full",
|
|
26
|
+
// La rejilla y los ejes, con los tokens del sistema en vez de los grises
|
|
27
|
+
// por defecto de Recharts. Van como variantes de descendiente porque los
|
|
28
|
+
// nodos los pinta la librería y no hay dónde ponerles una clase.
|
|
29
|
+
"[&_.recharts-cartesian-grid_line]:stroke-hairline",
|
|
30
|
+
"[&_.recharts-cartesian-axis-line]:stroke-hairline",
|
|
31
|
+
"[&_.recharts-cartesian-axis-tick_text]:fill-text-muted",
|
|
32
|
+
"[&_.recharts-cartesian-axis-tick_text]:font-mono",
|
|
33
|
+
"[&_.recharts-cartesian-axis-tick_text]:text-chip",
|
|
34
|
+
"[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-surface-raised",
|
|
35
|
+
"[&_.recharts-curve.recharts-tooltip-cursor]:stroke-hairline-hover",
|
|
36
|
+
"[&_.recharts-sector]:outline-none",
|
|
37
|
+
"[&_.recharts-surface]:overflow-visible",
|
|
38
|
+
className
|
|
39
|
+
),
|
|
40
|
+
...props,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx("div", { style: { height }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children }) }),
|
|
43
|
+
summary ? /* @__PURE__ */ jsx("figcaption", { className: "sr-only", children: summary }) : null
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function ChartTooltip(props) {
|
|
49
|
+
return /* @__PURE__ */ jsx(Tooltip, { isAnimationActive: false, ...props });
|
|
50
|
+
}
|
|
51
|
+
function ChartLegend(props) {
|
|
52
|
+
return /* @__PURE__ */ jsx(Legend, { ...props });
|
|
53
|
+
}
|
|
54
|
+
function ChartTooltipContent({
|
|
55
|
+
active,
|
|
56
|
+
payload,
|
|
57
|
+
label,
|
|
58
|
+
formatter,
|
|
59
|
+
hideLabel = false,
|
|
60
|
+
className
|
|
61
|
+
}) {
|
|
62
|
+
if (!active || !payload || payload.length === 0) return null;
|
|
63
|
+
return /* @__PURE__ */ jsxs(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: cn(
|
|
67
|
+
"rounded-card border-border bg-surface shadow-standard p-step-sm gap-step-xs flex flex-col border",
|
|
68
|
+
className
|
|
69
|
+
),
|
|
70
|
+
children: [
|
|
71
|
+
hideLabel || label === void 0 || label === null ? null : /* @__PURE__ */ jsx(Text, { as: "p", variant: "meta", tone: "muted", children: label }),
|
|
72
|
+
/* @__PURE__ */ jsx("ul", { className: "gap-step-xs flex flex-col", children: payload.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "gap-step-xs flex items-center", children: [
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
"span",
|
|
75
|
+
{
|
|
76
|
+
"aria-hidden": "true",
|
|
77
|
+
className: "rounded-chip size-2 shrink-0",
|
|
78
|
+
style: { backgroundColor: item.color ?? colorDeSerie(i) }
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
/* @__PURE__ */ jsx(Text, { as: "span", variant: "label", tone: "secondary", className: "font-normal", children: item.name }),
|
|
82
|
+
/* @__PURE__ */ jsx(Text, { as: "span", variant: "label", className: "ml-auto font-mono tabular-nums", children: formatter ? formatter(item.value, item) : String(item.value ?? "") })
|
|
83
|
+
] }, `${String(item.dataKey ?? item.name ?? i)}`)) })
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function ChartLegendContent({ payload, className }) {
|
|
89
|
+
if (!payload || payload.length === 0) return null;
|
|
90
|
+
return /* @__PURE__ */ jsx("ul", { className: cn("gap-step-md pt-step-sm flex flex-wrap items-center justify-center", className), children: payload.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "gap-step-xs flex items-center", children: [
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
"span",
|
|
93
|
+
{
|
|
94
|
+
"aria-hidden": "true",
|
|
95
|
+
className: "rounded-chip size-2 shrink-0",
|
|
96
|
+
style: { backgroundColor: item.color ?? colorDeSerie(i) }
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
/* @__PURE__ */ jsx(Text, { as: "span", variant: "label", tone: "secondary", className: "font-normal", children: item.value })
|
|
100
|
+
] }, `${String(item.dataKey ?? item.value ?? i)}`)) });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { COLORES_DE_SERIE, ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, colorDeSerie };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/tema/index.ts
|
|
2
|
+
var TEMA_CLAVE = "arrecife-tema";
|
|
3
|
+
var TEMA_ATRIBUTO = "data-theme";
|
|
4
|
+
var TEMA_EVENTO = "arrecife:tema";
|
|
5
|
+
var esTema = (valor) => valor === "dark" || valor === "light";
|
|
6
|
+
function temaActual() {
|
|
7
|
+
if (typeof document === "undefined") return "dark";
|
|
8
|
+
const puesto = document.documentElement.getAttribute(TEMA_ATRIBUTO);
|
|
9
|
+
return esTema(puesto) ? puesto : "dark";
|
|
10
|
+
}
|
|
11
|
+
function temaGuardado() {
|
|
12
|
+
if (typeof localStorage === "undefined") return null;
|
|
13
|
+
try {
|
|
14
|
+
const valor = localStorage.getItem(TEMA_CLAVE);
|
|
15
|
+
return esTema(valor) ? valor : null;
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function temaPreferido() {
|
|
21
|
+
const guardado = temaGuardado();
|
|
22
|
+
if (guardado) return guardado;
|
|
23
|
+
if (typeof matchMedia === "undefined") return "dark";
|
|
24
|
+
return matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
|
|
25
|
+
}
|
|
26
|
+
function aplicarTema(tema, persistir = true) {
|
|
27
|
+
if (typeof document === "undefined") return;
|
|
28
|
+
document.documentElement.setAttribute(TEMA_ATRIBUTO, tema);
|
|
29
|
+
document.documentElement.style.colorScheme = tema;
|
|
30
|
+
if (persistir) {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem(TEMA_CLAVE, tema);
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
dispatchEvent(new CustomEvent(TEMA_EVENTO, { detail: tema }));
|
|
37
|
+
}
|
|
38
|
+
function alternarTema() {
|
|
39
|
+
const siguiente = temaActual() === "dark" ? "light" : "dark";
|
|
40
|
+
aplicarTema(siguiente);
|
|
41
|
+
return siguiente;
|
|
42
|
+
}
|
|
43
|
+
function escucharTema(alCambiar) {
|
|
44
|
+
if (typeof window === "undefined") return () => {
|
|
45
|
+
};
|
|
46
|
+
const propio = (evento) => {
|
|
47
|
+
const detalle = evento.detail;
|
|
48
|
+
if (esTema(detalle)) alCambiar(detalle);
|
|
49
|
+
};
|
|
50
|
+
const otraPestana = (evento) => {
|
|
51
|
+
if (evento.key !== TEMA_CLAVE) return;
|
|
52
|
+
const tema = esTema(evento.newValue) ? evento.newValue : temaPreferido();
|
|
53
|
+
aplicarTema(tema, false);
|
|
54
|
+
alCambiar(tema);
|
|
55
|
+
};
|
|
56
|
+
addEventListener(TEMA_EVENTO, propio);
|
|
57
|
+
addEventListener("storage", otraPestana);
|
|
58
|
+
return () => {
|
|
59
|
+
removeEventListener(TEMA_EVENTO, propio);
|
|
60
|
+
removeEventListener("storage", otraPestana);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
var scriptTema = [
|
|
64
|
+
"(function () {",
|
|
65
|
+
" var CLAVE = " + JSON.stringify(TEMA_CLAVE) + ";",
|
|
66
|
+
" function resolver() {",
|
|
67
|
+
" try {",
|
|
68
|
+
" var guardado = localStorage.getItem(CLAVE);",
|
|
69
|
+
' if (guardado === "dark" || guardado === "light") return guardado;',
|
|
70
|
+
" } catch (e) {}",
|
|
71
|
+
' return matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";',
|
|
72
|
+
" }",
|
|
73
|
+
" function aplicar() {",
|
|
74
|
+
" var tema = resolver();",
|
|
75
|
+
" document.documentElement.setAttribute(" + JSON.stringify(TEMA_ATRIBUTO) + ", tema);",
|
|
76
|
+
" document.documentElement.style.colorScheme = tema;",
|
|
77
|
+
" }",
|
|
78
|
+
" aplicar();",
|
|
79
|
+
' document.addEventListener("astro:after-swap", aplicar);',
|
|
80
|
+
"})();"
|
|
81
|
+
].join("\n");
|
|
82
|
+
|
|
83
|
+
export { TEMA_ATRIBUTO, TEMA_CLAVE, TEMA_EVENTO, alternarTema, aplicarTema, escucharTema, scriptTema, temaActual, temaGuardado, temaPreferido };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { spacing, control, radius, typeScale } from './chunk-TSPJOM6K.js';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
4
|
+
|
|
5
|
+
var kebab = (nombre) => nombre.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
6
|
+
var escalas = Object.keys(typeScale);
|
|
7
|
+
var radios = Object.keys(radius);
|
|
8
|
+
var espacios = Object.keys(spacing).map(kebab);
|
|
9
|
+
var controles = Object.keys(control).map((nombre) => `control-${kebab(nombre)}`);
|
|
10
|
+
var twMerge = extendTailwindMerge({
|
|
11
|
+
extend: {
|
|
12
|
+
classGroups: {
|
|
13
|
+
"font-size": [{ text: escalas }],
|
|
14
|
+
rounded: [{ rounded: radios }],
|
|
15
|
+
p: [{ p: espacios }],
|
|
16
|
+
px: [{ px: [...espacios, ...controles] }],
|
|
17
|
+
py: [{ py: espacios }],
|
|
18
|
+
gap: [{ gap: espacios }],
|
|
19
|
+
size: [{ size: controles }]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
function cn(...inputs) {
|
|
24
|
+
return twMerge(clsx(inputs));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { cn };
|
|
@@ -1,29 +1,8 @@
|
|
|
1
1
|
import { aletas, RUTA_ASSETS, poses, caras } from './chunk-E3OMP2DL.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { extendTailwindMerge } from 'tailwind-merge';
|
|
2
|
+
import { cn } from './chunk-NHS7ETKJ.js';
|
|
3
|
+
import { naming } from './chunk-TSPJOM6K.js';
|
|
5
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
5
|
|
|
7
|
-
var escalas = Object.keys(typeScale);
|
|
8
|
-
var radios = Object.keys(radius);
|
|
9
|
-
var espacios = Object.keys(spacing);
|
|
10
|
-
var controles = Object.keys(control).map((nombre) => `control-${nombre}`);
|
|
11
|
-
var twMerge = extendTailwindMerge({
|
|
12
|
-
extend: {
|
|
13
|
-
classGroups: {
|
|
14
|
-
"font-size": [{ text: escalas }],
|
|
15
|
-
rounded: [{ rounded: radios }],
|
|
16
|
-
p: [{ p: espacios }],
|
|
17
|
-
px: [{ px: [...espacios, ...controles] }],
|
|
18
|
-
py: [{ py: espacios }],
|
|
19
|
-
gap: [{ gap: espacios }],
|
|
20
|
-
size: [{ size: controles }]
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
function cn(...inputs) {
|
|
25
|
-
return twMerge(clsx(inputs));
|
|
26
|
-
}
|
|
27
6
|
function Isotipo({
|
|
28
7
|
sobre = "oscuro",
|
|
29
8
|
basePath = RUTA_ASSETS,
|
|
@@ -51,7 +30,7 @@ function Logo({
|
|
|
51
30
|
className,
|
|
52
31
|
...props
|
|
53
32
|
}) {
|
|
54
|
-
return /* @__PURE__ */ jsxs("span", { className: cn("gap-xs inline-flex items-center", className), ...props, children: [
|
|
33
|
+
return /* @__PURE__ */ jsxs("span", { className: cn("gap-step-xs inline-flex items-center", className), ...props, children: [
|
|
55
34
|
/* @__PURE__ */ jsx(
|
|
56
35
|
Isotipo,
|
|
57
36
|
{
|
|
@@ -99,4 +78,4 @@ function CaraDeMascota({
|
|
|
99
78
|
);
|
|
100
79
|
}
|
|
101
80
|
|
|
102
|
-
export { CaraDeMascota, Isotipo, Logo, Mascota
|
|
81
|
+
export { CaraDeMascota, Isotipo, Logo, Mascota };
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
1
|
// src/tokens/tokens.ts
|
|
8
2
|
var dark = {
|
|
9
3
|
background: "#091319",
|
|
@@ -162,11 +156,11 @@ var control = {
|
|
|
162
156
|
icon: 42
|
|
163
157
|
};
|
|
164
158
|
var spacing = {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
159
|
+
stepXs: 8,
|
|
160
|
+
stepSm: 12,
|
|
161
|
+
stepMd: 16,
|
|
162
|
+
stepLg: 26,
|
|
163
|
+
stepXl: 40,
|
|
170
164
|
section: 96
|
|
171
165
|
};
|
|
172
166
|
var size = {
|
|
@@ -191,6 +185,10 @@ var sintaxis = {
|
|
|
191
185
|
/** `markup.deleted`, `invalid`. */
|
|
192
186
|
invalido: dark.error
|
|
193
187
|
};
|
|
188
|
+
var series = {
|
|
189
|
+
dark: [dark.accent, dark.warm, brand.body, dark.textMuted],
|
|
190
|
+
light: [light.accent, light.warm, brand.body, light.textMuted]
|
|
191
|
+
};
|
|
194
192
|
var profundo = "#0D2129";
|
|
195
193
|
var gradient = {
|
|
196
194
|
dark: {
|
|
@@ -228,4 +226,4 @@ var naming = {
|
|
|
228
226
|
domain: "eduardoalvarez.dev"
|
|
229
227
|
};
|
|
230
228
|
|
|
231
|
-
export {
|
|
229
|
+
export { brand, colors, control, dark, fonts, gradient, light, limits, motion, naming, radius, series, shadow, sintaxis, size, spacing, tagline, typeScale };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { cn } from './chunk-NHS7ETKJ.js';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var ETIQUETA = {
|
|
7
|
+
display: "h1",
|
|
8
|
+
stat: "p",
|
|
9
|
+
h1: "h1",
|
|
10
|
+
h2: "h2",
|
|
11
|
+
h3: "h3",
|
|
12
|
+
body: "p",
|
|
13
|
+
lead: "p",
|
|
14
|
+
ui: "p",
|
|
15
|
+
label: "span",
|
|
16
|
+
tag: "span",
|
|
17
|
+
meta: "p",
|
|
18
|
+
chip: "span",
|
|
19
|
+
eyebrow: "p"
|
|
20
|
+
};
|
|
21
|
+
var texto = cva("", {
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
display: "text-display font-display",
|
|
25
|
+
// Métricas grandes: 46px de display. Es la única escala pensada para un
|
|
26
|
+
// número, y por eso el interlineado es 1.
|
|
27
|
+
stat: "text-stat font-display",
|
|
28
|
+
h1: "text-h1 font-display",
|
|
29
|
+
h2: "text-h2 font-display",
|
|
30
|
+
h3: "text-h3 font-display",
|
|
31
|
+
body: "text-body font-sans",
|
|
32
|
+
// 17px: la bajada de las páginas internas y el botón grande.
|
|
33
|
+
lead: "text-lead font-sans",
|
|
34
|
+
ui: "text-ui font-sans",
|
|
35
|
+
label: "text-label font-sans",
|
|
36
|
+
// Las dos escalas de etiqueta. `tag` es el estado (sans 12.5/500) y `chip`
|
|
37
|
+
// la categoría y la métrica (mono 11.5). Ninguna transforma el texto.
|
|
38
|
+
tag: "text-tag font-sans",
|
|
39
|
+
chip: "text-chip font-mono",
|
|
40
|
+
// Mono SIN transformar: fechas, rutas, versiones, nombres de archivo y la
|
|
41
|
+
// firma del footer. Es el escalón que faltaba, y por el que cada sitio de
|
|
42
|
+
// uso terminaba escribiendo `variant="eyebrow" className="normal-case"`.
|
|
43
|
+
meta: "text-meta font-mono",
|
|
44
|
+
// `uppercase` no cabe en un token de tamaño: text-transform no es un
|
|
45
|
+
// modificador de --text-*. Por eso lo pone la variante y no theme.css.
|
|
46
|
+
eyebrow: "text-eyebrow font-mono uppercase"
|
|
47
|
+
},
|
|
48
|
+
tone: {
|
|
49
|
+
primary: "text-text-primary",
|
|
50
|
+
secondary: "text-text-secondary",
|
|
51
|
+
muted: "text-text-muted",
|
|
52
|
+
accent: "text-accent",
|
|
53
|
+
warm: "text-warm",
|
|
54
|
+
success: "text-success",
|
|
55
|
+
warning: "text-warning",
|
|
56
|
+
error: "text-error"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
defaultVariants: { variant: "body", tone: "primary" }
|
|
60
|
+
});
|
|
61
|
+
function Text({
|
|
62
|
+
className,
|
|
63
|
+
variant,
|
|
64
|
+
tone,
|
|
65
|
+
as,
|
|
66
|
+
asChild = false,
|
|
67
|
+
measure,
|
|
68
|
+
children,
|
|
69
|
+
...props
|
|
70
|
+
}) {
|
|
71
|
+
const escala = variant ?? "body";
|
|
72
|
+
const limitar = measure ?? escala === "body";
|
|
73
|
+
const clases = cn(texto({ variant, tone }), limitar && "max-w-measure", className);
|
|
74
|
+
if (asChild) {
|
|
75
|
+
return /* @__PURE__ */ jsx(Slot, { className: clases, ...props, children });
|
|
76
|
+
}
|
|
77
|
+
const Etiqueta = as ?? ETIQUETA[escala];
|
|
78
|
+
return /* @__PURE__ */ jsx(Etiqueta, { className: clases, ...props, children });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { Text, texto };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { naming, tagline, motion, shadow, sintaxis, gradient, size, spacing, control, radius, limits, typeScale, fonts, brand, colors } from './chunk-
|
|
1
|
+
import { naming, tagline, motion, shadow, series, sintaxis, gradient, size, spacing, control, radius, limits, typeScale, fonts, brand, colors } from './chunk-TSPJOM6K.js';
|
|
2
2
|
|
|
3
3
|
// src/tokens/index.ts
|
|
4
4
|
var tokens = {
|
|
@@ -13,6 +13,7 @@ var tokens = {
|
|
|
13
13
|
size,
|
|
14
14
|
gradient,
|
|
15
15
|
sintaxis,
|
|
16
|
+
series,
|
|
16
17
|
shadow,
|
|
17
18
|
motion,
|
|
18
19
|
tagline,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { cn } from './chunk-NHS7ETKJ.js';
|
|
2
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function Label({ className, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
LabelPrimitive.Root,
|
|
8
|
+
{
|
|
9
|
+
className: cn(
|
|
10
|
+
"text-label font-sans text-text-secondary select-none",
|
|
11
|
+
"peer-disabled:opacity-50 group-data-[disabled]:opacity-50",
|
|
12
|
+
className
|
|
13
|
+
),
|
|
14
|
+
...props
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { Label };
|