Saltar al contenido principal

Temas y estilos

El widget se personaliza con dos mecanismos complementarios:

  1. Variables CSS --nrn-* dentro del Shadow DOM — más de 60 tokens en categorías surface, text, border, primary, secondary, accent, radius, shadow, transition, z-index y layout.
  2. StyleOverrides desde la configuración (config.styles) — sobre-escribe cualquier subconjunto de las variables. Acepta hex (#06b6d4), rgb() o RGB-triplet (6 182 212).

Como el widget vive en un Shadow DOM, los estilos del host no entran y los del widget no salen. Esto es deliberado: garantiza paridad visual entre tiendas y elimina conflictos con frameworks CSS del host (Bootstrap, Tailwind del tema, etc.).

Formato RGB-triplet

El widget guarda los colores en el formato R G B (sin comas, sin rgb()) para componer con rgb() y alpha runtime:

.neuroon-widget {
--nrn-primary: 8 145 178; /* cyan-600 (default) */
--nrn-surface-base: 255 255 255; /* white (default) */
}

.button {
background-color: rgb(var(--nrn-primary));
/* alpha dinámico sin redeclarar el color */
box-shadow: 0 0 0 4px rgb(var(--nrn-primary) / 0.18);
}

Si pasas un hex (#06b6d4) en StyleOverrides, el widget lo convierte automáticamente al triplet (colorToRgb en widget/src/styling/variables.ts).

Override por tema

NeuroonWidget.init({
/* … */
styles: {
light: {
primary: '#06b6d4',
surfaceBase: '#ffffff',
textPrimary: '#0f172a',
},
dark: {
primary: '#22d3ee',
surfaceBase: '#0f172a',
textPrimary: '#f8fafc',
},
},
})

El widget detecta la forma con isThemedStyles() y aplica el bloque correspondiente al tema activo.

Cuando el usuario cambia de tema (porque prefers-color-scheme cambia o porque llamas a widget.setTheme()), el widget re-inyecta los overrides del tema activo via injectCustomStyles().

Categorías de variables

CategoríaPrefijoEjemplos
Superficies--nrn-surface-*surface-base, surface-elevated, surface-overlay, surface-hover, surface-subtle, surface-sunken, surface-float
Texto--nrn-text-*text-primary, text-secondary, text-tertiary, text-muted, text-disabled
Bordes--nrn-border-*border-default, border-emphasis, border-subtle
Marca primaria--nrn-primary*primary, primary-light, primary-dark, primary-hover, primary-text, primary-50…950
Marca secundaria--nrn-secondary*secondary, secondary-light, secondary-dark
Accent--nrn-accent-*accent-purple, accent-emerald, accent-amber (+ *-strong)
Semánticas--nrn-success, --nrn-error, --nrn-warning, --nrn-info
Tipografía--nrn-font-*font-size-{xs..xl}, font-weight-{normal..display}, font-letter-spacing-*
Spacing--nrn-spacing-*xs, sm, md, lg, xl
Radius--nrn-radius-*sm, md, lg, xl, 2xl
Shadow--nrn-shadow-*xs, sm, md, lg, xl, 2xl, primary, primary-lg
Animación--nrn-duration-*, --nrn-ease-*, --nrn-motion-*duration-{instant..slower}, ease-{out..bounce}, motion-{entrance..stagger}
Z-index--nrn-z-*dropdown, sticky, fixed, drawer, modal, popover, tooltip, toast, modal-fullscreen
Glass--nrn-glass-*glass-blur, glass-bg, glass-border-glass, glass-shadow, glass-inset
Layout--nrn-container-max-width, --nrn-drawer-width, --nrn-dropdown-max-height

Listado exhaustivo con valores default en widget/src/tailwind.css.

Ejemplo end-to-end

<div id="neuroon-search"></div>
<script
src="https://cdn.neuroon.ai/widget@0.9.10/widget.js"
data-token="WIDGET_TOKEN"
data-container="#neuroon-search"
data-theme="auto"
defer
></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
if (!window.NeuroonWidget?.getInstance) return
const w = window.NeuroonWidget.getInstance('#neuroon-search')
w?.setStyles({
light: {
primary: '#0f766e',
primaryLight: '#14b8a6',
radiusLg: '0.5rem',
fontFamily: '"Inter", system-ui, sans-serif',
},
dark: {
primary: '#5eead4',
surfaceBase: '#031c1a',
textPrimary: '#ecfeff',
},
})
})
</script>

Detección automática del host (theme: 'auto')

Con theme: 'auto' (default), el widget consulta window.matchMedia('(prefers-color-scheme: dark)') al montarse y se suscribe a sus cambios. Cada cambio dispara internamente un CustomEvent('neuroon-theme-change') que re-inyecta los overrides del tema activo.

Forzar tema desde el host

Desde el código del host, usa la API JavaScript:

const w = window.NeuroonWidget.getInstance('#neuroon-search')
w?.setTheme('dark') // 'light' | 'dark' | 'auto'

Próximas lecturas