@asteby/storefront-react 0.19.0 → 0.21.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.
Files changed (51) hide show
  1. package/README.md +41 -0
  2. package/dist/account-server.cjs +405 -7
  3. package/dist/account-server.cjs.map +1 -1
  4. package/dist/account-server.d.cts +41 -1
  5. package/dist/account-server.d.ts +41 -1
  6. package/dist/account-server.js +73 -3
  7. package/dist/account-server.js.map +1 -1
  8. package/dist/account.cjs +1663 -4
  9. package/dist/account.cjs.map +1 -1
  10. package/dist/account.css +362 -0
  11. package/dist/account.d.cts +499 -3
  12. package/dist/account.d.ts +499 -3
  13. package/dist/account.js +1102 -2
  14. package/dist/account.js.map +1 -1
  15. package/dist/cart.cjs +125 -2
  16. package/dist/cart.cjs.map +1 -1
  17. package/dist/cart.css +145 -2
  18. package/dist/cart.js +4 -2
  19. package/dist/cart.js.map +1 -1
  20. package/dist/checkout.cjs +129 -1
  21. package/dist/checkout.cjs.map +1 -1
  22. package/dist/checkout.css +142 -0
  23. package/dist/checkout.d.cts +3 -1
  24. package/dist/checkout.d.ts +3 -1
  25. package/dist/checkout.js +10 -3
  26. package/dist/checkout.js.map +1 -1
  27. package/dist/chunk-PPQEUTXJ.js +260 -0
  28. package/dist/chunk-PPQEUTXJ.js.map +1 -0
  29. package/dist/chunk-TXEYBDFG.js +182 -0
  30. package/dist/chunk-TXEYBDFG.js.map +1 -0
  31. package/dist/chunk-VHEY5AU3.js +152 -0
  32. package/dist/chunk-VHEY5AU3.js.map +1 -0
  33. package/dist/fiscal.d.cts +34 -34
  34. package/dist/fiscal.d.ts +34 -34
  35. package/dist/fiscal.js +4 -258
  36. package/dist/fiscal.js.map +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/payments.css +15 -14
  39. package/dist/payments.js +2 -2
  40. package/dist/product-preview-DRtLWGLS.d.cts +85 -0
  41. package/dist/product-preview-DaICr4f2.d.ts +85 -0
  42. package/dist/ui.cjs +202 -0
  43. package/dist/ui.cjs.map +1 -1
  44. package/dist/ui.css +142 -0
  45. package/dist/ui.d.cts +3 -0
  46. package/dist/ui.d.ts +3 -0
  47. package/dist/ui.js +3 -1
  48. package/dist/ui.js.map +1 -1
  49. package/dist/voucher-document-SFWJCLTN.js +124 -0
  50. package/dist/voucher-document-SFWJCLTN.js.map +1 -0
  51. package/package.json +2 -2
