Skip to content

Personalización de temas ​

lh-ui-plus ofrece un sistema completo de temas basado en variables CSS, que admite la estética china (国风, estilo chino), el modo oscuro, los fondos con patrón y el cambio en tiempo de ejecución, entre otras amplias posibilidades de personalización.

¿Quieres ajustar los colores de forma visual y exportar directamente un archivo scss? Consulta el Estudio de temas.

Sistema de colores chinos ​

La biblioteca, inspirada en la tradición de la pintura a tinta 水墨丹青 (pintura a tinta china), define 8 colores de tema chinos:

ColorSignificadoColor principalHoverAplicación
靛蓝 (azul índigo)El azul de la porcelana azul y blanco#2B4C7C#3D649EBotones principales, enlaces, estado de foco
松花绿 (verde pino)El verde fresco de las sombras del bambú#5B8C5A#6FA36EEstado de éxito
藤黄 (amarillo herbáceo)El dorado de las hojas otoñales#C4A35A#D4B76FEstado de advertencia
朱砂 (cinabrio, peligro)El rojo de la pasta de los sellos#B23A3A#C45050Estado de peligro/error (--lh-danger-*)
黛色 (gris tinta)El toque tenue de la tinta china#7A7A7A#8F8F8FEstado de información
金色 (dorado)El encanto antiguo de la suntuosidad#B8860B#D4A843Adornos decorativos (--lh-gold-*)
朱砂红 (cinabrio rojizo, énfasis)Variante de énfasis del cinabrio#C43A31#E85D4AColor de énfasis (--lh-vermilion-*)
玉色 (verde jade)El encanto fresco del bambú esmeralda#5B8C5A#7AAE7AÉxito/decoración (mismo valor que 松花绿)

Cada color suele incluir 4 niveles (color principal, hover, active, fondo light); el color principal y el dorado añaden además un color de borde lighter (*-color-border), de modo que siempre exista un contraste adecuado para cada escenario.

Sistema de temas con variables CSS ​

Todos los colores de tema se implementan mediante propiedades personalizadas CSS (--lh-*), en total más de 88 variables, que cubren las siguientes categorías:

Variables de color ​

Prefijo de variableDescripciónEjemplo
--lh-primary-colorValor base del color principal#2B4C7C
--lh-primary-color-hoverEstado hover del color principal#3D649E
--lh-primary-color-activeEstado active del color principal#1F3A5F
--lh-primary-color-bgFondo claro del color principal#E8EDF3
--lh-success-colorColor de éxito#5B8C5A
--lh-warning-colorColor de advertencia#C4A35A
--lh-danger-colorColor de peligro#B23A3A
--lh-info-colorColor de información#7A7A7A

Variables de texto ​

VariableDescripciónPredeterminado
--lh-text-primaryTexto principal#2C2C2C
--lh-text-regularTexto regular#5A5A5A
--lh-text-secondaryTexto secundario#8A8A8A
--lh-text-placeholderMarcador de posición#B0B0B0
--lh-text-disabledTexto deshabilitado#C8C8C8

Variables de borde ​

VariableDescripciónPredeterminado
--lh-border-color-baseBorde predeterminado#D8D3CC
--lh-border-color-lightBorde ligero#E5E0D8
--lh-border-radius-baseRedondeo base2px
--lh-border-radius-roundRedondeo de cápsula20px

Variables de fondo ​

VariableDescripciónPredeterminado
--lh-bg-colorFondo de los componentes#FAF6F0 (color 宣纸, papel de arroz)
--lh-bg-color-pageFondo de la página#F5F0EB
--lh-bg-color-overlayFondo de la capa de coberturargba(26, 26, 26, 0.4)

Variables de sombra ​

VariableDescripción
--lh-box-shadow-baseSombra predeterminada
--lh-box-shadow-lightSombra ligera
--lh-box-shadow-lighterSombra muy ligera

Variables de tipografía ​

VariableDescripciónPredeterminado
--lh-font-familyFamilia tipográficaNoto Serif SC, STSong, SimSun...
--lh-font-size-baseTamaño de fuente base14px
--lh-font-size-smallTamaño de fuente pequeño13px
--lh-font-weight-primaryGrosor de fuente regular400
--lh-font-line-height-primaryAltura de línea1.8

Variables de espaciado ​

