@arroyavecommerce/theme-kinetic 0.2.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/docs/design/README.md +22 -0
- package/docs/design/kinetic-street-concept.html +558 -0
- package/package.json +45 -0
- package/src/blocks/_shared.tsx +174 -0
- package/src/blocks/carrusel.tsx +109 -0
- package/src/blocks/category-tiles.test.tsx +59 -0
- package/src/blocks/category-tiles.tsx +70 -0
- package/src/blocks/editorial-banner.test.tsx +96 -0
- package/src/blocks/editorial-banner.tsx +205 -0
- package/src/blocks/faq.test.tsx +68 -0
- package/src/blocks/faq.tsx +122 -0
- package/src/blocks/featured-collection.test.tsx +80 -0
- package/src/blocks/featured-collection.tsx +97 -0
- package/src/blocks/features.test.tsx +71 -0
- package/src/blocks/features.tsx +159 -0
- package/src/blocks/hero.test.tsx +75 -0
- package/src/blocks/hero.tsx +290 -0
- package/src/blocks/index.tsx +35 -0
- package/src/blocks/lookbook.test.tsx +80 -0
- package/src/blocks/lookbook.tsx +117 -0
- package/src/blocks/marquee.test.tsx +54 -0
- package/src/blocks/marquee.tsx +114 -0
- package/src/blocks/newsletter.test.tsx +60 -0
- package/src/blocks/newsletter.tsx +105 -0
- package/src/blocks/product-grid.test.tsx +160 -0
- package/src/blocks/product-grid.tsx +76 -0
- package/src/blocks/promo-countdown.tsx +75 -0
- package/src/blocks/promo.test.tsx +71 -0
- package/src/blocks/promo.tsx +120 -0
- package/src/blocks/rich-text.test.tsx +67 -0
- package/src/blocks/rich-text.tsx +75 -0
- package/src/blocks/spacer.test.tsx +54 -0
- package/src/blocks/spacer.tsx +56 -0
- package/src/blocks/testimonials.test.tsx +74 -0
- package/src/blocks/testimonials.tsx +104 -0
- package/src/blocks/video.test.tsx +159 -0
- package/src/blocks/video.tsx +226 -0
- package/src/catalog/buy-box.test.tsx +225 -0
- package/src/catalog/buy-box.tsx +353 -0
- package/src/catalog/config.test.ts +115 -0
- package/src/catalog/config.ts +167 -0
- package/src/catalog/filter-controls.test.tsx +149 -0
- package/src/catalog/filter-controls.tsx +187 -0
- package/src/catalog/gallery.test.tsx +201 -0
- package/src/catalog/gallery.tsx +212 -0
- package/src/catalog/lightbox.test.tsx +95 -0
- package/src/catalog/lightbox.tsx +184 -0
- package/src/catalog/pdp.test.tsx +309 -0
- package/src/catalog/pdp.tsx +354 -0
- package/src/catalog/plp-arreglos.test.tsx +235 -0
- package/src/catalog/plp-inline.tsx +54 -0
- package/src/catalog/plp-overlay.tsx +129 -0
- package/src/catalog/plp-parts.test.tsx +146 -0
- package/src/catalog/plp-parts.tsx +292 -0
- package/src/catalog/plp-pills.tsx +44 -0
- package/src/catalog/plp-sidebar.tsx +47 -0
- package/src/catalog/plp.test.tsx +319 -0
- package/src/catalog/plp.tsx +259 -0
- package/src/catalog/product-card.test.tsx +221 -0
- package/src/catalog/product-card.tsx +411 -0
- package/src/catalog/registry.tsx +16 -0
- package/src/catalog/related.test.tsx +52 -0
- package/src/catalog/related.tsx +40 -0
- package/src/catalog/reviews.test.tsx +56 -0
- package/src/catalog/reviews.tsx +116 -0
- package/src/catalog/skeletons.test.tsx +61 -0
- package/src/catalog/skeletons.tsx +103 -0
- package/src/chrome/announcement-bar.test.tsx +86 -0
- package/src/chrome/announcement-bar.tsx +173 -0
- package/src/chrome/drawer-movil.test.tsx +113 -0
- package/src/chrome/drawer-movil.tsx +342 -0
- package/src/chrome/footer.test.tsx +133 -0
- package/src/chrome/footer.tsx +603 -0
- package/src/chrome/header.test.tsx +165 -0
- package/src/chrome/header.tsx +592 -0
- package/src/chrome/index.ts +26 -0
- package/src/chrome/mega-menu.test.tsx +161 -0
- package/src/chrome/mega-menu.tsx +317 -0
- package/src/chrome/mini-cart.test.tsx +111 -0
- package/src/chrome/mini-cart.tsx +320 -0
- package/src/content/home.ts +19 -0
- package/src/content/seed.test.ts +33 -0
- package/src/content/seed.ts +28 -0
- package/src/context.ts +104 -0
- package/src/icons/icons.test.tsx +118 -0
- package/src/icons/index.ts +136 -0
- package/src/icons/payment-icons.tsx +241 -0
- package/src/icons/social-icons.tsx +108 -0
- package/src/icons/svg-base.tsx +68 -0
- package/src/index.ts +49 -0
- package/src/puck-config.tsx +404 -0
- package/src/smoke.test.ts +8 -0
- package/src/template.test.tsx +88 -0
- package/src/test/mock-ctx.test.tsx +77 -0
- package/src/test/mock-ctx.tsx +236 -0
- package/src/theme-defaults.test.ts +9 -0
- package/src/theme.test.ts +82 -0
- package/src/theme.ts +195 -0
- package/tsconfig.json +4 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { CartData, RenderContext } from "../context"
|
|
2
|
+
import type { HttpTypes } from "@medusajs/types"
|
|
3
|
+
import type { CmsFiltersConfig } from "@arroyavecommerce/cms-core"
|
|
4
|
+
|
|
5
|
+
export function mockCtx(overrides?: Partial<RenderContext>): RenderContext {
|
|
6
|
+
return {
|
|
7
|
+
countryCode: "co",
|
|
8
|
+
region: {} as HttpTypes.StoreRegion,
|
|
9
|
+
products: [],
|
|
10
|
+
categories: [],
|
|
11
|
+
collections: [],
|
|
12
|
+
cartQuantities: {},
|
|
13
|
+
carrito: null,
|
|
14
|
+
acciones: { agregarAlCarrito: async () => ({ ok: true }) },
|
|
15
|
+
componentes: {
|
|
16
|
+
Imagen: ({ src, alt, className, prioridad }) =>
|
|
17
|
+
src
|
|
18
|
+
? <img src={src} alt={alt} className={className} data-prioridad={prioridad ? "true" : undefined} />
|
|
19
|
+
: <div role="img" aria-label={alt} className={className} style={{ background: "var(--cms-superficie)" }} />,
|
|
20
|
+
Enlace: ({ href, className, children, "aria-current": ariaCurrent }) => (
|
|
21
|
+
<a href={href} className={className} aria-current={ariaCurrent}>{children}</a>
|
|
22
|
+
),
|
|
23
|
+
},
|
|
24
|
+
sesion: null,
|
|
25
|
+
...overrides,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const fixtureProductos: HttpTypes.StoreProduct[] = [
|
|
30
|
+
{
|
|
31
|
+
id: "prod_1",
|
|
32
|
+
title: "Sneaker Runner Blanco",
|
|
33
|
+
handle: "sneaker-runner-blanco",
|
|
34
|
+
thumbnail: null,
|
|
35
|
+
variants: [
|
|
36
|
+
{
|
|
37
|
+
id: "var_1",
|
|
38
|
+
title: "M",
|
|
39
|
+
calculated_price: { calculated_amount: 289900, currency_code: "cop" },
|
|
40
|
+
inventory_quantity: 5,
|
|
41
|
+
allow_backorder: false,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "prod_2",
|
|
47
|
+
title: "Hoodie Heavy Negro",
|
|
48
|
+
handle: "hoodie-heavy-negro",
|
|
49
|
+
thumbnail: null,
|
|
50
|
+
variants: [
|
|
51
|
+
{
|
|
52
|
+
id: "var_2",
|
|
53
|
+
title: "M",
|
|
54
|
+
calculated_price: { calculated_amount: 179900, currency_code: "cop" },
|
|
55
|
+
inventory_quantity: 5,
|
|
56
|
+
allow_backorder: false,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "prod_3",
|
|
62
|
+
title: "Camiseta Basica Blanca",
|
|
63
|
+
handle: "camiseta-basica-blanca",
|
|
64
|
+
thumbnail: null,
|
|
65
|
+
variants: [
|
|
66
|
+
{
|
|
67
|
+
id: "var_3",
|
|
68
|
+
title: "S",
|
|
69
|
+
calculated_price: { calculated_amount: 89900, currency_code: "cop" },
|
|
70
|
+
inventory_quantity: 5,
|
|
71
|
+
allow_backorder: false,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
] as unknown as HttpTypes.StoreProduct[]
|
|
76
|
+
|
|
77
|
+
const fixtureFiltros: CmsFiltersConfig = {
|
|
78
|
+
version: 1,
|
|
79
|
+
facets: [
|
|
80
|
+
{
|
|
81
|
+
id: "categoria",
|
|
82
|
+
label: "Categoría",
|
|
83
|
+
control: "pill",
|
|
84
|
+
source: { type: "tag", tagIds: ["tag_camisetas", "tag_hoodies"] },
|
|
85
|
+
order: 1,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "precio",
|
|
89
|
+
label: "Precio",
|
|
90
|
+
control: "range",
|
|
91
|
+
source: { type: "price" },
|
|
92
|
+
order: 2,
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function fixtureCarrito(overrides?: Partial<CartData>): CartData {
|
|
98
|
+
return {
|
|
99
|
+
items: [
|
|
100
|
+
{
|
|
101
|
+
id: "line_1",
|
|
102
|
+
title: "Sneaker Runner Blanco",
|
|
103
|
+
variantTitle: "Blanco / 40",
|
|
104
|
+
thumbnail: "https://picsum.photos/seed/cart-1/80/100",
|
|
105
|
+
cantidad: 1,
|
|
106
|
+
precioTotal: 289900,
|
|
107
|
+
href: "/products/sneaker-runner-blanco",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "line_2",
|
|
111
|
+
title: "Hoodie Heavy Negro",
|
|
112
|
+
variantTitle: "Negro / M",
|
|
113
|
+
thumbnail: null,
|
|
114
|
+
cantidad: 2,
|
|
115
|
+
precioTotal: 359800,
|
|
116
|
+
href: "/products/hoodie-heavy-negro",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
count: 3,
|
|
120
|
+
subtotal: 649700,
|
|
121
|
+
moneda: "cop",
|
|
122
|
+
urlCarrito: "/cart",
|
|
123
|
+
urlCheckout: "/checkout",
|
|
124
|
+
...overrides,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function fixtureListado(
|
|
129
|
+
overrides?: Partial<NonNullable<NonNullable<RenderContext["catalogo"]>["listado"]>>
|
|
130
|
+
): NonNullable<NonNullable<RenderContext["catalogo"]>["listado"]> {
|
|
131
|
+
return {
|
|
132
|
+
titulo: "Todos los productos",
|
|
133
|
+
breadcrumb: [
|
|
134
|
+
{ texto: "Inicio", href: "/" },
|
|
135
|
+
{ texto: "Todos los productos", href: "/productos" },
|
|
136
|
+
],
|
|
137
|
+
productos: fixtureProductos,
|
|
138
|
+
total: fixtureProductos.length,
|
|
139
|
+
filtros: fixtureFiltros,
|
|
140
|
+
seleccion: {},
|
|
141
|
+
opcionesFaceta: {
|
|
142
|
+
categoria: [
|
|
143
|
+
{ valor: "camisetas", etiqueta: "Camisetas", conteo: 128 },
|
|
144
|
+
{ valor: "hoodies", etiqueta: "Hoodies", conteo: 42 },
|
|
145
|
+
],
|
|
146
|
+
precio: [{ valor: "0-100000", etiqueta: "$0 - $100.000" }],
|
|
147
|
+
},
|
|
148
|
+
paginacion: { pagina: 1, totalPaginas: 3, hrefPara: (p: number) => `?page=${p}` },
|
|
149
|
+
urlFiltro: (facetId: string, valor: string) => `?${facetId}=${valor}`,
|
|
150
|
+
urlOrden: (valor: string) => `?order=${valor}`,
|
|
151
|
+
orden: "relevancia",
|
|
152
|
+
...overrides,
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function fixtureDetalle(
|
|
157
|
+
overrides?: Partial<NonNullable<NonNullable<RenderContext["catalogo"]>["detalle"]>>
|
|
158
|
+
): NonNullable<NonNullable<RenderContext["catalogo"]>["detalle"]> {
|
|
159
|
+
return {
|
|
160
|
+
producto: {
|
|
161
|
+
eyebrow: "SNEAKERS · UNISEX",
|
|
162
|
+
titulo: "Sneaker Runner Blanco",
|
|
163
|
+
descripcion:
|
|
164
|
+
"Silueta runner de perfil bajo en cuero y malla. Entresuela de EVA con amortiguación para todo el día.",
|
|
165
|
+
precio: "$ 289.900",
|
|
166
|
+
compareAt: "$ 349.900",
|
|
167
|
+
descuentoPct: 17,
|
|
168
|
+
imagenes: [
|
|
169
|
+
{ url: "https://picsum.photos/seed/pdp-1/1200/1500", alt: "Sneaker Runner Blanco — lateral" },
|
|
170
|
+
{ url: "https://picsum.photos/seed/pdp-2/1200/1500", alt: "Sneaker Runner Blanco — detalle" },
|
|
171
|
+
{ url: "https://picsum.photos/seed/pdp-3/1200/1500", alt: "Sneaker Runner Blanco — puesto" },
|
|
172
|
+
{ url: "https://picsum.photos/seed/pdp-4/1200/1500", alt: "Sneaker Runner Blanco — suela" },
|
|
173
|
+
],
|
|
174
|
+
rating: { promedio: 4.6, total: 213 },
|
|
175
|
+
envioInfo: [
|
|
176
|
+
"🚚 Envío a Bogotá: 2–4 días hábiles · gratis desde $150.000",
|
|
177
|
+
"Paga con PSE, tarjeta o efectivo",
|
|
178
|
+
"↩ Cambios y devoluciones gratis por 30 días",
|
|
179
|
+
],
|
|
180
|
+
acordeon: [
|
|
181
|
+
{
|
|
182
|
+
titulo: "Descripción",
|
|
183
|
+
cuerpo:
|
|
184
|
+
"Silueta runner de perfil bajo en cuero y malla. Entresuela de EVA con amortiguación para todo el día.",
|
|
185
|
+
},
|
|
186
|
+
{ titulo: "Materiales y cuidado", cuerpo: "Cuero sintético y malla transpirable. Limpiar con paño húmedo." },
|
|
187
|
+
{ titulo: "Envíos y devoluciones", cuerpo: "Envío gratis desde $150.000. Devoluciones gratis por 30 días." },
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
variantes: {
|
|
191
|
+
color: [
|
|
192
|
+
{ valor: "blanco", etiqueta: "Blanco", swatchUrl: "https://picsum.photos/seed/color-blanco/52/52" },
|
|
193
|
+
{ valor: "negro", etiqueta: "Negro", swatchUrl: "https://picsum.photos/seed/color-negro/52/52" },
|
|
194
|
+
{ valor: "gris", etiqueta: "Gris", swatchUrl: "https://picsum.photos/seed/color-gris/52/52" },
|
|
195
|
+
],
|
|
196
|
+
talla: [
|
|
197
|
+
{ valor: "37", etiqueta: "37", agotada: false },
|
|
198
|
+
{ valor: "38", etiqueta: "38", agotada: false },
|
|
199
|
+
{ valor: "39", etiqueta: "39", agotada: false, pocasUnidades: 2 },
|
|
200
|
+
{ valor: "40", etiqueta: "40", agotada: true },
|
|
201
|
+
{ valor: "41", etiqueta: "41", agotada: false },
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
resolverVariante: (sel) => (sel.talla ? `var_${sel.talla}${sel.color ? `_${sel.color}` : ""}` : null),
|
|
205
|
+
reseñas: {
|
|
206
|
+
promedio: 4.6,
|
|
207
|
+
total: 213,
|
|
208
|
+
histograma: [
|
|
209
|
+
{ estrellas: 5, porcentaje: 72 },
|
|
210
|
+
{ estrellas: 4, porcentaje: 18 },
|
|
211
|
+
{ estrellas: 3, porcentaje: 7 },
|
|
212
|
+
{ estrellas: 2, porcentaje: 2 },
|
|
213
|
+
{ estrellas: 1, porcentaje: 1 },
|
|
214
|
+
],
|
|
215
|
+
muestra: [
|
|
216
|
+
{
|
|
217
|
+
autor: "Camila R.",
|
|
218
|
+
estrellas: 5,
|
|
219
|
+
verificada: true,
|
|
220
|
+
talla: "38",
|
|
221
|
+
texto:
|
|
222
|
+
"Súper cómodos para caminar todo el día. La talla es fiel, pedí mi talla usual y quedó perfecta.",
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
autor: "Andrés M.",
|
|
226
|
+
estrellas: 4,
|
|
227
|
+
verificada: true,
|
|
228
|
+
talla: "42",
|
|
229
|
+
texto: "Buen material y llegaron en 3 días a Medellín. El blanco se ensucia rápido, pero se limpian fácil.",
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
relacionados: [fixtureProductos[1], fixtureProductos[2]],
|
|
234
|
+
...overrides,
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import { THEME_DEFAULTS, THEME_PRESETS } from "./theme"
|
|
3
|
+
|
|
4
|
+
describe("THEME_DEFAULTS", () => {
|
|
5
|
+
it("es el preset kinetic (el brand del template)", () => {
|
|
6
|
+
expect(THEME_DEFAULTS).toBe(THEME_PRESETS.kinetic)
|
|
7
|
+
expect(THEME_DEFAULTS["fuente-titulo"]).toBe("archivo-black")
|
|
8
|
+
})
|
|
9
|
+
})
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import { FUENTES, THEME_DEFAULTS, THEME_PRESETS, themeModaCss, themeTokens } from "./theme"
|
|
3
|
+
|
|
4
|
+
describe("themeTokens", () => {
|
|
5
|
+
it("declara los 25 tokens del tema de moda", () => {
|
|
6
|
+
expect(Object.keys(themeTokens).length).toBe(25)
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it("incluye los tokens de fundaciones Kinetic", () => {
|
|
10
|
+
for (const key of [
|
|
11
|
+
"acento-2", "sombra-sm", "sombra-md", "sombra-lg",
|
|
12
|
+
"radio-sm", "radio-md", "radio-lg", "radio-full", "degradado",
|
|
13
|
+
]) {
|
|
14
|
+
expect(themeTokens[key], `falta token ${key}`).toBeDefined()
|
|
15
|
+
}
|
|
16
|
+
expect(themeTokens["acento-2"].tipo).toBe("color")
|
|
17
|
+
expect(themeTokens["sombra-md"].tipo).toBe("medida")
|
|
18
|
+
expect(themeTokens["acento-2"].cssVars).toContain("--cms-acento-2")
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
describe("FUENTES", () => {
|
|
23
|
+
it("incluye Archivo Black", () => {
|
|
24
|
+
expect(FUENTES["archivo-black"]).toBeDefined()
|
|
25
|
+
expect(FUENTES["archivo-black"].stack).toContain("Archivo Black")
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe("THEME_PRESETS", () => {
|
|
30
|
+
it("cada preset tiene las mismas 25 claves que themeTokens", () => {
|
|
31
|
+
const esperadas = Object.keys(themeTokens).sort()
|
|
32
|
+
for (const [nombre, preset] of Object.entries(THEME_PRESETS)) {
|
|
33
|
+
expect(Object.keys(preset).sort(), `preset ${nombre}`).toEqual(esperadas)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it("THEME_DEFAULTS es el preset kinetic (brand del template)", () => {
|
|
38
|
+
expect(THEME_DEFAULTS).toBe(THEME_PRESETS.kinetic)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it("incluye el preset kinetic (cobalto + coral + Archivo Black)", () => {
|
|
42
|
+
const k = THEME_PRESETS.kinetic
|
|
43
|
+
expect(k.acento).toBe("#3b2bff")
|
|
44
|
+
expect(k["acento-2"]).toBe("#ff3b2e")
|
|
45
|
+
expect(k["fuente-titulo"]).toBe("archivo-black")
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe("themeModaCss", () => {
|
|
50
|
+
it("editorial produce --cms-fondo: #fafaf8", () => {
|
|
51
|
+
const css = themeModaCss(THEME_PRESETS.editorial)
|
|
52
|
+
expect(css).toContain("--cms-fondo: #fafaf8")
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it("street produce --cms-titulo-transform: uppercase y --cms-primario: oklch(0.87 0.19 128)", () => {
|
|
56
|
+
const css = themeModaCss(THEME_PRESETS.street)
|
|
57
|
+
expect(css).toContain("--cms-titulo-transform: uppercase")
|
|
58
|
+
expect(css).toContain("--cms-primario: oklch(0.87 0.19 128)")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("premium produce --cms-radio: 2px y utility --cms-grosor-borde: 1.5px", () => {
|
|
62
|
+
expect(themeModaCss(THEME_PRESETS.premium)).toContain("--cms-radio: 2px")
|
|
63
|
+
expect(themeModaCss(THEME_PRESETS.utility)).toContain("--cms-grosor-borde: 1.5px")
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it("no omite ningún token de los 25 en ningún preset (25 declaraciones por preset)", () => {
|
|
67
|
+
for (const preset of Object.values(THEME_PRESETS)) {
|
|
68
|
+
const css = themeModaCss(preset)
|
|
69
|
+
const declaraciones = css.split(";").map((s) => s.trim()).filter(Boolean)
|
|
70
|
+
expect(declaraciones.length).toBe(25)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("kinetic emite las vars nuevas y resuelve la fuente Archivo Black", () => {
|
|
75
|
+
const css = themeModaCss(THEME_PRESETS.kinetic)
|
|
76
|
+
expect(css).toContain("--cms-acento-2: #ff3b2e")
|
|
77
|
+
expect(css).toContain("--cms-radio-full: 999px")
|
|
78
|
+
expect(css).toContain("--cms-sombra-md:")
|
|
79
|
+
expect(css).toContain("--cms-degradado: linear-gradient(120deg,#3b2bff,#ff3b2e)")
|
|
80
|
+
expect(css).toContain("--cms-fuente-titulo: 'Archivo Black',sans-serif")
|
|
81
|
+
})
|
|
82
|
+
})
|
package/src/theme.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { FuenteDef, ThemeTokenDef } from "@arroyavecommerce/cms-core/theme"
|
|
2
|
+
import { themeToCss } from "@arroyavecommerce/cms-core/theme"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tema de la plantilla de moda: 25 tokens `--cms-*` (9 colores, 3 fuentes,
|
|
6
|
+
* 13 medidas) y 5 presets (editorial/street/premium/utility/kinetic) sobre
|
|
7
|
+
* esos mismos tokens. Los tokens de "fundaciones Kinetic" (acento-2, sombras,
|
|
8
|
+
* radios por tamaño, degradado) son aditivos: `themeToCss` solo emite lo que
|
|
9
|
+
* está en el mapa publicado, así que los consumidores usan `var(--cms-x, fb)`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const themeTokens: Record<string, ThemeTokenDef> = {
|
|
13
|
+
fondo: { label: "Fondo", tipo: "color", default: "#fafaf8", cssVars: ["--cms-fondo"] },
|
|
14
|
+
superficie: { label: "Superficie", tipo: "color", default: "#ffffff", cssVars: ["--cms-superficie"] },
|
|
15
|
+
texto: { label: "Texto", tipo: "color", default: "#151515", cssVars: ["--cms-texto"] },
|
|
16
|
+
"texto-suave": { label: "Texto suave", tipo: "color", default: "#666666", cssVars: ["--cms-texto-suave"] },
|
|
17
|
+
primario: { label: "Primario", tipo: "color", default: "#151515", cssVars: ["--cms-primario"] },
|
|
18
|
+
"primario-texto": { label: "Texto sobre primario", tipo: "color", default: "#ffffff", cssVars: ["--cms-primario-texto"] },
|
|
19
|
+
acento: { label: "Acento", tipo: "color", default: "#151515", cssVars: ["--cms-acento"] },
|
|
20
|
+
"acento-2": { label: "Acento secundario", tipo: "color", default: "#ff3b2e", cssVars: ["--cms-acento-2"] },
|
|
21
|
+
borde: { label: "Borde", tipo: "color", default: "#e6e4df", cssVars: ["--cms-borde"] },
|
|
22
|
+
|
|
23
|
+
"fuente-titulo": { label: "Fuente de títulos", tipo: "fuente", default: "archivo", cssVars: ["--cms-fuente-titulo"] },
|
|
24
|
+
"fuente-texto": { label: "Fuente de texto", tipo: "fuente", default: "archivo", cssVars: ["--cms-fuente-texto"] },
|
|
25
|
+
"fuente-mono": { label: "Fuente monoespaciada", tipo: "fuente", default: "ibm-plex-mono", cssVars: ["--cms-fuente-mono"] },
|
|
26
|
+
|
|
27
|
+
radio: { label: "Radio de esquinas", tipo: "medida", default: "0px", cssVars: ["--cms-radio"] },
|
|
28
|
+
"radio-sm": { label: "Radio chico", tipo: "medida", default: "6px", cssVars: ["--cms-radio-sm"] },
|
|
29
|
+
"radio-md": { label: "Radio medio", tipo: "medida", default: "12px", cssVars: ["--cms-radio-md"] },
|
|
30
|
+
"radio-lg": { label: "Radio grande", tipo: "medida", default: "20px", cssVars: ["--cms-radio-lg"] },
|
|
31
|
+
"radio-full": { label: "Radio circular", tipo: "medida", default: "999px", cssVars: ["--cms-radio-full"] },
|
|
32
|
+
"grosor-borde": { label: "Grosor de borde", tipo: "medida", default: "1px", cssVars: ["--cms-grosor-borde"] },
|
|
33
|
+
"sombra-sm": { label: "Sombra chica", tipo: "medida", default: "0 1px 2px rgba(0,0,0,0.06)", cssVars: ["--cms-sombra-sm"] },
|
|
34
|
+
"sombra-md": { label: "Sombra media", tipo: "medida", default: "0 10px 30px -12px rgba(0,0,0,0.18)", cssVars: ["--cms-sombra-md"] },
|
|
35
|
+
"sombra-lg": { label: "Sombra grande", tipo: "medida", default: "0 30px 70px -28px rgba(0,0,0,0.32)", cssVars: ["--cms-sombra-lg"] },
|
|
36
|
+
"degradado": { label: "Degradado", tipo: "medida", default: "linear-gradient(120deg,#3b2bff,#ff3b2e)", cssVars: ["--cms-degradado"] },
|
|
37
|
+
"titulo-peso": { label: "Peso de títulos", tipo: "medida", default: "600", cssVars: ["--cms-titulo-peso"] },
|
|
38
|
+
"titulo-transform": { label: "Transformación de títulos", tipo: "medida", default: "none", cssVars: ["--cms-titulo-transform"] },
|
|
39
|
+
"titulo-espaciado": { label: "Espaciado de títulos", tipo: "medida", default: "-0.02em", cssVars: ["--cms-titulo-espaciado"] },
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const FUENTES: Record<string, FuenteDef> = {
|
|
43
|
+
archivo: { label: "Archivo", stack: "'Archivo',sans-serif" },
|
|
44
|
+
"archivo-black": { label: "Archivo Black", stack: "'Archivo Black',sans-serif" },
|
|
45
|
+
anton: { label: "Anton", stack: "'Anton',sans-serif" },
|
|
46
|
+
"libre-caslon": { label: "Libre Caslon Text", stack: "'Libre Caslon Text',serif" },
|
|
47
|
+
"ibm-plex-mono": { label: "IBM Plex Mono", stack: "'IBM Plex Mono',monospace" },
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const THEME_PRESETS: Record<
|
|
51
|
+
"editorial" | "street" | "premium" | "utility" | "kinetic",
|
|
52
|
+
Record<string, string>
|
|
53
|
+
> = {
|
|
54
|
+
editorial: {
|
|
55
|
+
fondo: "#fafaf8",
|
|
56
|
+
superficie: "#ffffff",
|
|
57
|
+
texto: "#151515",
|
|
58
|
+
"texto-suave": "#666666",
|
|
59
|
+
primario: "#151515",
|
|
60
|
+
"primario-texto": "#ffffff",
|
|
61
|
+
acento: "#151515",
|
|
62
|
+
"acento-2": "#151515",
|
|
63
|
+
borde: "#e6e4df",
|
|
64
|
+
radio: "0px",
|
|
65
|
+
"radio-sm": "0px",
|
|
66
|
+
"radio-md": "0px",
|
|
67
|
+
"radio-lg": "0px",
|
|
68
|
+
"radio-full": "999px",
|
|
69
|
+
"grosor-borde": "1px",
|
|
70
|
+
"sombra-sm": "0 1px 2px rgba(0,0,0,0.05)",
|
|
71
|
+
"sombra-md": "0 4px 16px -8px rgba(0,0,0,0.12)",
|
|
72
|
+
"sombra-lg": "0 18px 40px -24px rgba(0,0,0,0.22)",
|
|
73
|
+
"degradado": "linear-gradient(120deg,#151515,#333333)",
|
|
74
|
+
"fuente-titulo": "archivo",
|
|
75
|
+
"fuente-texto": "archivo",
|
|
76
|
+
"fuente-mono": "ibm-plex-mono",
|
|
77
|
+
"titulo-peso": "600",
|
|
78
|
+
"titulo-transform": "none",
|
|
79
|
+
"titulo-espaciado": "-0.02em",
|
|
80
|
+
},
|
|
81
|
+
street: {
|
|
82
|
+
fondo: "#101010",
|
|
83
|
+
superficie: "#181818",
|
|
84
|
+
texto: "#f2f2ef",
|
|
85
|
+
"texto-suave": "#999999",
|
|
86
|
+
primario: "oklch(0.87 0.19 128)",
|
|
87
|
+
"primario-texto": "#101010",
|
|
88
|
+
acento: "oklch(0.87 0.19 128)",
|
|
89
|
+
"acento-2": "#ff2e6a",
|
|
90
|
+
borde: "#262626",
|
|
91
|
+
radio: "0px",
|
|
92
|
+
"radio-sm": "0px",
|
|
93
|
+
"radio-md": "2px",
|
|
94
|
+
"radio-lg": "4px",
|
|
95
|
+
"radio-full": "999px",
|
|
96
|
+
"grosor-borde": "1px",
|
|
97
|
+
"sombra-sm": "0 1px 2px rgba(0,0,0,0.4)",
|
|
98
|
+
"sombra-md": "0 10px 30px -12px rgba(0,0,0,0.6)",
|
|
99
|
+
"sombra-lg": "0 30px 70px -28px rgba(0,0,0,0.75)",
|
|
100
|
+
"degradado": "linear-gradient(120deg,oklch(0.87 0.19 128),#101010)",
|
|
101
|
+
"fuente-titulo": "anton",
|
|
102
|
+
"fuente-texto": "archivo",
|
|
103
|
+
"fuente-mono": "ibm-plex-mono",
|
|
104
|
+
"titulo-peso": "400",
|
|
105
|
+
"titulo-transform": "uppercase",
|
|
106
|
+
"titulo-espaciado": "0.01em",
|
|
107
|
+
},
|
|
108
|
+
premium: {
|
|
109
|
+
fondo: "#f6f1e8",
|
|
110
|
+
superficie: "#fdfaf4",
|
|
111
|
+
texto: "#2b2620",
|
|
112
|
+
"texto-suave": "#6b6459",
|
|
113
|
+
primario: "#2b2620",
|
|
114
|
+
"primario-texto": "#f6f1e8",
|
|
115
|
+
acento: "oklch(0.55 0.11 50)",
|
|
116
|
+
"acento-2": "oklch(0.55 0.11 50)",
|
|
117
|
+
borde: "#e3dccd",
|
|
118
|
+
radio: "2px",
|
|
119
|
+
"radio-sm": "2px",
|
|
120
|
+
"radio-md": "4px",
|
|
121
|
+
"radio-lg": "10px",
|
|
122
|
+
"radio-full": "999px",
|
|
123
|
+
"grosor-borde": "1px",
|
|
124
|
+
"sombra-sm": "0 1px 2px rgba(43,38,32,0.06)",
|
|
125
|
+
"sombra-md": "0 8px 24px -12px rgba(43,38,32,0.16)",
|
|
126
|
+
"sombra-lg": "0 24px 60px -26px rgba(43,38,32,0.28)",
|
|
127
|
+
"degradado": "linear-gradient(120deg,#2b2620,#6b6459)",
|
|
128
|
+
"fuente-titulo": "libre-caslon",
|
|
129
|
+
"fuente-texto": "archivo",
|
|
130
|
+
"fuente-mono": "ibm-plex-mono",
|
|
131
|
+
"titulo-peso": "400",
|
|
132
|
+
"titulo-transform": "none",
|
|
133
|
+
"titulo-espaciado": "0",
|
|
134
|
+
},
|
|
135
|
+
utility: {
|
|
136
|
+
fondo: "#f2f2f0",
|
|
137
|
+
superficie: "#fbfbfa",
|
|
138
|
+
texto: "#1a1a1a",
|
|
139
|
+
"texto-suave": "#666666",
|
|
140
|
+
primario: "oklch(0.62 0.19 40)",
|
|
141
|
+
"primario-texto": "#ffffff",
|
|
142
|
+
acento: "oklch(0.62 0.19 40)",
|
|
143
|
+
"acento-2": "oklch(0.62 0.19 40)",
|
|
144
|
+
borde: "#1a1a1a",
|
|
145
|
+
radio: "0px",
|
|
146
|
+
"radio-sm": "0px",
|
|
147
|
+
"radio-md": "0px",
|
|
148
|
+
"radio-lg": "0px",
|
|
149
|
+
"radio-full": "999px",
|
|
150
|
+
"grosor-borde": "1.5px",
|
|
151
|
+
"sombra-sm": "0 1px 0 rgba(0,0,0,0.08)",
|
|
152
|
+
"sombra-md": "0 6px 18px -10px rgba(0,0,0,0.18)",
|
|
153
|
+
"sombra-lg": "0 20px 44px -24px rgba(0,0,0,0.3)",
|
|
154
|
+
"degradado": "linear-gradient(120deg,oklch(0.62 0.19 40),#1a1a1a)",
|
|
155
|
+
"fuente-titulo": "archivo",
|
|
156
|
+
"fuente-texto": "archivo",
|
|
157
|
+
"fuente-mono": "ibm-plex-mono",
|
|
158
|
+
"titulo-peso": "700",
|
|
159
|
+
"titulo-transform": "none",
|
|
160
|
+
"titulo-espaciado": "-0.01em",
|
|
161
|
+
},
|
|
162
|
+
kinetic: {
|
|
163
|
+
fondo: "#f1eee6",
|
|
164
|
+
superficie: "#ffffff",
|
|
165
|
+
texto: "#0c0c10",
|
|
166
|
+
"texto-suave": "#6b675e",
|
|
167
|
+
primario: "#3b2bff",
|
|
168
|
+
"primario-texto": "#ffffff",
|
|
169
|
+
acento: "#3b2bff",
|
|
170
|
+
"acento-2": "#ff3b2e",
|
|
171
|
+
borde: "#dbd6c9",
|
|
172
|
+
radio: "8px",
|
|
173
|
+
"radio-sm": "8px",
|
|
174
|
+
"radio-md": "14px",
|
|
175
|
+
"radio-lg": "22px",
|
|
176
|
+
"radio-full": "999px",
|
|
177
|
+
"grosor-borde": "1px",
|
|
178
|
+
"sombra-sm": "0 1px 2px rgba(12,12,16,0.06)",
|
|
179
|
+
"sombra-md": "0 10px 30px -12px rgba(12,12,16,0.22)",
|
|
180
|
+
"sombra-lg": "0 30px 70px -28px rgba(12,12,16,0.4)",
|
|
181
|
+
"degradado": "linear-gradient(120deg,#3b2bff,#ff3b2e)",
|
|
182
|
+
"fuente-titulo": "archivo-black",
|
|
183
|
+
"fuente-texto": "archivo",
|
|
184
|
+
"fuente-mono": "ibm-plex-mono",
|
|
185
|
+
"titulo-peso": "900",
|
|
186
|
+
"titulo-transform": "uppercase",
|
|
187
|
+
"titulo-espaciado": "-0.04em",
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export const THEME_DEFAULTS: Record<string, string> = THEME_PRESETS.kinetic
|
|
192
|
+
|
|
193
|
+
export function themeModaCss(tokens: Record<string, string>): string {
|
|
194
|
+
return themeToCss(tokens, { tokens: themeTokens, fuentes: FUENTES }, () => {})
|
|
195
|
+
}
|
package/tsconfig.json
ADDED