package/dist/ui.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ui/select.tsx","../src/ui/swatch-colors.ts","../src/ui/swatch.tsx","../src/ui/theme-toggle.tsx","../src/ui/pwa.tsx"],"names":["jsx","useRef","useState","useId","current","useEffect","jsxs","Fragment","style"],"mappings":"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","file":"ui.cjs","sourcesContent":["import { useEffect, useId, useRef, useState } from 'react'\n\nexport type SelectOption = { value: string; label: string }\n\nconst Chevron = ({ open = false, floating = false }: { open?: boolean; floating?: boolean }) => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" data-select-chevron={floating ? 'floating' : ''} data-open={open || undefined}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n)\nconst Check = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n)\n\nexport type SelectProps = {\n id: string\n name: string\n options: SelectOption[]\n defaultValue?: string\n /** Etiqueta accesible (la visible la pone el llamador con <label htmlFor={id}>). */\n label: string\n className?: string\n}\n\n/**\n * Selector con mejora progresiva. Sin JavaScript (o antes de hidratar) es un <select> nativo dentro de un formulario;\n * con JavaScript se reemplaza por un listbox propio (teclado completo, objetivo táctil de 44 px, tema claro/oscuro).\n * El <select> nativo sigue en el DOM como fuente de verdad: al elegir se cambia su valor y se emite \"change\", así un\n * formulario con onChange → submit (filtros por URL) no nota la diferencia.\n * Estilos: clases `select` (ver ui.css) y los tokens --background, --foreground, --border, --tint, --primary.\n */\nexport function Select({ id, name, options, defaultValue, label, className = '' }: SelectProps) {\n const native = useRef<HTMLSelectElement>(null)\n const root = useRef<HTMLDivElement>(null)\n const [enhanced, setEnhanced] = useState(false)\n const [open, setOpen] = useState(false)\n const [value, setValue] = useState(defaultValue ?? options[0]?.value ?? '')\n const [active, setActive] = useState(0)\n const listId = useId()\n const current = options.find((o) => o.value === value) ?? options[0]\n\n useEffect(() => setEnhanced(true), [])\n // El valor lo puede cambiar la URL (atrás/adelante): se sincroniza.\n useEffect(() => {\n if (defaultValue != null) setValue(defaultValue)\n }, [defaultValue])\n\n useEffect(() => {\n if (!open) return\n const onDown = (e: PointerEvent) => {\n if (!root.current?.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('pointerdown', onDown)\n return () => document.removeEventListener('pointerdown', onDown)\n }, [open])\n\n const openList = () => {\n setActive(Math.max(0, options.findIndex((o) => o.value === value)))\n setOpen(true)\n }\n\n const choose = (next: string) => {\n setOpen(false)\n setValue(next)\n const el = native.current\n if (el && el.value !== next) {\n el.value = next\n el.dispatchEvent(new Event('change', { bubbles: true }))\n }\n root.current?.querySelector<HTMLButtonElement>('button')?.focus()\n }\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n const last = options.length - 1\n if (!open) {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {\n e.preventDefault()\n openList()\n }\n return\n }\n const go = (i: number) => {\n e.preventDefault()\n setActive(i)\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n setOpen(false)\n } else if (e.key === 'ArrowDown') go(Math.min(last, active + 1))\n else if (e.key === 'ArrowUp') go(Math.max(0, active - 1))\n else if (e.key === 'Home') go(0)\n else if (e.key === 'End') go(last)\n else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n const picked = options[active]\n if (picked) choose(picked.value)\n } else if (e.key === 'Tab') setOpen(false)\n }\n\n return (\n <div ref={root} data-select=\"\" className={className || undefined}>\n <div data-select-native={enhanced ? 'hidden' : ''}>\n <select\n ref={native}\n id={enhanced ? undefined : id}\n name={name}\n defaultValue={defaultValue}\n tabIndex={enhanced ? -1 : undefined}\n aria-hidden={enhanced || undefined}\n aria-label={enhanced ? label : undefined}\n className=\"select\"\n >\n {options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n {!enhanced ? <Chevron floating /> : null}\n </div>\n\n {enhanced ? (\n <>\n <button\n type=\"button\"\n id={id}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listId}\n aria-label={`${label}: ${current?.label}`}\n onClick={() => (open ? setOpen(false) : openList())}\n onKeyDown={onKeyDown}\n className=\"select\" data-select-trigger=\"\"\n >\n <span data-select-value=\"\">{current?.label}</span>\n <Chevron open={open} />\n </button>\n {open ? (\n <ul id={listId} role=\"listbox\" aria-label={label} tabIndex={-1} data-select-list=\"\">\n {options.map((o, i) => (\n <li\n key={o.value}\n role=\"option\"\n aria-selected={o.value === value}\n data-active={i === active || undefined}\n onPointerEnter={() => setActive(i)}\n onClick={() => choose(o.value)}\n >\n {o.label}\n {o.value === value ? <Check /> : null}\n </li>\n ))}\n </ul>\n ) : null}\n </>\n ) : null}\n </div>\n )\n}\n","/**\n * Muestras de variante (color, combinación o emoji), pura y sin DOM: sirve en servidor y cliente.\n *\n * El MOTOR es genérico; los DICCIONARIOS no. El SDK solo trae colores básicos (ropa, acabados). Los sabores, emojis y cualquier\n * vocabulario de un giro (suplementos, café, moda…) los inyecta la tienda con `createSwatchResolver`, o llegan del catálogo\n * como atributo (`parseSwatchAttribute`), que siempre manda sobre cualquier diccionario.\n */\n\n/**\n * Lo que dibuja una muestra: colores planos, emoji, o AMBOS (una píldora pastel con la mezcla de colores y los emoji encima).\n * Al menos uno de los dos viene lleno.\n */\nexport type SwatchSpec = { colors?: string[]; emoji?: string }\n\n/** [frase normalizada (minúsculas, sin acentos), un color hex o varios] */\nexport type ColorEntry = [phrase: string, color: string | string[]]\n/** [frase normalizada, emoji o varios emoji] */\nexport type EmojiEntry = [phrase: string, emoji: string]\n\n/** Qué dibujar primero cuando hay color y emoji para el mismo nombre. */\nexport type SwatchPrefer = 'auto' | 'color' | 'emoji' | 'both'\n\nconst HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i\nconst HEX_IN_TEXT = /#(?:[0-9a-f]{6}|[0-9a-f]{3})\\b/gi\nconst MAX = 4\n\n/** Minúsculas, sin acentos, sin puntuación suelta. \"Piña\" → \"pina\". */\nexport function normalize(value: string): string {\n return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase().trim()\n}\n\n/** Colores básicos (es/en) para ropa y acabados. Sin vocabulario de ningún giro en particular. */\nexport const defaultColors: ColorEntry[] = [\n ['azul marino', '#14213d'], ['navy', '#14213d'], ['azul rey', '#2447d6'], ['azul cielo', '#6ec1f0'], ['celeste', '#8fd0f5'],\n ['verde militar', '#4b5320'], ['verde oliva', '#6b7a2a'], ['verde limon', '#b8e03a'], ['verde menta', '#8fe0b5'],\n ['rosa mexicano', '#e4007c'], ['gris oscuro', '#4a4f57'], ['gris claro', '#cfd3d8'],\n ['rojo', '#e0262d'], ['red', '#e0262d'], ['vino', '#6d1a36'], ['guinda', '#7a1f3d'], ['burgundy', '#6d1a36'],\n ['azul', '#2f5bea'], ['blue', '#2f5bea'], ['verde', '#2fa84f'], ['green', '#2fa84f'],\n ['amarillo', '#ffd21f'], ['yellow', '#ffd21f'], ['naranja', '#ff8a1f'], ['orange', '#ff8a1f'],\n ['morado', '#7b3fc4'], ['purpura', '#7b3fc4'], ['purple', '#7b3fc4'], ['violeta', '#8a4fd6'], ['lila', '#c4a5f0'],\n ['rosa', '#ff7eb6'], ['pink', '#ff7eb6'], ['fucsia', '#e4007c'], ['magenta', '#d4119e'],\n ['negro', '#111111'], ['black', '#111111'], ['blanco', '#ffffff'], ['white', '#ffffff'],\n ['gris', '#9aa0a8'], ['gray', '#9aa0a8'], ['grey', '#9aa0a8'], ['plata', '#c0c4cc'], ['plateado', '#c0c4cc'], ['silver', '#c0c4cc'],\n ['dorado', '#d4a72c'], ['oro', '#d4a72c'], ['gold', '#d4a72c'], ['cafe', '#7a4a2b'], ['marron', '#7a4a2b'], ['brown', '#7a4a2b'],\n ['beige', '#e6d3b3'], ['crema', '#f4ead2'], ['hueso', '#f1ecde'], ['arena', '#d9c39a'], ['khaki', '#b8a77a'], ['camel', '#b9824a'],\n ['turquesa', '#1fc8c8'], ['aqua', '#34d3d3'], ['coral', '#ff6f61'], ['salmon', '#ff8f7a'], ['mostaza', '#d9a521'], ['terracota', '#c4623f'],\n ['transparente', '#e8edf2'],\n]\n\n/**\n * Busca en el texto COMPLETO las frases del diccionario como palabras (plural con \"s\" opcional), la más larga primero, y las\n * devuelve en el orden en que se leen. Se tacha lo encontrado: \"azul\" no vuelve a salir dentro de \"azul marino\". Al no partir\n * el texto por \"y\"/\"and\", las frases con conectores (\"cookies and cream\") se resuelven como frase.\n */\nfunction scan<T>(text: string, entries: [string, T][]): T[] {\n const found: { index: number; value: T }[] = []\n let rest = text\n for (const [phrase, value] of [...entries].sort((a, b) => b[0].length - a[0].length)) {\n const m = new RegExp(`(^|[^a-z])${phrase}s?(?![a-z])`).exec(rest)\n if (!m) continue\n const start = m.index + (m[1]?.length ?? 0)\n found.push({ index: start, value })\n rest = rest.slice(0, start) + ' '.repeat(phrase.length + 1) + rest.slice(start + phrase.length + 1)\n }\n return found.sort((a, b) => a.index - b.index).map((f) => f.value)\n}\n\nfunction graphemes(text: string): string[] {\n return [...new Intl.Segmenter(undefined, { granularity: 'grapheme' }).segment(text)].map((g) => g.segment)\n}\n\nexport type SwatchResolverOptions = {\n /** Diccionario de colores. Default: `defaultColors`. Para sumar vocabulario: `[...defaultColors, ...tusColores]`. */\n colors?: ColorEntry[]\n /** Diccionario de emoji (sin default: es vocabulario del giro). */\n emojis?: EmojiEntry[]\n /** Qué dibujar si hay color y emoji: `auto`/`color` = color primero, `emoji` = emoji primero, `both` = píldora pastel con colores y emoji. */\n prefer?: SwatchPrefer\n}\n\nexport type SwatchResolver = {\n /** Colores del nombre (\"Rojo / Negro\", \"#ff8800\"), en orden de lectura, o `null`. */\n colors(value: string): string[] | null\n /** Emoji(s) del nombre (hasta 3, sin repetir), o `null`. */\n emoji(value: string): string | null\n /** Muestra de una variante: primero el atributo del catálogo, luego el nombre según `prefer`. */\n resolve(value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null\n /** ¿Todos los valores de una opción tienen muestra? */\n hasSwatches(values: string[], attribute?: Map<string, SwatchSpec>): boolean\n}\n\nexport function createSwatchResolver({ colors: colorTable = defaultColors, emojis = [], prefer = 'auto' }: SwatchResolverOptions = {}): SwatchResolver {\n const colors = (value: string): string[] | null => {\n const text = normalize(value)\n if (!text) return null\n const hex = (text.match(HEX_IN_TEXT) ?? []).filter((h) => HEX.test(h))\n const found = [...hex, ...scan(text, colorTable).flat()]\n const unique = found.filter((c, i) => found.indexOf(c) === i).slice(0, MAX)\n return unique.length > 0 ? unique : null\n }\n const emoji = (value: string): string | null => {\n const parts = scan(normalize(value), emojis).flatMap(graphemes)\n const unique = parts.filter((e, i) => parts.indexOf(e) === i).slice(0, 3)\n return unique.length > 0 ? unique.join('') : null\n }\n const resolve = (value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null => {\n const fromCatalog = attribute?.get(normalize(value))\n if (fromCatalog) return fromCatalog\n const c = colors(value)\n const e = emoji(value)\n if (prefer === 'both' && c && e) return { colors: c, emoji: e }\n if (prefer === 'emoji') return e ? { emoji: e } : c ? { colors: c } : null\n if (prefer === 'color') return c ? { colors: c } : e ? { emoji: e } : null\n return c ? { colors: c } : e ? { emoji: e } : null\n }\n return { colors, emoji, resolve, hasSwatches: (values, attribute) => values.length > 0 && values.every((v) => resolve(v, attribute) !== null) }\n}\n\nconst basic = createSwatchResolver()\n\n/** Colores básicos del nombre (sin vocabulario de giro). Para uno propio: `createSwatchResolver`. */\nexport const resolveSwatch = basic.colors\n/** Muestra de una variante con solo colores básicos. Para uno propio: `createSwatchResolver`. */\nexport const resolveSwatchSpec = (value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null => basic.resolve(value, attribute)\nexport const optionHasSwatches = basic.hasSwatches\n\n/**\n * Atributo del producto con el color o emoji de cada variante, como lo siembra el catálogo (OPS):\n * `\"Mora Azul:#3d4fd6|Fresa Kiwi:#ff4d6d+#8bc34a 🍓🥝|Natural:🥛\"`. Cada valor es un hex, varios hex con \"+\" (combinación), emoji, o colores y emoji juntos.\n * Es la fuente de verdad: manda sobre cualquier diccionario.\n */\nexport function parseSwatchAttribute(raw: unknown): Map<string, SwatchSpec> {\n const map = new Map<string, SwatchSpec>()\n if (typeof raw !== 'string') return map\n for (const part of raw.split('|')) {\n const i = part.lastIndexOf(':')\n if (i <= 0) continue\n const name = normalize(part.slice(0, i))\n const value = part.slice(i + 1).trim()\n const colors = (value.match(HEX_IN_TEXT) ?? []).filter((c) => HEX.test(c)).slice(0, MAX)\n const emoji = value.replace(HEX_IN_TEXT, '').replace(/[+\\s]/g, '')\n const hasEmoji = emoji.length > 0 && /\\p{Extended_Pictographic}/u.test(emoji)\n if (colors.length > 0 || hasEmoji) map.set(name, { ...(colors.length > 0 ? { colors } : {}), ...(hasEmoji ? { emoji } : {}) })\n }\n return map\n}\n\n/** Fondo CSS plano: un color liso, dos mitades, o sectores iguales (hasta 4). */\nexport function swatchBackground(colors: string[]): string {\n const [first = 'transparent', second] = colors\n if (second === undefined) return first\n if (colors.length === 2) return `linear-gradient(90deg, ${first} 50%, ${second} 50%)`\n const step = 360 / colors.length\n return `conic-gradient(${colors.map((c, i) => `${c} ${i * step}deg ${(i + 1) * step}deg`).join(', ')})`\n}\n\n/** Luminancia relativa (0 negro – 1 blanco) de un color hex, para decidir si hace falta un aro. */\nexport function luminance(hex: string): number {\n const h = hex.replace('#', '')\n const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h\n const channel = (i: number): number => {\n const v = parseInt(full.slice(i, i + 2), 16) / 255\n return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * channel(0) + 0.7152 * channel(2) + 0.0722 * channel(4)\n}\n\n/**\n * Fondo pastel de una píldora: cada color mezclado con blanco (queda claro y suave en claro y oscuro), un degradado suave entre\n * ellos si son varios. Con ese fondo el emoji siempre contrasta.\n */\nexport function pastelBackground(colors: string[]): string {\n const soft = colors.map((c) => `color-mix(in srgb, ${c} 26%, white)`)\n const [first = 'transparent', second] = soft\n if (second === undefined) return first\n return `linear-gradient(100deg, ${soft.join(', ')})`\n}\n","import type { CSSProperties } from 'react'\nimport { luminance, pastelBackground, resolveSwatchSpec, swatchBackground, type SwatchSpec } from './swatch-colors'\n\nexport type SwatchProps = {\n /** Nombre de la variante; se resuelve con los colores básicos del SDK. Para vocabulario propio resuelve tú con `createSwatchResolver` y pasa `spec`. */\n value?: string\n /** Lo que se dibuja (color(es) o emoji), ya resuelto: del catálogo (`parseSwatchAttribute`) o de tu `createSwatchResolver`. Manda sobre `value`. */\n spec?: SwatchSpec | null\n size?: number\n shape?: 'circle' | 'square'\n className?: string\n}\n\n/**\n * Muestra de color 2D para variantes: plana, sin sombras ni brillos y sin borde, salvo un aro mínimo cuando el color\n * se perdería contra el fondo (blanco en tema claro, negro en tema oscuro). Las combinaciones se dibujan en partes iguales.\n * Es decorativa (aria-hidden): el nombre de la variante debe ir siempre como texto junto a ella.\n * Con `spec.emoji` dibuja el emoji. Devuelve null si no reconoce nada, para que el llamador muestre solo el texto.\n */\nexport function Swatch({ value = '', spec, size = 20, shape = 'circle', className = '' }: SwatchProps) {\n const resolved = spec ?? resolveSwatchSpec(value)\n if (!resolved) return null\n const colors = resolved.colors ?? []\n if (resolved.emoji) {\n // Badge: círculo (un emoji) o píldora (mezcla) con fondo pastel de los colores del sabor y el emoji encima; sin colores, fondo\n // neutro de superficie. En la mezcla los emoji se montan un poco, el primero arriba. Así se ve qué emoji forman cada grupo.\n const parts = [...new Intl.Segmenter(undefined, { granularity: 'grapheme' }).segment(resolved.emoji)].map((g) => g.segment)\n const mixed = parts.length > 1\n const style: CSSProperties = {\n minWidth: size,\n height: size,\n fontSize: Math.round(size * (mixed ? 0.56 : 0.6)),\n ...(colors.length > 0 ? { background: pastelBackground(colors), ['--sw-ring' as string]: colors[0] } : {}),\n }\n return (\n <span aria-hidden=\"true\" data-swatch=\"\" data-kind=\"emoji\" data-mixed={mixed || undefined} data-colored={colors.length > 0 || undefined} data-shape={shape} className={className || undefined} style={style}>\n {parts.map((emoji, i) => (\n <span key={`${emoji}-${i}`} style={i > 0 ? { marginInlineStart: '-0.3em', zIndex: parts.length - i } : { zIndex: parts.length }}>\n {emoji}\n </span>\n ))}\n </span>\n )\n }\n if (colors.length === 0) return null\n const lums = colors.map(luminance)\n const edge = lums.some((l) => l > 0.82) ? 'light' : lums.some((l) => l < 0.04) ? 'dark' : undefined\n const style: CSSProperties = { width: size, height: size, background: swatchBackground(colors) }\n return <span aria-hidden=\"true\" data-swatch=\"\" data-edge={edge} data-shape={shape} className={className || undefined} style={style} />\n}\n","import { useEffect, useState } from 'react'\n\ntype Theme = 'light' | 'dark'\n\n/** Script de cabecera: aplica el tema guardado antes de pintar (sin parpadeo). Sin preferencia guardada manda el sistema. */\nexport const THEME_INIT_SCRIPT = `try{var t=localStorage.getItem(\"theme\");if(t===\"light\"||t===\"dark\")document.documentElement.setAttribute(\"data-theme\",t)}catch(e){}`\n\nfunction current(): Theme {\n const attr = document.documentElement.getAttribute('data-theme')\n if (attr === 'light' || attr === 'dark') return attr\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\n/**\n * Botón claro/oscuro. El estado real se lee del DOM tras hidratar (el servidor no sabe la preferencia).\n * Guarda la elección en localStorage (\"theme\") y fija `html[data-theme]`; los tokens de la tienda reaccionan a eso.\n */\nexport function ThemeToggle({ className = '', themeColors = { light: '#ffffff', dark: '#000000' } }: { className?: string; themeColors?: { light: string; dark: string } }) {\n const [theme, setTheme] = useState<Theme | null>(null)\n useEffect(() => setTheme(current()), [])\n\n const toggle = () => {\n const next: Theme = current() === 'dark' ? 'light' : 'dark'\n document.documentElement.setAttribute('data-theme', next)\n try {\n localStorage.setItem('theme', next)\n } catch {\n /* modo privado: el cambio dura la sesión */\n }\n document.querySelector('meta[name=\"theme-color\"][data-dynamic]')?.setAttribute('content', themeColors[next])\n setTheme(next)\n }\n\n const dark = theme === 'dark'\n return (\n <button type=\"button\" onClick={toggle} className={className} aria-label={dark ? 'Cambiar a tema claro' : 'Cambiar a tema oscuro'} aria-pressed={theme === null ? undefined : dark}>\n {dark ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z\" />\n </svg>\n )}\n </button>\n )\n}\n","import { useEffect, useState } from 'react'\n\ntype InstallEvent = Event & { prompt: () => Promise<void>; userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }> }\n\n/** Registra el service worker (solo si `enabled`, normalmente producción; requiere HTTPS o localhost). */\nexport function useServiceWorker({ enabled, url = '/sw.js', scope = '/' }: { enabled: boolean; url?: string; scope?: string }) {\n useEffect(() => {\n if (!enabled || !('serviceWorker' in navigator)) return\n const register = () => navigator.serviceWorker.register(url, { scope }).catch(() => undefined)\n if (document.readyState === 'complete') register()\n else window.addEventListener('load', register, { once: true })\n }, [enabled, url, scope])\n}\n\n/**\n * Botón \"Instalar app\": aparece solo cuando el navegador ofrece la instalación (Chrome, Edge, Android).\n * En iPhone/iPad no existe ese evento: muestra la instrucción de Compartir → Agregar a pantalla de inicio.\n */\nexport function InstallApp({ className = '', label = 'Instalar app', iosHint = 'Para instalar: toca Compartir y luego «Agregar a pantalla de inicio».' }: { className?: string; label?: string; iosHint?: string }) {\n const [event, setEvent] = useState<InstallEvent | null>(null)\n const [ios, setIos] = useState(false)\n const [installed, setInstalled] = useState(true)\n\n useEffect(() => {\n const standalone = window.matchMedia('(display-mode: standalone)').matches || (navigator as Navigator & { standalone?: boolean }).standalone === true\n setInstalled(standalone)\n setIos(/iphone|ipad|ipod/i.test(navigator.userAgent) && !standalone)\n const onPrompt = (e: Event) => {\n e.preventDefault()\n setEvent(e as InstallEvent)\n }\n const onInstalled = () => setInstalled(true)\n window.addEventListener('beforeinstallprompt', onPrompt)\n window.addEventListener('appinstalled', onInstalled)\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt)\n window.removeEventListener('appinstalled', onInstalled)\n }\n }, [])\n\n if (installed) return null\n if (event) {\n return (\n <button\n type=\"button\"\n className={className}\n onClick={async () => {\n await event.prompt()\n await event.userChoice\n setEvent(null)\n }}\n >\n {label}\n </button>\n )\n }\n return ios ? <p className={className}>{iosHint}</p> : null\n}\n"]}
1
+ {"version":3,"sources":["../src/ui/select.tsx","../src/ui/swatch-colors.ts","../src/ui/swatch.tsx","../src/ui/theme-toggle.tsx","../src/ui/pwa.tsx","../src/components.tsx","../src/ui/product-preview.tsx"],"names":["jsx","useRef","useState","useId","current","useEffect","jsxs","Fragment","style"],"mappings":"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","file":"ui.cjs","sourcesContent":["import { useEffect, useId, useRef, useState } from 'react'\n\nexport type SelectOption = { value: string; label: string }\n\nconst Chevron = ({ open = false, floating = false }: { open?: boolean; floating?: boolean }) => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" data-select-chevron={floating ? 'floating' : ''} data-open={open || undefined}>\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n)\nconst Check = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n)\n\nexport type SelectProps = {\n id: string\n name: string\n options: SelectOption[]\n defaultValue?: string\n /** Etiqueta accesible (la visible la pone el llamador con <label htmlFor={id}>). */\n label: string\n className?: string\n}\n\n/**\n * Selector con mejora progresiva. Sin JavaScript (o antes de hidratar) es un <select> nativo dentro de un formulario;\n * con JavaScript se reemplaza por un listbox propio (teclado completo, objetivo táctil de 44 px, tema claro/oscuro).\n * El <select> nativo sigue en el DOM como fuente de verdad: al elegir se cambia su valor y se emite \"change\", así un\n * formulario con onChange → submit (filtros por URL) no nota la diferencia.\n * Estilos: clases `select` (ver ui.css) y los tokens --background, --foreground, --border, --tint, --primary.\n */\nexport function Select({ id, name, options, defaultValue, label, className = '' }: SelectProps) {\n const native = useRef<HTMLSelectElement>(null)\n const root = useRef<HTMLDivElement>(null)\n const [enhanced, setEnhanced] = useState(false)\n const [open, setOpen] = useState(false)\n const [value, setValue] = useState(defaultValue ?? options[0]?.value ?? '')\n const [active, setActive] = useState(0)\n const listId = useId()\n const current = options.find((o) => o.value === value) ?? options[0]\n\n useEffect(() => setEnhanced(true), [])\n // El valor lo puede cambiar la URL (atrás/adelante): se sincroniza.\n useEffect(() => {\n if (defaultValue != null) setValue(defaultValue)\n }, [defaultValue])\n\n useEffect(() => {\n if (!open) return\n const onDown = (e: PointerEvent) => {\n if (!root.current?.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('pointerdown', onDown)\n return () => document.removeEventListener('pointerdown', onDown)\n }, [open])\n\n const openList = () => {\n setActive(Math.max(0, options.findIndex((o) => o.value === value)))\n setOpen(true)\n }\n\n const choose = (next: string) => {\n setOpen(false)\n setValue(next)\n const el = native.current\n if (el && el.value !== next) {\n el.value = next\n el.dispatchEvent(new Event('change', { bubbles: true }))\n }\n root.current?.querySelector<HTMLButtonElement>('button')?.focus()\n }\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n const last = options.length - 1\n if (!open) {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(e.key)) {\n e.preventDefault()\n openList()\n }\n return\n }\n const go = (i: number) => {\n e.preventDefault()\n setActive(i)\n }\n if (e.key === 'Escape') {\n e.preventDefault()\n setOpen(false)\n } else if (e.key === 'ArrowDown') go(Math.min(last, active + 1))\n else if (e.key === 'ArrowUp') go(Math.max(0, active - 1))\n else if (e.key === 'Home') go(0)\n else if (e.key === 'End') go(last)\n else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n const picked = options[active]\n if (picked) choose(picked.value)\n } else if (e.key === 'Tab') setOpen(false)\n }\n\n return (\n <div ref={root} data-select=\"\" className={className || undefined}>\n <div data-select-native={enhanced ? 'hidden' : ''}>\n <select\n ref={native}\n id={enhanced ? undefined : id}\n name={name}\n defaultValue={defaultValue}\n tabIndex={enhanced ? -1 : undefined}\n aria-hidden={enhanced || undefined}\n aria-label={enhanced ? label : undefined}\n className=\"select\"\n >\n {options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n {!enhanced ? <Chevron floating /> : null}\n </div>\n\n {enhanced ? (\n <>\n <button\n type=\"button\"\n id={id}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-controls={listId}\n aria-label={`${label}: ${current?.label}`}\n onClick={() => (open ? setOpen(false) : openList())}\n onKeyDown={onKeyDown}\n className=\"select\" data-select-trigger=\"\"\n >\n <span data-select-value=\"\">{current?.label}</span>\n <Chevron open={open} />\n </button>\n {open ? (\n <ul id={listId} role=\"listbox\" aria-label={label} tabIndex={-1} data-select-list=\"\">\n {options.map((o, i) => (\n <li\n key={o.value}\n role=\"option\"\n aria-selected={o.value === value}\n data-active={i === active || undefined}\n onPointerEnter={() => setActive(i)}\n onClick={() => choose(o.value)}\n >\n {o.label}\n {o.value === value ? <Check /> : null}\n </li>\n ))}\n </ul>\n ) : null}\n </>\n ) : null}\n </div>\n )\n}\n","/**\n * Muestras de variante (color, combinación o emoji), pura y sin DOM: sirve en servidor y cliente.\n *\n * El MOTOR es genérico; los DICCIONARIOS no. El SDK solo trae colores básicos (ropa, acabados). Los sabores, emojis y cualquier\n * vocabulario de un giro (suplementos, café, moda…) los inyecta la tienda con `createSwatchResolver`, o llegan del catálogo\n * como atributo (`parseSwatchAttribute`), que siempre manda sobre cualquier diccionario.\n */\n\n/**\n * Lo que dibuja una muestra: colores planos, emoji, o AMBOS (una píldora pastel con la mezcla de colores y los emoji encima).\n * Al menos uno de los dos viene lleno.\n */\nexport type SwatchSpec = { colors?: string[]; emoji?: string }\n\n/** [frase normalizada (minúsculas, sin acentos), un color hex o varios] */\nexport type ColorEntry = [phrase: string, color: string | string[]]\n/** [frase normalizada, emoji o varios emoji] */\nexport type EmojiEntry = [phrase: string, emoji: string]\n\n/** Qué dibujar primero cuando hay color y emoji para el mismo nombre. */\nexport type SwatchPrefer = 'auto' | 'color' | 'emoji' | 'both'\n\nconst HEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i\nconst HEX_IN_TEXT = /#(?:[0-9a-f]{6}|[0-9a-f]{3})\\b/gi\nconst MAX = 4\n\n/** Minúsculas, sin acentos, sin puntuación suelta. \"Piña\" → \"pina\". */\nexport function normalize(value: string): string {\n return value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase().trim()\n}\n\n/** Colores básicos (es/en) para ropa y acabados. Sin vocabulario de ningún giro en particular. */\nexport const defaultColors: ColorEntry[] = [\n ['azul marino', '#14213d'], ['navy', '#14213d'], ['azul rey', '#2447d6'], ['azul cielo', '#6ec1f0'], ['celeste', '#8fd0f5'],\n ['verde militar', '#4b5320'], ['verde oliva', '#6b7a2a'], ['verde limon', '#b8e03a'], ['verde menta', '#8fe0b5'],\n ['rosa mexicano', '#e4007c'], ['gris oscuro', '#4a4f57'], ['gris claro', '#cfd3d8'],\n ['rojo', '#e0262d'], ['red', '#e0262d'], ['vino', '#6d1a36'], ['guinda', '#7a1f3d'], ['burgundy', '#6d1a36'],\n ['azul', '#2f5bea'], ['blue', '#2f5bea'], ['verde', '#2fa84f'], ['green', '#2fa84f'],\n ['amarillo', '#ffd21f'], ['yellow', '#ffd21f'], ['naranja', '#ff8a1f'], ['orange', '#ff8a1f'],\n ['morado', '#7b3fc4'], ['purpura', '#7b3fc4'], ['purple', '#7b3fc4'], ['violeta', '#8a4fd6'], ['lila', '#c4a5f0'],\n ['rosa', '#ff7eb6'], ['pink', '#ff7eb6'], ['fucsia', '#e4007c'], ['magenta', '#d4119e'],\n ['negro', '#111111'], ['black', '#111111'], ['blanco', '#ffffff'], ['white', '#ffffff'],\n ['gris', '#9aa0a8'], ['gray', '#9aa0a8'], ['grey', '#9aa0a8'], ['plata', '#c0c4cc'], ['plateado', '#c0c4cc'], ['silver', '#c0c4cc'],\n ['dorado', '#d4a72c'], ['oro', '#d4a72c'], ['gold', '#d4a72c'], ['cafe', '#7a4a2b'], ['marron', '#7a4a2b'], ['brown', '#7a4a2b'],\n ['beige', '#e6d3b3'], ['crema', '#f4ead2'], ['hueso', '#f1ecde'], ['arena', '#d9c39a'], ['khaki', '#b8a77a'], ['camel', '#b9824a'],\n ['turquesa', '#1fc8c8'], ['aqua', '#34d3d3'], ['coral', '#ff6f61'], ['salmon', '#ff8f7a'], ['mostaza', '#d9a521'], ['terracota', '#c4623f'],\n ['transparente', '#e8edf2'],\n]\n\n/**\n * Busca en el texto COMPLETO las frases del diccionario como palabras (plural con \"s\" opcional), la más larga primero, y las\n * devuelve en el orden en que se leen. Se tacha lo encontrado: \"azul\" no vuelve a salir dentro de \"azul marino\". Al no partir\n * el texto por \"y\"/\"and\", las frases con conectores (\"cookies and cream\") se resuelven como frase.\n */\nfunction scan<T>(text: string, entries: [string, T][]): T[] {\n const found: { index: number; value: T }[] = []\n let rest = text\n for (const [phrase, value] of [...entries].sort((a, b) => b[0].length - a[0].length)) {\n const m = new RegExp(`(^|[^a-z])${phrase}s?(?![a-z])`).exec(rest)\n if (!m) continue\n const start = m.index + (m[1]?.length ?? 0)\n found.push({ index: start, value })\n rest = rest.slice(0, start) + ' '.repeat(phrase.length + 1) + rest.slice(start + phrase.length + 1)\n }\n return found.sort((a, b) => a.index - b.index).map((f) => f.value)\n}\n\nfunction graphemes(text: string): string[] {\n return [...new Intl.Segmenter(undefined, { granularity: 'grapheme' }).segment(text)].map((g) => g.segment)\n}\n\nexport type SwatchResolverOptions = {\n /** Diccionario de colores. Default: `defaultColors`. Para sumar vocabulario: `[...defaultColors, ...tusColores]`. */\n colors?: ColorEntry[]\n /** Diccionario de emoji (sin default: es vocabulario del giro). */\n emojis?: EmojiEntry[]\n /** Qué dibujar si hay color y emoji: `auto`/`color` = color primero, `emoji` = emoji primero, `both` = píldora pastel con colores y emoji. */\n prefer?: SwatchPrefer\n}\n\nexport type SwatchResolver = {\n /** Colores del nombre (\"Rojo / Negro\", \"#ff8800\"), en orden de lectura, o `null`. */\n colors(value: string): string[] | null\n /** Emoji(s) del nombre (hasta 3, sin repetir), o `null`. */\n emoji(value: string): string | null\n /** Muestra de una variante: primero el atributo del catálogo, luego el nombre según `prefer`. */\n resolve(value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null\n /** ¿Todos los valores de una opción tienen muestra? */\n hasSwatches(values: string[], attribute?: Map<string, SwatchSpec>): boolean\n}\n\nexport function createSwatchResolver({ colors: colorTable = defaultColors, emojis = [], prefer = 'auto' }: SwatchResolverOptions = {}): SwatchResolver {\n const colors = (value: string): string[] | null => {\n const text = normalize(value)\n if (!text) return null\n const hex = (text.match(HEX_IN_TEXT) ?? []).filter((h) => HEX.test(h))\n const found = [...hex, ...scan(text, colorTable).flat()]\n const unique = found.filter((c, i) => found.indexOf(c) === i).slice(0, MAX)\n return unique.length > 0 ? unique : null\n }\n const emoji = (value: string): string | null => {\n const parts = scan(normalize(value), emojis).flatMap(graphemes)\n const unique = parts.filter((e, i) => parts.indexOf(e) === i).slice(0, 3)\n return unique.length > 0 ? unique.join('') : null\n }\n const resolve = (value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null => {\n const fromCatalog = attribute?.get(normalize(value))\n if (fromCatalog) return fromCatalog\n const c = colors(value)\n const e = emoji(value)\n if (prefer === 'both' && c && e) return { colors: c, emoji: e }\n if (prefer === 'emoji') return e ? { emoji: e } : c ? { colors: c } : null\n if (prefer === 'color') return c ? { colors: c } : e ? { emoji: e } : null\n return c ? { colors: c } : e ? { emoji: e } : null\n }\n return { colors, emoji, resolve, hasSwatches: (values, attribute) => values.length > 0 && values.every((v) => resolve(v, attribute) !== null) }\n}\n\nconst basic = createSwatchResolver()\n\n/** Colores básicos del nombre (sin vocabulario de giro). Para uno propio: `createSwatchResolver`. */\nexport const resolveSwatch = basic.colors\n/** Muestra de una variante con solo colores básicos. Para uno propio: `createSwatchResolver`. */\nexport const resolveSwatchSpec = (value: string, attribute?: Map<string, SwatchSpec>): SwatchSpec | null => basic.resolve(value, attribute)\nexport const optionHasSwatches = basic.hasSwatches\n\n/**\n * Atributo del producto con el color o emoji de cada variante, como lo siembra el catálogo (OPS):\n * `\"Mora Azul:#3d4fd6|Fresa Kiwi:#ff4d6d+#8bc34a 🍓🥝|Natural:🥛\"`. Cada valor es un hex, varios hex con \"+\" (combinación), emoji, o colores y emoji juntos.\n * Es la fuente de verdad: manda sobre cualquier diccionario.\n */\nexport function parseSwatchAttribute(raw: unknown): Map<string, SwatchSpec> {\n const map = new Map<string, SwatchSpec>()\n if (typeof raw !== 'string') return map\n for (const part of raw.split('|')) {\n const i = part.lastIndexOf(':')\n if (i <= 0) continue\n const name = normalize(part.slice(0, i))\n const value = part.slice(i + 1).trim()\n const colors = (value.match(HEX_IN_TEXT) ?? []).filter((c) => HEX.test(c)).slice(0, MAX)\n const emoji = value.replace(HEX_IN_TEXT, '').replace(/[+\\s]/g, '')\n const hasEmoji = emoji.length > 0 && /\\p{Extended_Pictographic}/u.test(emoji)\n if (colors.length > 0 || hasEmoji) map.set(name, { ...(colors.length > 0 ? { colors } : {}), ...(hasEmoji ? { emoji } : {}) })\n }\n return map\n}\n\n/** Fondo CSS plano: un color liso, dos mitades, o sectores iguales (hasta 4). */\nexport function swatchBackground(colors: string[]): string {\n const [first = 'transparent', second] = colors\n if (second === undefined) return first\n if (colors.length === 2) return `linear-gradient(90deg, ${first} 50%, ${second} 50%)`\n const step = 360 / colors.length\n return `conic-gradient(${colors.map((c, i) => `${c} ${i * step}deg ${(i + 1) * step}deg`).join(', ')})`\n}\n\n/** Luminancia relativa (0 negro – 1 blanco) de un color hex, para decidir si hace falta un aro. */\nexport function luminance(hex: string): number {\n const h = hex.replace('#', '')\n const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h\n const channel = (i: number): number => {\n const v = parseInt(full.slice(i, i + 2), 16) / 255\n return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4\n }\n return 0.2126 * channel(0) + 0.7152 * channel(2) + 0.0722 * channel(4)\n}\n\n/**\n * Fondo pastel de una píldora: cada color mezclado con blanco (queda claro y suave en claro y oscuro), un degradado suave entre\n * ellos si son varios. Con ese fondo el emoji siempre contrasta.\n */\nexport function pastelBackground(colors: string[]): string {\n const soft = colors.map((c) => `color-mix(in srgb, ${c} 26%, white)`)\n const [first = 'transparent', second] = soft\n if (second === undefined) return first\n return `linear-gradient(100deg, ${soft.join(', ')})`\n}\n","import type { CSSProperties } from 'react'\nimport { luminance, pastelBackground, resolveSwatchSpec, swatchBackground, type SwatchSpec } from './swatch-colors'\n\nexport type SwatchProps = {\n /** Nombre de la variante; se resuelve con los colores básicos del SDK. Para vocabulario propio resuelve tú con `createSwatchResolver` y pasa `spec`. */\n value?: string\n /** Lo que se dibuja (color(es) o emoji), ya resuelto: del catálogo (`parseSwatchAttribute`) o de tu `createSwatchResolver`. Manda sobre `value`. */\n spec?: SwatchSpec | null\n size?: number\n shape?: 'circle' | 'square'\n className?: string\n}\n\n/**\n * Muestra de color 2D para variantes: plana, sin sombras ni brillos y sin borde, salvo un aro mínimo cuando el color\n * se perdería contra el fondo (blanco en tema claro, negro en tema oscuro). Las combinaciones se dibujan en partes iguales.\n * Es decorativa (aria-hidden): el nombre de la variante debe ir siempre como texto junto a ella.\n * Con `spec.emoji` dibuja el emoji. Devuelve null si no reconoce nada, para que el llamador muestre solo el texto.\n */\nexport function Swatch({ value = '', spec, size = 20, shape = 'circle', className = '' }: SwatchProps) {\n const resolved = spec ?? resolveSwatchSpec(value)\n if (!resolved) return null\n const colors = resolved.colors ?? []\n if (resolved.emoji) {\n // Badge: círculo (un emoji) o píldora (mezcla) con fondo pastel de los colores del sabor y el emoji encima; sin colores, fondo\n // neutro de superficie. En la mezcla los emoji se montan un poco, el primero arriba. Así se ve qué emoji forman cada grupo.\n const parts = [...new Intl.Segmenter(undefined, { granularity: 'grapheme' }).segment(resolved.emoji)].map((g) => g.segment)\n const mixed = parts.length > 1\n const style: CSSProperties = {\n minWidth: size,\n height: size,\n fontSize: Math.round(size * (mixed ? 0.56 : 0.6)),\n ...(colors.length > 0 ? { background: pastelBackground(colors), ['--sw-ring' as string]: colors[0] } : {}),\n }\n return (\n <span aria-hidden=\"true\" data-swatch=\"\" data-kind=\"emoji\" data-mixed={mixed || undefined} data-colored={colors.length > 0 || undefined} data-shape={shape} className={className || undefined} style={style}>\n {parts.map((emoji, i) => (\n <span key={`${emoji}-${i}`} style={i > 0 ? { marginInlineStart: '-0.3em', zIndex: parts.length - i } : { zIndex: parts.length }}>\n {emoji}\n </span>\n ))}\n </span>\n )\n }\n if (colors.length === 0) return null\n const lums = colors.map(luminance)\n const edge = lums.some((l) => l > 0.82) ? 'light' : lums.some((l) => l < 0.04) ? 'dark' : undefined\n const style: CSSProperties = { width: size, height: size, background: swatchBackground(colors) }\n return <span aria-hidden=\"true\" data-swatch=\"\" data-edge={edge} data-shape={shape} className={className || undefined} style={style} />\n}\n","import { useEffect, useState } from 'react'\n\ntype Theme = 'light' | 'dark'\n\n/** Script de cabecera: aplica el tema guardado antes de pintar (sin parpadeo). Sin preferencia guardada manda el sistema. */\nexport const THEME_INIT_SCRIPT = `try{var t=localStorage.getItem(\"theme\");if(t===\"light\"||t===\"dark\")document.documentElement.setAttribute(\"data-theme\",t)}catch(e){}`\n\nfunction current(): Theme {\n const attr = document.documentElement.getAttribute('data-theme')\n if (attr === 'light' || attr === 'dark') return attr\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\n/**\n * Botón claro/oscuro. El estado real se lee del DOM tras hidratar (el servidor no sabe la preferencia).\n * Guarda la elección en localStorage (\"theme\") y fija `html[data-theme]`; los tokens de la tienda reaccionan a eso.\n */\nexport function ThemeToggle({ className = '', themeColors = { light: '#ffffff', dark: '#000000' } }: { className?: string; themeColors?: { light: string; dark: string } }) {\n const [theme, setTheme] = useState<Theme | null>(null)\n useEffect(() => setTheme(current()), [])\n\n const toggle = () => {\n const next: Theme = current() === 'dark' ? 'light' : 'dark'\n document.documentElement.setAttribute('data-theme', next)\n try {\n localStorage.setItem('theme', next)\n } catch {\n /* modo privado: el cambio dura la sesión */\n }\n document.querySelector('meta[name=\"theme-color\"][data-dynamic]')?.setAttribute('content', themeColors[next])\n setTheme(next)\n }\n\n const dark = theme === 'dark'\n return (\n <button type=\"button\" onClick={toggle} className={className} aria-label={dark ? 'Cambiar a tema claro' : 'Cambiar a tema oscuro'} aria-pressed={theme === null ? undefined : dark}>\n {dark ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z\" />\n </svg>\n )}\n </button>\n )\n}\n","import { useEffect, useState } from 'react'\n\ntype InstallEvent = Event & { prompt: () => Promise<void>; userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }> }\n\n/** Registra el service worker (solo si `enabled`, normalmente producción; requiere HTTPS o localhost). */\nexport function useServiceWorker({ enabled, url = '/sw.js', scope = '/' }: { enabled: boolean; url?: string; scope?: string }) {\n useEffect(() => {\n if (!enabled || !('serviceWorker' in navigator)) return\n const register = () => navigator.serviceWorker.register(url, { scope }).catch(() => undefined)\n if (document.readyState === 'complete') register()\n else window.addEventListener('load', register, { once: true })\n }, [enabled, url, scope])\n}\n\n/**\n * Botón \"Instalar app\": aparece solo cuando el navegador ofrece la instalación (Chrome, Edge, Android).\n * En iPhone/iPad no existe ese evento: muestra la instrucción de Compartir → Agregar a pantalla de inicio.\n */\nexport function InstallApp({ className = '', label = 'Instalar app', iosHint = 'Para instalar: toca Compartir y luego «Agregar a pantalla de inicio».' }: { className?: string; label?: string; iosHint?: string }) {\n const [event, setEvent] = useState<InstallEvent | null>(null)\n const [ios, setIos] = useState(false)\n const [installed, setInstalled] = useState(true)\n\n useEffect(() => {\n const standalone = window.matchMedia('(display-mode: standalone)').matches || (navigator as Navigator & { standalone?: boolean }).standalone === true\n setInstalled(standalone)\n setIos(/iphone|ipad|ipod/i.test(navigator.userAgent) && !standalone)\n const onPrompt = (e: Event) => {\n e.preventDefault()\n setEvent(e as InstallEvent)\n }\n const onInstalled = () => setInstalled(true)\n window.addEventListener('beforeinstallprompt', onPrompt)\n window.addEventListener('appinstalled', onInstalled)\n return () => {\n window.removeEventListener('beforeinstallprompt', onPrompt)\n window.removeEventListener('appinstalled', onInstalled)\n }\n }, [])\n\n if (installed) return null\n if (event) {\n return (\n <button\n type=\"button\"\n className={className}\n onClick={async () => {\n await event.prompt()\n await event.userChoice\n setEvent(null)\n }}\n >\n {label}\n </button>\n )\n }\n return ios ? <p className={className}>{iosHint}</p> : null\n}\n","import { createElement, type ComponentPropsWithoutRef, type ElementType, type ReactNode } from 'react'\nimport { formatMoney, parseMoney, type FormatMoneyOptions, type Image as ImageData, type Money as MoneyData, type Product, type ProductVariant } from '@asteby/storefront'\nimport { useOptionalStorefront } from './context.js'\n\n// ---------------------------------------------------------------------------\n// Money\n// ---------------------------------------------------------------------------\n\nexport type MoneyProps<As extends ElementType = 'span'> = FormatMoneyOptions & {\n data: MoneyData\n /** Element to render (default `span`). */\n as?: As\n /** Overrides the provider locale. */\n locale?: string\n} & Omit<ComponentPropsWithoutRef<As>, 'children' | 'as'>\n\n/** Formats `Money` with the provider locale (or `locale`). */\nexport function Money<As extends ElementType = 'span'>({\n data,\n as,\n locale,\n withoutTrailingZeros,\n withoutCurrency,\n currencyDisplay,\n ...rest\n}: MoneyProps<As>) {\n const sf = useOptionalStorefront()\n const text = formatMoney(data, locale ?? sf?.locale, {\n ...(withoutTrailingZeros !== undefined ? { withoutTrailingZeros } : {}),\n ...(withoutCurrency !== undefined ? { withoutCurrency } : {}),\n ...(currencyDisplay !== undefined ? { currencyDisplay } : {}),\n })\n return createElement(as ?? 'span', rest, text)\n}\n\n// ---------------------------------------------------------------------------\n// Image\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_IMAGE_WIDTHS = [320, 480, 640, 768, 1024, 1280, 1600] as const\n\n/** Builds the URL for one srcset width. */\nexport type ImageLoader = (src: string, width: number, height?: number) => string\n\n/**\n * Default loader: adds `?width=<w>` (the convention of most image CDNs and of\n * the OPS image proxy). URLs that cannot be parsed are returned unchanged.\n */\nexport const defaultImageLoader: ImageLoader = (src, width, height) => {\n try {\n const isAbsolute = /^[a-z][a-z0-9+.-]*:/i.test(src)\n const url = new URL(src, 'http://relative.invalid')\n url.searchParams.set('width', String(width))\n if (height) url.searchParams.set('height', String(height))\n return isAbsolute ? url.toString() : url.pathname + url.search + url.hash\n } catch {\n return src\n }\n}\n\nexport type ImageProps = Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'srcSet' | 'width' | 'height'> & {\n data: ImageData\n /** `sizes` attribute (default `100vw`). */\n sizes?: string\n /** Candidate widths for `srcset` (capped at the intrinsic width when known). */\n widths?: readonly number[]\n /** URL builder per width (default adds `?width=`). Pass `null` to disable srcset. */\n loader?: ImageLoader | null\n /** Above-the-fold image: eager loading and `fetchpriority=\"high\"`. */\n priority?: boolean\n /** Forces an aspect ratio, e.g. `1/1` or `4/3`, used for width/height and srcset heights. */\n aspectRatio?: string\n}\n\nfunction parseRatio(ratio: string | undefined): number | null {\n if (!ratio) return null\n const [w, h] = ratio.split(/[/:]/).map((n) => Number.parseFloat(n))\n return w && h ? w / h : null\n}\n\n/** Responsive `<img>` with `srcset`, lazy by default, intrinsic size to avoid layout shift. */\nexport function Image({\n data,\n sizes = '100vw',\n widths = DEFAULT_IMAGE_WIDTHS,\n loader = defaultImageLoader,\n priority = false,\n aspectRatio,\n alt,\n loading,\n decoding,\n ...rest\n}: ImageProps) {\n const ratio = parseRatio(aspectRatio) ?? (data.width && data.height ? data.width / data.height : null)\n let candidates = [...widths].sort((a, b) => a - b)\n if (data.width) {\n const capped = candidates.filter((w) => w <= data.width!)\n candidates = capped.length ? capped : [data.width]\n }\n const srcSet = loader\n ? candidates.map((w) => `${loader(data.url, w, ratio ? Math.round(w / ratio) : undefined)} ${w}w`).join(', ')\n : undefined\n const width = data.width ?? candidates[candidates.length - 1]\n const height = data.height ?? (ratio && width ? Math.round(width / ratio) : undefined)\n return (\n <img\n src={data.url}\n alt={alt ?? data.alt ?? ''}\n {...(srcSet ? { srcSet, sizes } : {})}\n {...(width ? { width } : {})}\n {...(height ? { height } : {})}\n loading={loading ?? (priority ? 'eager' : 'lazy')}\n decoding={decoding ?? (priority ? 'auto' : 'async')}\n {...(priority ? { fetchPriority: 'high' as const } : {})}\n {...rest}\n />\n )\n}\n\n// ---------------------------------------------------------------------------\n// ProductPrice\n// ---------------------------------------------------------------------------\n\nconst VISUALLY_HIDDEN = {\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: 0,\n} as const\n\nexport type ProductPriceProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'> & {\n product?: Pick<Product, 'price_range' | 'compare_at_price_range'> | null\n variant?: Pick<ProductVariant, 'price' | 'compare_at_price'> | null\n /** Prefix shown when the product has a price range and no variant is selected (default `Desde`). */\n fromLabel?: ReactNode\n /** Accessible label for the compare-at price (default `Precio anterior`). */\n compareAtLabel?: string\n locale?: string\n withoutTrailingZeros?: boolean\n}\n\n/**\n * Price with optional compare-at (strikethrough). With a `variant` it shows\n * that variant; otherwise the product's minimum price (prefixed with\n * `fromLabel` when prices vary).\n */\nexport function ProductPrice({\n product,\n variant,\n fromLabel = 'Desde',\n compareAtLabel = 'Precio anterior',\n locale,\n withoutTrailingZeros,\n ...rest\n}: ProductPriceProps) {\n let price: MoneyData | null = null\n let compareAt: MoneyData | null = null\n let isRange = false\n if (variant) {\n price = variant.price\n compareAt = variant.compare_at_price\n } else if (product) {\n price = product.price_range.min\n compareAt = product.compare_at_price_range?.min ?? null\n isRange = product.price_range.min.amount !== product.price_range.max.amount\n }\n if (!price) return null\n const onSale = compareAt !== null && parseMoney(compareAt) > parseMoney(price)\n const opts = { ...(locale ? { locale } : {}), ...(withoutTrailingZeros !== undefined ? { withoutTrailingZeros } : {}) }\n return (\n <div data-on-sale={onSale || undefined} {...rest}>\n {isRange ? <span data-price-prefix=\"\">{fromLabel} </span> : null}\n <Money data={price} data-price=\"\" {...opts} />\n {onSale && compareAt ? (\n <>\n {' '}\n <s data-compare-at-price=\"\">\n <span style={VISUALLY_HIDDEN}>{compareAtLabel}: </span>\n <Money data={compareAt} {...opts} />\n </s>\n </>\n ) : null}\n </div>\n )\n}\n","/**\n * Product preview of the storefront: ONE picture-plus-text pattern for every place a product is listed (cart drawer,\n * checkout summary, \"Mis pedidos\", order detail). Headless (`data-sf-preview*`, `classNames`), styled by\n * `product-preview.css` (plain CSS on the store tokens, dark mode included), SSR-safe.\n *\n * - `ProductThumb`: the picture alone. Fixed aspect ratio, `object-fit: contain` on a soft surface (parts photographed\n * on white are never cropped), responsive `srcset` through the shared `Image`, lazy by default, a shimmer while it\n * loads and an elegant fallback (initial of the name, or a package glyph) when there is no image, it is broken, or\n * the product no longer exists. Optional quantity badge.\n * - `ProductPreview`: thumb + name (2 lines) + variant + SKU + quantity x unit price, with the line total aligned right.\n * - `ProductThumbStack`: overlapped thumbs with a \"+N\" counter (order cards).\n */\nimport { useEffect, useRef, useState, type ReactNode } from 'react'\nimport type { Image as ImageData } from '@asteby/storefront'\nimport { Image, type ImageLoader } from '../components.js'\n\ntype ThumbState = 'loading' | 'loaded' | 'fallback'\n\n/** First letter(s) of the name for the fallback: two initials from two words, one otherwise. Empty when nothing usable. */\nexport function productInitials(name: string | null | undefined): string {\n const words = (name ?? '')\n .normalize('NFKC')\n .split(/[\\s\\-_/.,()]+/)\n .map((w) => Array.from(w).find((c) => /\\p{L}|\\p{N}/u.test(c)) ?? '')\n .filter(Boolean)\n if (words.length === 0) return ''\n return (words.length > 1 ? words[0]! + words[1]! : words[0]!).toLocaleUpperCase()\n}\n\nexport type ProductThumbClassNames = Partial<Record<'root' | 'img' | 'fallback' | 'badge', string>>\n\nexport type ProductThumbImage = { url: string; alt?: string | null; width?: number; height?: number }\n\nexport type ProductThumbProps = {\n /** Picture of the product or variant. `null`/missing: shows the fallback. */\n image?: ProductThumbImage | null\n /** Name of the product: alt of the picture (unless `decorative`) and source of the fallback initial. */\n name?: string | null\n /** Side in px. Default 56. */\n size?: number\n /** Aspect ratio of the box, `w/h`. Default `1/1`. */\n ratio?: string\n /** `contain` (default) never crops; `cover` fills the box. */\n fit?: 'contain' | 'cover'\n /** Quantity badge, shown when greater than 1. */\n quantity?: number\n /** The name sits next to it as text: the picture has `alt=\"\"` and the fallback is hidden from screen readers. Default false. */\n decorative?: boolean\n /** Slight zoom on hover (honours `prefers-reduced-motion`). Default true. */\n zoom?: boolean\n /** Above the fold: eager load. */\n priority?: boolean\n sizes?: string\n loader?: ImageLoader | null\n className?: string\n classNames?: ProductThumbClassNames\n}\n\n/** The picture of a product with fixed ratio, shimmer, lazy loading and a fallback that always looks designed. */\nexport function ProductThumb({\n image,\n name,\n size = 56,\n ratio = '1/1',\n fit = 'contain',\n quantity,\n decorative = false,\n zoom = true,\n priority = false,\n sizes,\n loader,\n className,\n classNames: cx = {},\n}: ProductThumbProps) {\n const url = image?.url || null\n const [state, setState] = useState<ThumbState>(url ? 'loading' : 'fallback')\n const box = useRef<HTMLSpanElement>(null)\n // A new picture (another variant) starts over; a missing one goes straight to the fallback.\n useEffect(() => {\n const img = box.current?.querySelector('img')\n // The browser may have loaded the picture before hydration: no `load` event will come.\n setState(!url ? 'fallback' : img?.complete ? (img.naturalWidth > 0 ? 'loaded' : 'fallback') : 'loading')\n }, [url])\n\n const label = name?.trim() || ''\n const initials = productInitials(label)\n const showBadge = typeof quantity === 'number' && quantity > 1\n const a11y = state === 'fallback' && !decorative && label ? { role: 'img', 'aria-label': label } : { 'aria-hidden': decorative || state === 'fallback' ? true : undefined }\n return (\n <span\n ref={box}\n className={[cx.root, className].filter(Boolean).join(' ') || undefined}\n style={{ ['--sf-preview-size' as string]: `${size}px`, ['--sf-preview-ratio' as string]: ratio.replace(':', '/') }}\n data-sf-thumb=\"\"\n data-state={state}\n data-fit={fit}\n data-zoom={zoom || undefined}\n {...a11y}\n >\n {url && state !== 'fallback' ? (\n <Image\n data={{ url, alt: image?.alt ?? null, ...(image?.width ? { width: image.width } : {}), ...(image?.height ? { height: image.height } : {}) }}\n alt={decorative ? '' : (image?.alt ?? label)}\n aspectRatio={ratio}\n sizes={sizes ?? `${size * 2}px`}\n widths={[Math.round(size), Math.round(size * 2), Math.round(size * 3)]}\n {...(loader !== undefined ? { loader } : {})}\n priority={priority}\n className={cx.img}\n onLoad={() => setState('loaded')}\n onError={() => setState('fallback')}\n />\n ) : null}\n {state === 'fallback' ? (\n <span className={cx.fallback} data-sf-thumb-fallback=\"\" aria-hidden=\"true\">\n {initials ? <span data-sf-thumb-initial=\"\">{initials}</span> : <PackageGlyph />}\n </span>\n ) : null}\n {showBadge ? (\n <span className={cx.badge} data-sf-thumb-qty=\"\" aria-hidden=\"true\">\n {quantity}\n </span>\n ) : null}\n </span>\n )\n}\n\nfunction PackageGlyph() {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"45%\" height=\"45%\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" focusable=\"false\">\n <path d=\"M21 8 12 3 3 8v8l9 5 9-5V8Z\" />\n <path d=\"m3 8 9 5 9-5M12 13v8\" />\n </svg>\n )\n}\n\nexport type ProductPreviewClassNames = Partial<Record<'root' | 'media' | 'body' | 'name' | 'variant' | 'meta' | 'sku' | 'qty' | 'price' | 'total' | 'unit', string>> & { thumb?: ProductThumbClassNames }\n\nexport type ProductPreviewProps = Pick<ProductThumbProps, 'image' | 'size' | 'ratio' | 'fit' | 'zoom' | 'priority' | 'sizes' | 'loader'> & {\n name: string\n /** \"Rojo / L\". Omit for default variants. */\n variant?: string | null\n sku?: string | null\n /** Quantity: a badge on the picture (> 1) and \"Cantidad N\" under the name. */\n quantity?: number\n /** Unit price, already formatted. Shown next to the quantity when it is greater than 1. */\n unitPrice?: ReactNode\n /** Line total, already formatted: aligned right, the strongest number. */\n total?: ReactNode\n /** Link on the name (product page). */\n href?: string | null\n /** Rendered under the text (status, note, actions). */\n children?: ReactNode\n /** Text of the quantity for screen readers and the meta line. Default `Cantidad {n}`. */\n quantityLabel?: string\n /** Name shown when the line has none (product deleted). Default `Producto no disponible`. */\n unavailableLabel?: string\n className?: string\n classNames?: ProductPreviewClassNames\n}\n\n/**\n * A product line: picture, name (2 lines), variant, SKU, quantity and prices with a clear hierarchy. Degrades to a\n * designed placeholder when the product has no image or no longer exists (empty name).\n */\nexport function ProductPreview({\n image,\n name,\n variant,\n sku,\n quantity,\n unitPrice,\n total,\n href,\n children,\n size = 64,\n ratio,\n fit,\n zoom,\n priority,\n sizes,\n loader,\n quantityLabel,\n unavailableLabel = 'Producto no disponible',\n className,\n classNames: cx = {},\n}: ProductPreviewProps) {\n const missing = !name.trim()\n const title = missing ? unavailableLabel : name\n const hasQty = typeof quantity === 'number' && Number.isFinite(quantity)\n return (\n <div className={[cx.root, className].filter(Boolean).join(' ') || undefined} data-sf-preview=\"\" data-missing={missing || undefined}>\n <span className={cx.media} data-sf-preview-media=\"\">\n <ProductThumb\n image={image}\n name={missing ? null : name}\n size={size}\n decorative\n {...(ratio ? { ratio } : {})}\n {...(fit ? { fit } : {})}\n {...(zoom !== undefined ? { zoom } : {})}\n {...(priority ? { priority } : {})}\n {...(sizes ? { sizes } : {})}\n {...(loader !== undefined ? { loader } : {})}\n {...(hasQty ? { quantity: quantity! } : {})}\n {...(cx.thumb ? { classNames: cx.thumb } : {})}\n />\n </span>\n <span className={cx.body} data-sf-preview-body=\"\">\n <span className={cx.name} data-sf-preview-name=\"\">\n {href && !missing ? <a href={href}>{title}</a> : title}\n </span>\n {variant ? (\n <span className={cx.variant} data-sf-preview-variant=\"\">\n {variant}\n </span>\n ) : null}\n {sku ? (\n <span className={cx.sku} data-sf-preview-sku=\"\">\n SKU {sku}\n </span>\n ) : null}\n {hasQty ? (\n <span className={cx.meta} data-sf-preview-meta=\"\">\n <span className={cx.qty} data-sf-preview-qty=\"\">\n {(quantityLabel ?? 'Cantidad {n}').replace('{n}', String(quantity))}\n </span>\n {unitPrice != null && quantity! > 1 ? (\n <span className={cx.unit} data-sf-preview-unit=\"\">\n {' · '}\n {unitPrice}\n </span>\n ) : null}\n </span>\n ) : null}\n {children}\n </span>\n {total != null ? (\n <span className={cx.total} data-sf-preview-total=\"\">\n {total}\n </span>\n ) : unitPrice != null && !(hasQty && quantity! > 1) ? (\n <span className={cx.price} data-sf-preview-total=\"\">\n {unitPrice}\n </span>\n ) : null}\n </div>\n )\n}\n\nexport type ProductThumbStackProps = {\n items: ReadonlyArray<{ image?: ProductThumbImage | null; name?: string | null }>\n /** Thumbs shown before \"+N\". Default 4. */\n max?: number\n size?: number\n /** Screen reader text for the hidden remainder, `{n}` = how many. Default `y {n} más`. */\n moreLabel?: string\n className?: string\n}\n\n/** Overlapped thumbs with a \"+N\" counter: the products of an order at a glance. */\nexport function ProductThumbStack({ items, max = 4, size = 44, moreLabel = 'y {n} más', className }: ProductThumbStackProps) {\n if (items.length === 0) return null\n const shown = items.length > max ? items.slice(0, max - 1) : items\n const rest = items.length - shown.length\n return (\n <span className={className} data-sf-thumb-stack=\"\" style={{ ['--sf-preview-size' as string]: `${size}px` }}>\n {shown.map((it, i) => (\n <ProductThumb key={i} image={it.image ?? null} name={it.name ?? null} size={size} zoom={false} />\n ))}\n {rest > 0 ? (\n <span data-sf-thumb-more=\"\" role=\"img\" aria-label={moreLabel.replace('{n}', String(rest))}>\n +{rest}\n </span>\n ) : null}\n </span>\n )\n}\n"]}
package/dist/ui.css CHANGED
@@ -164,3 +164,145 @@
164
164
  @media (prefers-color-scheme: dark) {
165
165
  :root:not([data-theme="light"]) .check:checked { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23080808' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3.2L13 4.5'/%3E%3C/svg%3E"); }
166
166
  }
167
+
168
+ /*
169
+ * <ProductThumb>, <ProductPreview>, <ProductThumbStack>: la foto del producto y la línea de producto de la tienda.
170
+ * CSS plano sobre los tokens de la tienda (--foreground, --background, --border, --muted-foreground, --radius); en tema
171
+ * oscuro la superficie y el brillo salen de color-mix, sin colores escritos aquí. Va incluido en cart.css, checkout.css,
172
+ * account.css y ui.css (misma regla, un solo origen: src/ui/product-preview.css).
173
+ */
174
+ [data-sf-thumb] {
175
+ --_surface: color-mix(in srgb, var(--foreground, #111) 5%, var(--background, #fff));
176
+ position: relative;
177
+ display: inline-block;
178
+ flex: none;
179
+ box-sizing: border-box;
180
+ width: var(--sf-preview-size, 3.5rem);
181
+ aspect-ratio: var(--sf-preview-ratio, 1 / 1);
182
+ overflow: hidden;
183
+ border-radius: calc(var(--radius, 0.5rem) * 1.25);
184
+ background: var(--_surface);
185
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--foreground, #111) 9%, transparent);
186
+ vertical-align: middle;
187
+ }
188
+ :root[data-theme="dark"] [data-sf-thumb] { --_surface: color-mix(in srgb, var(--foreground, #fff) 9%, var(--background, #111)); }
189
+ [data-sf-thumb] > img {
190
+ display: block;
191
+ width: 100%;
192
+ height: 100%;
193
+ box-sizing: border-box;
194
+ object-fit: contain;
195
+ padding: 6%;
196
+ transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1), opacity 180ms;
197
+ }
198
+ [data-sf-thumb][data-fit="cover"] > img { object-fit: cover; padding: 0; }
199
+ /* Fotos sobre fondo blanco: se funden con la superficie en tema claro (no hay caja blanca dentro del marco). */
200
+ [data-sf-thumb][data-fit="contain"] > img { mix-blend-mode: multiply; }
201
+ :root[data-theme="dark"] [data-sf-thumb] > img { mix-blend-mode: normal; }
202
+ [data-sf-thumb][data-state="loading"]::before {
203
+ content: "";
204
+ position: absolute;
205
+ inset: 0;
206
+ background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--foreground, #111) 8%, transparent) 50%, transparent 80%);
207
+ background-size: 200% 100%;
208
+ animation: sf-thumb-shimmer 1.4s linear infinite;
209
+ pointer-events: none;
210
+ }
211
+ @keyframes sf-thumb-shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }
212
+ [data-sf-thumb][data-zoom]:hover > img { transform: scale(1.07); }
213
+ @media (prefers-reduced-motion: reduce) {
214
+ [data-sf-thumb][data-state="loading"]::before { animation: none; }
215
+ [data-sf-thumb] > img { transition: none; }
216
+ [data-sf-thumb][data-zoom]:hover > img { transform: none; }
217
+ }
218
+
219
+ [data-sf-thumb-fallback] {
220
+ position: absolute;
221
+ inset: 0;
222
+ display: grid;
223
+ place-items: center;
224
+ color: color-mix(in srgb, var(--foreground, #111) 42%, transparent);
225
+ background: linear-gradient(145deg, color-mix(in srgb, var(--foreground, #111) 3%, transparent), color-mix(in srgb, var(--foreground, #111) 9%, transparent));
226
+ }
227
+ [data-sf-thumb-initial] {
228
+ font-size: calc(var(--sf-preview-size, 3.5rem) * 0.36);
229
+ font-weight: 600;
230
+ letter-spacing: 0.02em;
231
+ line-height: 1;
232
+ }
233
+
234
+ [data-sf-thumb-qty] {
235
+ position: absolute;
236
+ top: 0.2rem;
237
+ right: 0.2rem;
238
+ min-width: 1.25rem;
239
+ height: 1.25rem;
240
+ padding: 0 0.3rem;
241
+ box-sizing: border-box;
242
+ display: inline-grid;
243
+ place-items: center;
244
+ border-radius: 999px;
245
+ font-size: 0.7rem;
246
+ font-weight: 700;
247
+ font-variant-numeric: tabular-nums;
248
+ background: var(--sf-summary-qty-bg, color-mix(in srgb, var(--foreground, #111) 78%, transparent));
249
+ color: var(--sf-summary-qty-fg, var(--background, #fff));
250
+ }
251
+
252
+ /* Línea de producto: foto | texto | importe. */
253
+ [data-sf-preview] {
254
+ display: flex;
255
+ align-items: center;
256
+ gap: 0.875rem;
257
+ min-width: 0;
258
+ }
259
+ [data-sf-preview][data-missing] [data-sf-preview-name] { font-style: italic; color: var(--muted-foreground, color-mix(in srgb, currentColor 60%, transparent)); }
260
+ [data-sf-preview-media] { flex: none; display: inline-flex; }
261
+ [data-sf-preview-body] { display: grid; flex: 1 1 auto; gap: 0.125rem; min-width: 0; }
262
+ [data-sf-preview-name] {
263
+ display: -webkit-box;
264
+ -webkit-line-clamp: 2;
265
+ -webkit-box-orient: vertical;
266
+ overflow: hidden;
267
+ overflow-wrap: anywhere;
268
+ font-size: 0.9375rem;
269
+ font-weight: 600;
270
+ line-height: 1.3;
271
+ }
272
+ [data-sf-preview-name] a { color: inherit; text-decoration: none; }
273
+ [data-sf-preview-name] a:hover { text-decoration: underline; }
274
+ [data-sf-preview-variant],
275
+ [data-sf-preview-sku],
276
+ [data-sf-preview-meta] {
277
+ font-size: 0.8125rem;
278
+ line-height: 1.35;
279
+ color: var(--muted-foreground, color-mix(in srgb, currentColor 66%, transparent));
280
+ }
281
+ [data-sf-preview-sku] { font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
282
+ [data-sf-preview-total] {
283
+ flex: none;
284
+ align-self: flex-start;
285
+ font-size: 0.9375rem;
286
+ font-weight: 700;
287
+ font-variant-numeric: tabular-nums;
288
+ text-align: right;
289
+ }
290
+
291
+ /* Fotos apiladas (tarjeta de pedido). */
292
+ [data-sf-thumb-stack] { display: inline-flex; align-items: center; }
293
+ [data-sf-thumb-stack] > * { box-shadow: 0 0 0 2px var(--card, var(--background, #fff)), inset 0 0 0 1px color-mix(in srgb, var(--foreground, #111) 9%, transparent); }
294
+ [data-sf-thumb-stack] > * + * { margin-inline-start: -0.625rem; }
295
+ [data-sf-thumb-more] {
296
+ display: inline-grid;
297
+ place-items: center;
298
+ flex: none;
299
+ box-sizing: border-box;
300
+ width: var(--sf-preview-size, 2.75rem);
301
+ aspect-ratio: 1 / 1;
302
+ border-radius: calc(var(--radius, 0.5rem) * 1.25);
303
+ font-size: 0.8125rem;
304
+ font-weight: 600;
305
+ font-variant-numeric: tabular-nums;
306
+ color: var(--muted-foreground, color-mix(in srgb, currentColor 66%, transparent));
307
+ background: color-mix(in srgb, var(--foreground, #111) 7%, var(--background, #fff));
308
+ }
package/dist/ui.d.cts CHANGED
@@ -1,4 +1,7 @@
1
1
  import * as react from 'react';
2
+ export { P as ProductPreview, a as ProductPreviewClassNames, b as ProductPreviewProps, c as ProductThumb, d as ProductThumbClassNames, e as ProductThumbImage, f as ProductThumbProps, g as ProductThumbStack, h as ProductThumbStackProps, p as productInitials } from './product-preview-DRtLWGLS.cjs';
3
+ import './components-B5XhSH-m.cjs';
4
+ import '@asteby/storefront';
2
5
 
3
6
  type SelectOption = {
4
7
  value: string;
package/dist/ui.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import * as react from 'react';
2
+ export { P as ProductPreview, a as ProductPreviewClassNames, b as ProductPreviewProps, c as ProductThumb, d as ProductThumbClassNames, e as ProductThumbImage, f as ProductThumbProps, g as ProductThumbStack, h as ProductThumbStackProps, p as productInitials } from './product-preview-DaICr4f2.js';
3
+ import './components-B5XhSH-m.js';
4
+ import '@asteby/storefront';
2
5
 
3
6
  type SelectOption = {
4
7
  value: string;
package/dist/ui.js CHANGED
@@ -1,7 +1,9 @@
1
+ export { ProductPreview, ProductThumb, ProductThumbStack, productInitials } from './chunk-VHEY5AU3.js';
2
+ import './chunk-6CVKW7F3.js';
3
+ import './chunk-DQBL2DFJ.js';
1
4
  import { useRef, useState, useId, useEffect } from 'react';
2
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
6
 
4
- // src/ui/select.tsx
5
7
  var Chevron = ({ open = false, floating = false }) => /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", "data-select-chevron": floating ? "floating" : "", "data-open": open || void 0, children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) });
6
8
  var Check = () => /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
7
9
  function Select({ id, name, options, defaultValue, label, className = "" }) {