VariableValorUso
--lh-spacing-xs4pxEspaciado mínimo
--lh-spacing-sm8pxEspaciado pequeño
--lh-spacing-md12pxEspaciado medio
--lh-spacing-base16pxEspaciado base
--lh-spacing-lg20pxEspaciado grande
--lh-spacing-xl24pxEspaciado muy grande

Variables de Z-Index ​

VariableValorUso
--lh-z-index-dropdown1000Menú desplegable
--lh-z-index-modal1050Cuadro modal
--lh-z-index-tooltip2000Información sobre herramientas

Variables de transición ​

VariableValorDescripción
--lh-transition-duration-fast0.25sTransición rápida
--lh-transition-duration-base0.3sTransición predeterminada
--lh-transition-duration-slow0.4sTransición lenta

Tema oscuro ​

La biblioteca incorpora los estilos del tema oscuro; todas las variables CSS cambian automáticamente a sus valores adaptados en el modo oscuro.

Opción 1: usar el composable useLhTheme ​

Composition API ​

vue
<script setup lang="ts">
import { useLhTheme } from '@lh-ui/vue3'

const { theme, toggleTheme, setTheme } = useLhTheme()
</script>

<template>
  <div>
    <LhButton @click="toggleTheme">
      {{ theme === 'dark' ? 'Cambiar a claro' : 'Cambiar a oscuro' }}
    </LhButton>
    <LhButton @click="() => setTheme('light')">Claro</LhButton>
    <LhButton @click="() => setTheme('dark')">Oscuro</LhButton>
  </div>
</template>

Options API ​

vue
<script>
import { useLhTheme } from '@lh-ui/vue3'

export default {
  setup() {
    const { theme, toggleTheme, setTheme } = useLhTheme()
    return { theme, toggleTheme, setTheme }
  },
}
</script>

<template>
  <div>
    <LhButton @click="toggleTheme">
      {{ theme === 'dark' ? 'Cambiar a claro' : 'Cambiar a oscuro' }}
    </LhButton>
  </div>
</template>

useLhTheme persiste automáticamente el estado del tema en localStorage (clave: lh-ui-theme); tras actualizar la página, el tema no se pierde.

Opción 2: conmutación mediante atributo HTML ​

Establece data-theme="dark" en el elemento raíz para activar globalmente el modo oscuro:

html
<!DOCTYPE html>
<html lang="es" data-theme="dark">
  <!-- ... -->
</html>

Colores de tema personalizados (porcelana azul y blanco / verde pino / cinabrio) ​

Además de los temas claro y oscuro integrados, la biblioteca permite personalizar cualquier combinación de colores a través de themeVars para crear temas propios.

El ejemplo siguiente es una demostración de variables personalizadas escritas a mano, con valores ajustados para la explicación, y no coincide exactamente con los presets integrados del mismo nombre (cerblue / songhua / zhusha) de Temas predefinidos. Para usar directamente un preset integrado, emplea useLhPresetTheme o getThemeVars(name).

Tema 青花瓷 (porcelana azul y blanco) ​

Con un azul índigo profundo como color principal, inspirado en la porcelana azul y blanco tradicional.

Composition API ​

vue
<script setup lang="ts">
const cerblueTheme = {
  'primary-color': '#2B4C7C',
  'primary-color-hover': '#3D649E',
  'primary-color-active': '#1F3A5F',
  'primary-color-bg': '#E8EDF3',
  'bg-color': '#F0F4F8',
  'border-color-base': '#C8D6E5',
}
</script>

<template>
  <LhConfigProvider :theme-vars="cerblueTheme">
    <LhButton type="primary">Botón de porcelana azul</LhButton>
    <LhInput placeholder="Campo de porcelana azul" />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
import { LhConfigProvider, LhButton, LhInput } from '@lh-ui/vue3'

