@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,136 @@
|
|
|
1
|
+
import type { FC } from "react"
|
|
2
|
+
import type { IconProps } from "./svg-base"
|
|
3
|
+
import {
|
|
4
|
+
AddiIcon,
|
|
5
|
+
AmexIcon,
|
|
6
|
+
ApplepayIcon,
|
|
7
|
+
BancolombiaIcon,
|
|
8
|
+
BitcoinIcon,
|
|
9
|
+
DaviplataIcon,
|
|
10
|
+
DinersIcon,
|
|
11
|
+
DiscoverIcon,
|
|
12
|
+
EfectivoIcon,
|
|
13
|
+
EfectyIcon,
|
|
14
|
+
GooglepayIcon,
|
|
15
|
+
MaestroIcon,
|
|
16
|
+
MastercardIcon,
|
|
17
|
+
MercadopagoIcon,
|
|
18
|
+
NequiIcon,
|
|
19
|
+
PaypalIcon,
|
|
20
|
+
PseIcon,
|
|
21
|
+
VisaIcon,
|
|
22
|
+
} from "./payment-icons"
|
|
23
|
+
import {
|
|
24
|
+
FacebookIcon,
|
|
25
|
+
InstagramIcon,
|
|
26
|
+
LinkedinIcon,
|
|
27
|
+
PinterestIcon,
|
|
28
|
+
ThreadsIcon,
|
|
29
|
+
TiktokIcon,
|
|
30
|
+
WhatsappIcon,
|
|
31
|
+
XIcon,
|
|
32
|
+
YoutubeIcon,
|
|
33
|
+
} from "./social-icons"
|
|
34
|
+
|
|
35
|
+
export type { IconProps }
|
|
36
|
+
|
|
37
|
+
export type PaymentKey =
|
|
38
|
+
| "visa"
|
|
39
|
+
| "mastercard"
|
|
40
|
+
| "amex"
|
|
41
|
+
| "diners"
|
|
42
|
+
| "pse"
|
|
43
|
+
| "nequi"
|
|
44
|
+
| "daviplata"
|
|
45
|
+
| "bancolombia"
|
|
46
|
+
| "efecty"
|
|
47
|
+
| "addi"
|
|
48
|
+
| "mercadopago"
|
|
49
|
+
| "paypal"
|
|
50
|
+
| "efectivo"
|
|
51
|
+
| "applepay"
|
|
52
|
+
| "googlepay"
|
|
53
|
+
| "maestro"
|
|
54
|
+
| "discover"
|
|
55
|
+
| "bitcoin"
|
|
56
|
+
|
|
57
|
+
export type SocialKey =
|
|
58
|
+
| "instagram"
|
|
59
|
+
| "tiktok"
|
|
60
|
+
| "whatsapp"
|
|
61
|
+
| "x"
|
|
62
|
+
| "facebook"
|
|
63
|
+
| "youtube"
|
|
64
|
+
| "threads"
|
|
65
|
+
| "pinterest"
|
|
66
|
+
| "linkedin"
|
|
67
|
+
|
|
68
|
+
export type IconEntry = { label: string; Icon: FC<IconProps> }
|
|
69
|
+
|
|
70
|
+
/** Registro tipado de iconos de medios de pago. */
|
|
71
|
+
export const PAYMENT_ICONS: Record<PaymentKey, IconEntry> = {
|
|
72
|
+
visa: { label: "Visa", Icon: VisaIcon },
|
|
73
|
+
mastercard: { label: "Mastercard", Icon: MastercardIcon },
|
|
74
|
+
amex: { label: "American Express", Icon: AmexIcon },
|
|
75
|
+
diners: { label: "Diners Club", Icon: DinersIcon },
|
|
76
|
+
pse: { label: "PSE", Icon: PseIcon },
|
|
77
|
+
nequi: { label: "Nequi", Icon: NequiIcon },
|
|
78
|
+
daviplata: { label: "DaviPlata", Icon: DaviplataIcon },
|
|
79
|
+
bancolombia: { label: "Bancolombia", Icon: BancolombiaIcon },
|
|
80
|
+
efecty: { label: "Efecty", Icon: EfectyIcon },
|
|
81
|
+
addi: { label: "Addi", Icon: AddiIcon },
|
|
82
|
+
mercadopago: { label: "Mercado Pago", Icon: MercadopagoIcon },
|
|
83
|
+
paypal: { label: "PayPal", Icon: PaypalIcon },
|
|
84
|
+
efectivo: { label: "Efectivo", Icon: EfectivoIcon },
|
|
85
|
+
applepay: { label: "Apple Pay", Icon: ApplepayIcon },
|
|
86
|
+
googlepay: { label: "Google Pay", Icon: GooglepayIcon },
|
|
87
|
+
maestro: { label: "Maestro", Icon: MaestroIcon },
|
|
88
|
+
discover: { label: "Discover", Icon: DiscoverIcon },
|
|
89
|
+
bitcoin: { label: "Bitcoin", Icon: BitcoinIcon },
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Registro tipado de iconos de redes sociales. */
|
|
93
|
+
export const SOCIAL_ICONS: Record<SocialKey, IconEntry> = {
|
|
94
|
+
instagram: { label: "Instagram", Icon: InstagramIcon },
|
|
95
|
+
tiktok: { label: "TikTok", Icon: TiktokIcon },
|
|
96
|
+
whatsapp: { label: "WhatsApp", Icon: WhatsappIcon },
|
|
97
|
+
x: { label: "X", Icon: XIcon },
|
|
98
|
+
facebook: { label: "Facebook", Icon: FacebookIcon },
|
|
99
|
+
youtube: { label: "YouTube", Icon: YoutubeIcon },
|
|
100
|
+
threads: { label: "Threads", Icon: ThreadsIcon },
|
|
101
|
+
pinterest: { label: "Pinterest", Icon: PinterestIcon },
|
|
102
|
+
linkedin: { label: "LinkedIn", Icon: LinkedinIcon },
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
AddiIcon,
|
|
107
|
+
AmexIcon,
|
|
108
|
+
ApplepayIcon,
|
|
109
|
+
BancolombiaIcon,
|
|
110
|
+
BitcoinIcon,
|
|
111
|
+
DaviplataIcon,
|
|
112
|
+
DinersIcon,
|
|
113
|
+
DiscoverIcon,
|
|
114
|
+
EfectivoIcon,
|
|
115
|
+
EfectyIcon,
|
|
116
|
+
GooglepayIcon,
|
|
117
|
+
MaestroIcon,
|
|
118
|
+
MastercardIcon,
|
|
119
|
+
MercadopagoIcon,
|
|
120
|
+
NequiIcon,
|
|
121
|
+
PaypalIcon,
|
|
122
|
+
PseIcon,
|
|
123
|
+
VisaIcon,
|
|
124
|
+
} from "./payment-icons"
|
|
125
|
+
|
|
126
|
+
export {
|
|
127
|
+
FacebookIcon,
|
|
128
|
+
InstagramIcon,
|
|
129
|
+
LinkedinIcon,
|
|
130
|
+
PinterestIcon,
|
|
131
|
+
ThreadsIcon,
|
|
132
|
+
TiktokIcon,
|
|
133
|
+
WhatsappIcon,
|
|
134
|
+
XIcon,
|
|
135
|
+
YoutubeIcon,
|
|
136
|
+
} from "./social-icons"
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { Svg, type IconProps } from "./svg-base"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Iconos de medios de pago — marcas reconocibles y simplificadas, legibles a
|
|
5
|
+
* ~20–30px de alto. Los colores de marca viven en elementos con `data-brand`
|
|
6
|
+
* para permitir el tintado monocromo por CSS (ver `svg-base.tsx`). Los huecos
|
|
7
|
+
* blancos (negativo del logo) NO llevan `data-brand`.
|
|
8
|
+
*
|
|
9
|
+
* No son logos pixel-perfect: priorizan legibilidad y reconocimiento.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Pila de fuentes sans para wordmarks; bold para máxima legibilidad en chico. */
|
|
13
|
+
const SANS = "'Helvetica Neue', Arial, sans-serif"
|
|
14
|
+
|
|
15
|
+
/** Wordmark reutilizable centrado en un badge rectangular. */
|
|
16
|
+
function Wordmark({
|
|
17
|
+
texto,
|
|
18
|
+
color,
|
|
19
|
+
props,
|
|
20
|
+
italic,
|
|
21
|
+
weight = 800,
|
|
22
|
+
letterSpacing = 0,
|
|
23
|
+
fontSize = 15,
|
|
24
|
+
}: {
|
|
25
|
+
texto: string
|
|
26
|
+
color: string
|
|
27
|
+
props: IconProps
|
|
28
|
+
italic?: boolean
|
|
29
|
+
weight?: number
|
|
30
|
+
letterSpacing?: number
|
|
31
|
+
fontSize?: number
|
|
32
|
+
}) {
|
|
33
|
+
return (
|
|
34
|
+
<Svg viewBox="0 0 64 24" {...props}>
|
|
35
|
+
<text
|
|
36
|
+
data-brand
|
|
37
|
+
x="32"
|
|
38
|
+
y="17"
|
|
39
|
+
textAnchor="middle"
|
|
40
|
+
fontFamily={SANS}
|
|
41
|
+
fontSize={fontSize}
|
|
42
|
+
fontWeight={weight}
|
|
43
|
+
fontStyle={italic ? "italic" : undefined}
|
|
44
|
+
letterSpacing={letterSpacing}
|
|
45
|
+
fill={color}
|
|
46
|
+
>
|
|
47
|
+
{texto}
|
|
48
|
+
</text>
|
|
49
|
+
</Svg>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const VisaIcon = (props: IconProps) => (
|
|
54
|
+
<Wordmark texto="VISA" color="#1A1F71" italic letterSpacing={1} props={props} />
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
export const MastercardIcon = (props: IconProps) => (
|
|
58
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
59
|
+
<circle data-brand cx="16" cy="12" r="9" fill="#EB001B" />
|
|
60
|
+
<circle data-brand cx="24" cy="12" r="9" fill="#F79E1B" fillOpacity="0.9" />
|
|
61
|
+
{/* Solape central: naranja translúcido sobre rojo insinúa el ámbar Mastercard */}
|
|
62
|
+
<path data-brand d="M20 5.2a9 9 0 0 0 0 13.6 9 9 0 0 0 0-13.6z" fill="#FF5F00" />
|
|
63
|
+
</Svg>
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
export const AmexIcon = (props: IconProps) => (
|
|
67
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
68
|
+
<rect data-brand x="1" y="1" width="38" height="22" rx="3" fill="#2E77BB" />
|
|
69
|
+
<text
|
|
70
|
+
x="20"
|
|
71
|
+
y="16"
|
|
72
|
+
textAnchor="middle"
|
|
73
|
+
fontFamily={SANS}
|
|
74
|
+
fontSize="10"
|
|
75
|
+
fontWeight="800"
|
|
76
|
+
letterSpacing="0.5"
|
|
77
|
+
fill="#FFFFFF"
|
|
78
|
+
>
|
|
79
|
+
AMEX
|
|
80
|
+
</text>
|
|
81
|
+
</Svg>
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
export const DinersIcon = (props: IconProps) => (
|
|
85
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
86
|
+
<circle data-brand cx="20" cy="12" r="10" fill="#0079BE" />
|
|
87
|
+
<circle cx="20" cy="12" r="6.5" fill="#FFFFFF" />
|
|
88
|
+
<circle data-brand cx="20" cy="12" r="4" fill="#0079BE" />
|
|
89
|
+
</Svg>
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
export const PseIcon = (props: IconProps) => (
|
|
93
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
94
|
+
<rect data-brand x="1" y="1" width="38" height="22" rx="3" fill="#00579F" />
|
|
95
|
+
<text
|
|
96
|
+
x="20"
|
|
97
|
+
y="16"
|
|
98
|
+
textAnchor="middle"
|
|
99
|
+
fontFamily={SANS}
|
|
100
|
+
fontSize="11"
|
|
101
|
+
fontWeight="800"
|
|
102
|
+
letterSpacing="1"
|
|
103
|
+
fill="#FFFFFF"
|
|
104
|
+
>
|
|
105
|
+
PSE
|
|
106
|
+
</text>
|
|
107
|
+
</Svg>
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
export const NequiIcon = (props: IconProps) => (
|
|
111
|
+
<Wordmark texto="Nequi" color="#DA0081" weight={800} fontSize={14} props={props} />
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
export const DaviplataIcon = (props: IconProps) => (
|
|
115
|
+
<Wordmark texto="DaviPlata" color="#ED1C27" weight={800} fontSize={11} props={props} />
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
export const BancolombiaIcon = (props: IconProps) => (
|
|
119
|
+
<Svg viewBox="0 0 64 24" {...props}>
|
|
120
|
+
<rect data-brand x="4" y="7" width="10" height="10" rx="1.5" fill="#FDDA24" />
|
|
121
|
+
<path data-brand d="M6.5 12h5M9 9.5v5" stroke="#2C2A29" strokeWidth="1.6" />
|
|
122
|
+
<text
|
|
123
|
+
data-brand
|
|
124
|
+
x="18"
|
|
125
|
+
y="16"
|
|
126
|
+
fontFamily={SANS}
|
|
127
|
+
fontSize="9"
|
|
128
|
+
fontWeight="800"
|
|
129
|
+
fill="#2C2A29"
|
|
130
|
+
>
|
|
131
|
+
Bancolombia
|
|
132
|
+
</text>
|
|
133
|
+
</Svg>
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
export const EfectyIcon = (props: IconProps) => (
|
|
137
|
+
<Wordmark texto="Efecty" color="#8DC63F" weight={800} fontSize={13} props={props} />
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
export const AddiIcon = (props: IconProps) => (
|
|
141
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
142
|
+
<rect data-brand x="1" y="1" width="38" height="22" rx="6" fill="#161615" />
|
|
143
|
+
<text
|
|
144
|
+
x="20"
|
|
145
|
+
y="16"
|
|
146
|
+
textAnchor="middle"
|
|
147
|
+
fontFamily={SANS}
|
|
148
|
+
fontSize="11"
|
|
149
|
+
fontWeight="800"
|
|
150
|
+
letterSpacing="0.5"
|
|
151
|
+
fill="#C6F24E"
|
|
152
|
+
>
|
|
153
|
+
addi
|
|
154
|
+
</text>
|
|
155
|
+
</Svg>
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
export const MercadopagoIcon = (props: IconProps) => (
|
|
159
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
160
|
+
<ellipse data-brand cx="20" cy="12" rx="18" ry="10" fill="#009EE3" />
|
|
161
|
+
{/* Apretón de manos simplificado en blanco (negativo del óvalo celeste) */}
|
|
162
|
+
<path
|
|
163
|
+
d="M9 12.5c2.2-2.2 4-2.4 6-1 1.6-1 3-.9 4.4.2l3.2 2.6c.7.6.2 1.7-.7 1.5l-2-.5 1 1c.7.7-.3 1.8-1.1 1.2l-1-.8.4.7c.5.8-.6 1.6-1.3.9l-1.2-1.1c-1.8 1-3.6.7-5.2-.7L9 15.5a1.8 1.8 0 0 1 0-3z"
|
|
164
|
+
fill="#FFFFFF"
|
|
165
|
+
/>
|
|
166
|
+
<circle cx="27" cy="9.5" r="1.6" fill="#FFE600" />
|
|
167
|
+
</Svg>
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
export const PaypalIcon = (props: IconProps) => (
|
|
171
|
+
<Svg viewBox="0 0 64 24" {...props}>
|
|
172
|
+
<text x="6" y="17" fontFamily={SANS} fontSize="15" fontWeight="800" fontStyle="italic">
|
|
173
|
+
<tspan data-brand fill="#003087">Pay</tspan>
|
|
174
|
+
<tspan data-brand fill="#009CDE">Pal</tspan>
|
|
175
|
+
</text>
|
|
176
|
+
</Svg>
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
export const EfectivoIcon = (props: IconProps) => (
|
|
180
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
181
|
+
<rect data-brand x="2" y="5" width="36" height="14" rx="2" fill="#2E7D32" />
|
|
182
|
+
<rect x="5" y="8" width="30" height="8" rx="1" fill="none" stroke="#FFFFFF" strokeWidth="1" />
|
|
183
|
+
<circle cx="20" cy="12" r="3.2" fill="none" stroke="#FFFFFF" strokeWidth="1.2" />
|
|
184
|
+
<text x="20" y="14.5" textAnchor="middle" fontFamily={SANS} fontSize="6" fontWeight="800" fill="#FFFFFF">
|
|
185
|
+
$
|
|
186
|
+
</text>
|
|
187
|
+
</Svg>
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
export const ApplepayIcon = (props: IconProps) => (
|
|
191
|
+
<Svg viewBox="0 0 48 24" {...props}>
|
|
192
|
+
{/* Manzana simplificada */}
|
|
193
|
+
<path
|
|
194
|
+
data-brand
|
|
195
|
+
d="M12.6 8.2c-.5.6-1.3 1-2 .95-.1-.8.28-1.65.73-2.18.5-.6 1.35-1 2.05-1.03.08.83-.25 1.64-.78 2.26zm.77.98c-1.12-.07-2.07.63-2.6.63-.55 0-1.36-.6-2.24-.58-1.15.02-2.22.67-2.8 1.7-1.2 2.08-.31 5.15.85 6.84.57.83 1.24 1.76 2.13 1.73.85-.03 1.18-.55 2.2-.55 1.03 0 1.32.55 2.22.53.92-.02 1.5-.84 2.06-1.68.65-.96.92-1.9.93-1.94-.02-.01-1.78-.69-1.8-2.72-.02-1.7 1.39-2.51 1.45-2.55-.79-1.17-2.02-1.3-2.45-1.33z"
|
|
196
|
+
fill="#000000"
|
|
197
|
+
/>
|
|
198
|
+
<text data-brand x="20" y="16" fontFamily={SANS} fontSize="11" fontWeight="600" fill="#000000">
|
|
199
|
+
Pay
|
|
200
|
+
</text>
|
|
201
|
+
</Svg>
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
export const GooglepayIcon = (props: IconProps) => (
|
|
205
|
+
<Svg viewBox="0 0 48 24" {...props}>
|
|
206
|
+
{/* G multicolor de Google (4 arcos) sobre barra central */}
|
|
207
|
+
<path data-brand d="M11 12a5 5 0 0 1 5-5c1.3 0 2.4.45 3.3 1.2l-1.4 1.4A2.9 2.9 0 0 0 16 9.1 2.9 2.9 0 0 0 13.1 12" fill="#EA4335" />
|
|
208
|
+
<path data-brand d="M13.1 12A2.9 2.9 0 0 0 16 14.9c.9 0 1.6-.3 2.1-.8.4-.4.65-.95.75-1.6H16v-1.9h4.8c.06.34.1.68.1 1.05 0 1.5-.54 2.77-1.48 3.63A4.9 4.9 0 0 1 16 17 5 5 0 0 1 11 12" fill="#4285F4" />
|
|
209
|
+
<path d="M11 12a5 5 0 0 1 .27-1.63l1.9.66A2.9 2.9 0 0 0 13.1 12z" fill="#FBBC04" />
|
|
210
|
+
<path d="M13.1 12a2.9 2.9 0 0 0 .07.63l-1.9.66A5 5 0 0 1 11 12z" fill="#34A853" />
|
|
211
|
+
<text data-brand x="24" y="16" fontFamily={SANS} fontSize="11" fontWeight="600" fill="#5F6368">
|
|
212
|
+
Pay
|
|
213
|
+
</text>
|
|
214
|
+
</Svg>
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
export const MaestroIcon = (props: IconProps) => (
|
|
218
|
+
<Svg viewBox="0 0 40 24" {...props}>
|
|
219
|
+
<circle data-brand cx="16" cy="12" r="9" fill="#0099DF" />
|
|
220
|
+
<circle data-brand cx="24" cy="12" r="9" fill="#ED0006" fillOpacity="0.9" />
|
|
221
|
+
<path data-brand d="M20 5.2a9 9 0 0 0 0 13.6 9 9 0 0 0 0-13.6z" fill="#6C6BBD" />
|
|
222
|
+
</Svg>
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
export const DiscoverIcon = (props: IconProps) => (
|
|
226
|
+
<Svg viewBox="0 0 64 24" {...props}>
|
|
227
|
+
<text data-brand x="4" y="16" fontFamily={SANS} fontSize="10" fontWeight="800" letterSpacing="0.3" fill="#1A1A1A">
|
|
228
|
+
DISCOVER
|
|
229
|
+
</text>
|
|
230
|
+
<circle data-brand cx="58" cy="12.5" r="4.5" fill="#F76E11" />
|
|
231
|
+
</Svg>
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
export const BitcoinIcon = (props: IconProps) => (
|
|
235
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
236
|
+
<circle data-brand cx="12" cy="12" r="11" fill="#F7931A" />
|
|
237
|
+
<text x="12" y="17" textAnchor="middle" fontFamily={SANS} fontSize="15" fontWeight="800" fill="#FFFFFF">
|
|
238
|
+
₿
|
|
239
|
+
</text>
|
|
240
|
+
</Svg>
|
|
241
|
+
)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Svg, type IconProps } from "./svg-base"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Iconos de redes sociales — glifos limpios de marca, legibles a ~20–30px.
|
|
5
|
+
* Los colores de marca viven en elementos con `data-brand` para el tintado
|
|
6
|
+
* monocromo por CSS (ver `svg-base.tsx`). Los huecos blancos (negativo del
|
|
7
|
+
* símbolo) NO llevan `data-brand`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const SANS = "'Helvetica Neue', Arial, sans-serif"
|
|
11
|
+
|
|
12
|
+
export const InstagramIcon = (props: IconProps) => (
|
|
13
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
14
|
+
<defs>
|
|
15
|
+
<linearGradient id="ig-grad" x1="0" y1="24" x2="24" y2="0" gradientUnits="userSpaceOnUse">
|
|
16
|
+
<stop offset="0" stopColor="#FEDA75" />
|
|
17
|
+
<stop offset="0.35" stopColor="#FA7E1E" />
|
|
18
|
+
<stop offset="0.6" stopColor="#D62976" />
|
|
19
|
+
<stop offset="0.8" stopColor="#962FBF" />
|
|
20
|
+
<stop offset="1" stopColor="#4F5BD5" />
|
|
21
|
+
</linearGradient>
|
|
22
|
+
</defs>
|
|
23
|
+
<rect data-brand x="2" y="2" width="20" height="20" rx="6" fill="none" stroke="url(#ig-grad)" strokeWidth="2" />
|
|
24
|
+
<circle data-brand cx="12" cy="12" r="5" fill="none" stroke="url(#ig-grad)" strokeWidth="2" />
|
|
25
|
+
<circle data-brand cx="17.5" cy="6.5" r="1.4" fill="url(#ig-grad)" />
|
|
26
|
+
</Svg>
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
export const TiktokIcon = (props: IconProps) => (
|
|
30
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
31
|
+
<path
|
|
32
|
+
data-brand
|
|
33
|
+
d="M15 3c.3 2.2 1.6 3.8 3.9 4v2.6c-1.4.1-2.7-.3-3.9-1.05V15a5.5 5.5 0 1 1-5.5-5.5c.3 0 .6.02.9.07v2.7a2.8 2.8 0 1 0 1.9 2.65V3H15z"
|
|
34
|
+
fill="#111111"
|
|
35
|
+
/>
|
|
36
|
+
</Svg>
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
export const WhatsappIcon = (props: IconProps) => (
|
|
40
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
41
|
+
<path
|
|
42
|
+
data-brand
|
|
43
|
+
d="M12 2a10 10 0 0 0-8.6 15.05L2 22l5.1-1.34A10 10 0 1 0 12 2z"
|
|
44
|
+
fill="#25D366"
|
|
45
|
+
/>
|
|
46
|
+
<path
|
|
47
|
+
d="M8.4 7.1c-.2-.45-.4-.46-.6-.47h-.5c-.18 0-.47.07-.72.34-.25.27-.95.93-.95 2.27s.98 2.63 1.12 2.81c.14.18 1.9 3.04 4.7 4.14 2.33.92 2.8.73 3.3.69.5-.05 1.63-.67 1.86-1.31.23-.64.23-1.19.16-1.31-.07-.11-.25-.18-.53-.32-.28-.14-1.63-.8-1.88-.9-.25-.09-.43-.13-.62.14-.18.27-.71.9-.87 1.08-.16.18-.32.2-.6.07-.28-.14-1.17-.43-2.22-1.37-.82-.73-1.37-1.63-1.53-1.9-.16-.28-.02-.43.12-.56.13-.13.28-.32.42-.48.14-.16.18-.28.28-.46.09-.18.05-.34-.02-.48-.07-.14-.6-1.5-.84-2.05z"
|
|
48
|
+
fill="#FFFFFF"
|
|
49
|
+
/>
|
|
50
|
+
</Svg>
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
export const XIcon = (props: IconProps) => (
|
|
54
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
55
|
+
<path
|
|
56
|
+
data-brand
|
|
57
|
+
d="M17.5 3h3l-6.55 7.5L21.7 21h-5.9l-4.6-6-5.3 6H3l7-8-6.6-9h6l4.15 5.5L17.5 3zm-1.05 16h1.65L7.6 4.6H5.85L16.45 19z"
|
|
58
|
+
fill="#000000"
|
|
59
|
+
/>
|
|
60
|
+
</Svg>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export const FacebookIcon = (props: IconProps) => (
|
|
64
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
65
|
+
<circle data-brand cx="12" cy="12" r="11" fill="#1877F2" />
|
|
66
|
+
<path
|
|
67
|
+
d="M15.1 12.5l.4-2.6h-2.5V8.2c0-.72.35-1.42 1.48-1.42h1.13V4.56s-1.03-.18-2-.18c-2.05 0-3.38 1.24-3.38 3.48V9.9H8.4v2.6h2.23V19h2.87v-6.5h2.6z"
|
|
68
|
+
fill="#FFFFFF"
|
|
69
|
+
/>
|
|
70
|
+
</Svg>
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
export const YoutubeIcon = (props: IconProps) => (
|
|
74
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
75
|
+
<rect data-brand x="1" y="5" width="22" height="14" rx="4" fill="#FF0000" />
|
|
76
|
+
<path d="M10 8.5l6 3.5-6 3.5v-7z" fill="#FFFFFF" />
|
|
77
|
+
</Svg>
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
export const ThreadsIcon = (props: IconProps) => (
|
|
81
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
82
|
+
<path
|
|
83
|
+
data-brand
|
|
84
|
+
d="M16.5 11.4c-.1-.05-.2-.1-.3-.14-.18-3.2-1.94-5.03-4.9-5.05h-.04c-1.77 0-3.24.75-4.15 2.13l1.63 1.12c.68-1.02 1.74-1.24 2.52-1.24h.03c.97.01 1.7.29 2.17.84.34.4.57.95.68 1.64-.85-.14-1.77-.19-2.75-.13-2.76.16-4.53 1.77-4.41 4 .06 1.14.63 2.11 1.6 2.74.82.53 1.88.79 2.98.73 1.45-.08 2.59-.63 3.38-1.65.6-.77.98-1.77 1.15-3.03.7.42 1.21.98 1.5 1.65.48 1.14.51 3.01-1.01 4.53-1.34 1.33-2.94 1.91-5.36 1.93-2.68-.02-4.71-.88-6.03-2.56C4.66 17.5 4.02 15.45 4 12.86c.02-2.58.66-4.63 1.9-6.09C7.22 5.09 9.25 4.23 11.93 4.2c2.7.02 4.76.88 6.13 2.57.67.83 1.18 1.87 1.51 3.09l1.9-.51c-.4-1.5-1.04-2.8-1.9-3.87C17.83 3.4 15.25 2.28 11.94 2.26h-.01c-3.3.02-5.85 1.14-7.57 3.33C2.83 7.61 2.03 10.1 2 12.85v.02c.03 2.75.83 5.24 2.36 7.06 1.72 2.19 4.27 3.31 7.57 3.33h.01c2.93-.02 5-.79 6.7-2.49 2.23-2.22 2.16-5.01 1.43-6.72-.53-1.23-1.53-2.23-2.98-2.65z"
|
|
85
|
+
fill="#000000"
|
|
86
|
+
/>
|
|
87
|
+
</Svg>
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
export const PinterestIcon = (props: IconProps) => (
|
|
91
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
92
|
+
<circle data-brand cx="12" cy="12" r="11" fill="#E60023" />
|
|
93
|
+
<path
|
|
94
|
+
d="M12.2 5.5c-3.6 0-5.6 2.35-5.6 4.9 0 1.18.66 2.65 1.72 3.12.16.07.25.04.28-.11.03-.12.17-.7.24-.97.02-.09.01-.16-.06-.25-.4-.47-.71-1.34-.71-2.15 0-2.08 1.6-4.1 4.31-4.1 2.35 0 3.99 1.55 3.99 3.77 0 2.5-1.29 4.24-2.96 4.24-.92 0-1.62-.75-1.4-1.68.26-1.1.78-2.29.78-3.08 0-.71-.39-1.3-1.19-1.3-.94 0-1.7.96-1.7 2.25 0 .82.28 1.37.28 1.37s-.96 3.98-1.13 4.68c-.28 1.18-.04 2.62-.02 2.77.01.09.13.11.18.04.08-.1 1.09-1.34 1.43-2.58.1-.35.55-2.11.55-2.11.27.51 1.07.95 1.91.95 2.52 0 4.23-2.27 4.23-5.31 0-2.3-1.97-4.46-4.87-4.46z"
|
|
95
|
+
fill="#FFFFFF"
|
|
96
|
+
/>
|
|
97
|
+
</Svg>
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
export const LinkedinIcon = (props: IconProps) => (
|
|
101
|
+
<Svg viewBox="0 0 24 24" {...props}>
|
|
102
|
+
<rect data-brand x="1" y="1" width="22" height="22" rx="4" fill="#0A66C2" />
|
|
103
|
+
<path
|
|
104
|
+
d="M7.2 9.5H4.8V18h2.4V9.5zM6 5.6a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8zM18.2 18h2.4v-4.9c0-2.35-1.26-3.44-2.93-3.44-1.35 0-1.95.74-2.29 1.26V9.5h-2.4V18h2.4v-4.5c0-1.02.5-1.6 1.35-1.6.78 0 1.47.55 1.47 1.6V18z"
|
|
105
|
+
fill="#FFFFFF"
|
|
106
|
+
/>
|
|
107
|
+
</Svg>
|
|
108
|
+
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ReactNode } from "react"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* API pública de cada icono. Ninguna dimensión es fija: por defecto el icono
|
|
5
|
+
* mide `1em` de alto (hereda del `font-size` del contenedor) y el ancho se
|
|
6
|
+
* calcula solo a partir del `viewBox`. Pasá `size` (número → px, o cualquier
|
|
7
|
+
* unidad CSS) para forzar un alto concreto.
|
|
8
|
+
*/
|
|
9
|
+
export type IconProps = {
|
|
10
|
+
className?: string
|
|
11
|
+
/** Texto accesible. Si se omite, el icono se marca `aria-hidden` (decorativo). */
|
|
12
|
+
title?: string
|
|
13
|
+
/** Alto del icono. Número = px; string = unidad CSS. Default `"1em"`. */
|
|
14
|
+
size?: number | string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Envoltura común de todos los iconos.
|
|
19
|
+
*
|
|
20
|
+
* ── Tintado por CSS ────────────────────────────────────────────────────────
|
|
21
|
+
* Los colores de marca viven en elementos marcados con `data-brand`. El
|
|
22
|
+
* consumidor (footer/chrome) envuelve la fila de iconos en un contenedor con
|
|
23
|
+
* una clase y elige el modo con CSS. Convención:
|
|
24
|
+
*
|
|
25
|
+
* modo "marca" (default): no hace nada, cada icono muestra sus colores.
|
|
26
|
+
* modo "tinta" (monocromo con el color de texto):
|
|
27
|
+
* .icons--tinta svg [data-brand] { fill: currentColor; stroke: currentColor }
|
|
28
|
+
* modo "acento" (monocromo con el acento de la paleta):
|
|
29
|
+
* .icons--acento svg [data-brand] { fill: var(--cms-acento, #3b2bff);
|
|
30
|
+
* stroke: var(--cms-acento, #3b2bff) }
|
|
31
|
+
*
|
|
32
|
+
* Los elementos "hueco" (blancos, que representan el negativo del logo) NO
|
|
33
|
+
* llevan `data-brand`, así en modo monocromo el fondo se recolorea pero el
|
|
34
|
+
* hueco se mantiene y el símbolo sigue legible.
|
|
35
|
+
*
|
|
36
|
+
* El alto se controla con el atributo intrínseco (del `viewBox`) + `style`:
|
|
37
|
+
* `height` fija el alto y `width:auto` conserva la proporción, igual que un
|
|
38
|
+
* `<img>`. Una clase del consumidor puede sobrescribir el alto sin deformar.
|
|
39
|
+
*/
|
|
40
|
+
export function Svg({
|
|
41
|
+
viewBox,
|
|
42
|
+
title,
|
|
43
|
+
className,
|
|
44
|
+
size,
|
|
45
|
+
children,
|
|
46
|
+
}: IconProps & { viewBox: string; children: ReactNode }) {
|
|
47
|
+
const parts = viewBox.split(/\s+/)
|
|
48
|
+
const w = parts[2]
|
|
49
|
+
const h = parts[3]
|
|
50
|
+
const height = size ?? "1em"
|
|
51
|
+
return (
|
|
52
|
+
<svg
|
|
53
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
54
|
+
viewBox={viewBox}
|
|
55
|
+
width={w}
|
|
56
|
+
height={h}
|
|
57
|
+
className={className}
|
|
58
|
+
style={{ height, width: "auto" }}
|
|
59
|
+
role="img"
|
|
60
|
+
aria-label={title}
|
|
61
|
+
aria-hidden={title ? undefined : true}
|
|
62
|
+
focusable="false"
|
|
63
|
+
>
|
|
64
|
+
{title ? <title>{title}</title> : null}
|
|
65
|
+
{children}
|
|
66
|
+
</svg>
|
|
67
|
+
)
|
|
68
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { defineTemplate, type Template } from "@arroyavecommerce/cms-storefront"
|
|
2
|
+
import type { RenderContext } from "./context"
|
|
3
|
+
import { homeBlocks } from "./blocks"
|
|
4
|
+
import { puckConfig } from "./puck-config"
|
|
5
|
+
import { DEFAULT_HOME_PAGE } from "./content/home"
|
|
6
|
+
import { FUENTES, THEME_DEFAULTS, THEME_PRESETS, themeTokens } from "./theme"
|
|
7
|
+
import { chromeRegistry } from "./chrome"
|
|
8
|
+
import { catalogo } from "./catalog/registry"
|
|
9
|
+
import { SkeletonPlp, SkeletonPdp } from "./catalog/skeletons"
|
|
10
|
+
import {
|
|
11
|
+
PAYMENT_ICONS,
|
|
12
|
+
SOCIAL_ICONS,
|
|
13
|
+
type PaymentKey,
|
|
14
|
+
type SocialKey,
|
|
15
|
+
type IconEntry,
|
|
16
|
+
type IconProps,
|
|
17
|
+
} from "./icons"
|
|
18
|
+
|
|
19
|
+
export type { RenderContext }
|
|
20
|
+
export type { PaymentKey, SocialKey, IconEntry, IconProps }
|
|
21
|
+
export { themeTokens, FUENTES, THEME_PRESETS, homeBlocks, puckConfig, DEFAULT_HOME_PAGE, chromeRegistry, catalogo }
|
|
22
|
+
export { PAYMENT_ICONS, SOCIAL_ICONS }
|
|
23
|
+
export { SkeletonPlp, SkeletonPdp }
|
|
24
|
+
|
|
25
|
+
export const themeKinetic: Template<RenderContext> = defineTemplate<RenderContext>()({
|
|
26
|
+
meta: { id: "kinetic", nombre: "Kinetic", industria: "fashion" },
|
|
27
|
+
blocks: homeBlocks,
|
|
28
|
+
chrome: chromeRegistry,
|
|
29
|
+
catalogo,
|
|
30
|
+
puckConfig,
|
|
31
|
+
theme: {
|
|
32
|
+
definition: { tokens: themeTokens, fuentes: FUENTES },
|
|
33
|
+
defaults: THEME_DEFAULTS,
|
|
34
|
+
marca: "Kinetic",
|
|
35
|
+
},
|
|
36
|
+
defaultHomePage: DEFAULT_HOME_PAGE,
|
|
37
|
+
reservados: [
|
|
38
|
+
"store",
|
|
39
|
+
"products",
|
|
40
|
+
"cart",
|
|
41
|
+
"checkout",
|
|
42
|
+
"account",
|
|
43
|
+
"categories",
|
|
44
|
+
"collections",
|
|
45
|
+
"studio",
|
|
46
|
+
"api",
|
|
47
|
+
],
|
|
48
|
+
basePath: "/p",
|
|
49
|
+
})
|