export default {
  components: { LhConfigProvider, LhButton, LhInput },
  data() {
    return {
      cerblueTheme: {
        'primary-color': '#2B4C7C',
        'primary-color-hover': '#3D649E',
        'primary-color-bg': '#E8EDF3',
        'bg-color': '#F0F4F8',
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider :theme-vars="cerblueTheme">
    <LhButton type="primary">Botón de porcelana azul</LhButton>
  </LhConfigProvider>
</template>

Tema 松花绿 (verde pino) ​

Con el verde del bambú como adorno, crea un estilo fresco y natural.

vue
<script setup lang="ts">
const bambooTheme = {
  'primary-color': '#5B8C5A',
  'primary-color-hover': '#6FA36E',
  'primary-color-bg': '#EDF5EC',
  'success-color': '#5B8C5A',
  'bg-color': '#F6FAF5',
}
</script>

<template>
  <LhConfigProvider :theme-vars="bambooTheme">
    <LhButton type="primary">Sendero del bosque de bambú</LhButton>
    <LhTag type="success">Nuevas hojas</LhTag>
  </LhConfigProvider>
</template>

Tema 朱砂红 (cinabrio rojizo) ​

Con el rojo de la pasta de los sellos como tono principal, destaca una atmósfera de elegancia y suntuosidad.

vue
<script setup lang="ts">
const vermilionTheme = {
  'primary-color': '#C43A31',
  'primary-color-hover': '#E85D4A',
  'primary-color-bg': '#FDF0EE',
  'bg-color': '#FFFBF9',
  'border-color-base': '#F0D5CF',
}
</script>

<template>
  <LhConfigProvider :theme-vars="vermilionTheme">
    <LhButton type="primary">Sello de cinabrio</LhButton>
  </LhConfigProvider>
</template>

Sistema de fondos con patrón ​

La biblioteca ofrece un sistema de fondos con patrón de poética china, con 6 presets, que se puede combinar con la lista blanca patternComponents para controlar con precisión el alcance de la aplicación.

Presets de patrón ​

PatrónVariable CSSDescripción
柳叶 (hoja de sauce)var(--lh-pattern-willow)Hojas de sauce alargadas, con densidad bien compuesta
祥云 (nube propicia)var(--lh-pattern-cloud)Nubes propicias que se despliegan, serpenteando
水波 (ondas de agua)var(--lh-pattern-water)Ondulaciones tenues, en capas superpuestas
雪花 (copo de nieve)var(--lh-pattern-snow)Copos hexagonales, con ramificaciones finas
梅花 (flor de ciruelo)var(--lh-pattern-plum)Cinco pétalos desplegados, con el centro bien definido
竹叶 (hoja de bambú)var(--lh-pattern-bamboo)Hojas de bambú lanceoladas, dispuestas con armonía

Configuración global de patrón ​

Composition API ​

vue
<script setup lang="ts">
const config = {
  themeVars: {
    'bg-pattern': 'var(--lh-pattern-cloud)',
    'bg-pattern-opacity': '0.15',
  },
  patternComponents: ['button', 'input'] as const,
}
</script>

<template>
  <LhConfigProvider
    :theme-vars="config.themeVars"
    :pattern-components="config.patternComponents"
  >
    <!-- Los botones y los campos aplican la textura; Dialog no -->
    <LhButton>Botón con patrón</LhButton>
    <LhInput placeholder="Campo con patrón" />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
export default {
  data() {
    return {
      config: {
        themeVars: {
          'bg-pattern': 'var(--lh-pattern-cloud)',
          'bg-pattern-opacity': '0.15',
        },
        patternComponents: ['button', 'input'],
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider
    :theme-vars="config.themeVars"
    :pattern-components="config.patternComponents"
  >
    <LhButton>Botón con patrón</LhButton>
  </LhConfigProvider>
</template>

Referencia de variables de patrón ​

VariableDescripciónPredeterminado
--lh-bg-patternURL del patrón de fondonone
--lh-bg-pattern-repeatModo de repetición en mosaicorepeat
--lh-bg-pattern-sizeTamaño del patrón40px
--lh-bg-pattern-opacityOpacidad del patrón0.15
--lh-bg-pattern-colorColor del patrónvar(--lh-decoration-color, rgba(184, 134, 11, 0.12))
--lh-bg-pattern-blendModo de mezclasoft-light

Ejemplo de configuración completa ​

A continuación se muestra el uso completo de la configuración de ConfigProvider, integrando todas las capacidades de tema, idioma, tamaño y patrón.

Composition API ​

vue
<script setup lang="ts">
import { zhCN } from '@lh-ui/vue3'

const configProvider = {
  size: 'medium' as const,
  locale: zhCN,
  themeVars: {
    'primary-color': '#2B4C7C',
    'bg-pattern': 'var(--lh-pattern-cloud)',
    'bg-pattern-opacity': '0.15',
  },
  patternComponents: ['button', 'input', 'dialog'],
}
</script>

<template>
  <LhConfigProvider
    :size="configProvider.size"
    :locale="configProvider.locale"
    :theme-vars="configProvider.themeVars"
    :pattern-components="configProvider.patternComponents"
  >
    <slot />
  </LhConfigProvider>
</template>

Options API ​

vue
<script>
import { zhCN } from '@lh-ui/vue3'

export default {
  data() {
    return {
      configProvider: {
        size: 'medium',
        locale: zhCN,
        themeVars: {
          'primary-color': '#2B4C7C',
          'bg-pattern': 'var(--lh-pattern-cloud)',
        },
        patternComponents: ['button', 'input', 'dialog'],
      },
    }
  },
}
</script>

<template>
  <LhConfigProvider
    :size="configProvider.size"
    :locale="configProvider.locale"
    :theme-vars="configProvider.themeVars"
    :pattern-components="configProvider.patternComponents"
  >
    <slot />
  </LhConfigProvider>
</template>

Prioridad de las variables de tema ​

Las variables CSS finales de un componente se fusionan según la siguiente prioridad (cada nivel sobrescribe al anterior):

  1. themeVars global de ConfigProvider (prioridad más baja)
  2. componentTheme[nombre del componente] de ConfigProvider
  3. La prop themeVars del propio componente
  4. La prop bgPattern del propio componente (prioridad más alta)

Para la variable bg-pattern existe además el control de la lista blanca patternComponents: solo los componentes de la lista blanca aplican el bg-pattern de la configuración global.

Diseño rápido con sx ​

La propiedad sx ofrece una forma declarativa de diseño en línea, que permite establecer los márgenes y el tamaño de los componentes sin escribir CSS. Actualmente está soportado en los siguientes componentes: Button, Input, Dialog, Tooltip, Alert, Card, Empty, Breadcrumb, Pagination, Steps, Tabs y Skeleton.

Principio ​

sx se basa en una retícula de referencia de 8px: el número se multiplica por 8 para obtener el valor en píxeles. Por ejemplo, mt: 2 equivale a marginTop: 16px.

Propiedades admitidas ​

Márgenes y rellenos ​

PropiedadDescripciónEjemploCSS equivalente
mMargen exterior en los cuatro ladosm: 2margin: 16px
mxMargen exterior horizontalmx: 1marginLeft: 8px; marginRight: 8px
myMargen exterior verticalmy: 1marginTop: 8px; marginBottom: 8px
mt, mr, mb, mlMargen exterior de un solo ladomt: 2marginTop: 16px
pRelleno interior en los cuatro ladosp: 3padding: 24px
pxRelleno interior horizontalpx: 2paddingLeft: 16px; paddingRight: 16px
pyRelleno interior verticalpy: 1paddingTop: 8px; paddingBottom: 8px
pt, pr, pb, plRelleno interior de un solo ladopt: 2paddingTop: 16px

Tamaño ​

PropiedadDescripciónEjemplo
wAncho (un número es px; una cadena es el valor en bruto)w: 200 o w: '100%'
hAltoh: 100 o h: 'auto'

Diseño Flex ​

PropiedadDescripciónEjemplo
displayTipo de visualizacióndisplay: 'flex'
flexAbreviatura de flexflex: '1 1 0%'
flexDirectionDirección del eje principalflexDirection: 'column'
alignItemsAlineación del eje transversalalignItems: 'center'
justifyContentAlineación del eje principaljustifyContent: 'flex-end'

Ejemplos de uso ​

vue
<script setup lang="ts">
import { ref } from 'vue'

const visible = ref(false)
</script>

<template>
  <!-- Márgenes del botón -->
  <LhButton type="primary" :sx="{ mt: 2, mx: 1 }">Botón con márgenes</LhButton>

  <!-- Margen exterior del campo -->
  <LhInput placeholder="Márgenes verticales del campo" :sx="{ my: 1 }" />

  <!-- Ancho del Dialog: sx solo admite w/h y propiedades de tipo layout -->
  <LhDialog v-model="visible" title="Ejemplo" :sx="{ w: 480 }">
    <p>Diálogo con ancho fijo</p>
  </LhDialog>
</template>
vue
<script>
export default {
  data() {
    return { visible: false }
  },
}
</script>

<template>
  <LhButton type="primary" :sx="{ mt: 2, mx: 1 }">Botón con márgenes</LhButton>
</template>

La belleza de la tradición, el cimiento del código