Files
Mplan 02d64bf206 chore: add naive-ui and web-design-reviewer skills
Add 12 Naive UI skill modules (components, dark mode, design tokens,
i18n, SSR, theming, quickstart) and web-design-reviewer skill.
2026-05-24 17:09:06 +08:00

6.6 KiB

name, description, metadata
name description metadata
naive-ui-theming Customize and apply themes in Naive UI including dark mode, theme variables, and creating themed components
author version
jiaiyan 1.0.0

Naive UI Theming

Learn how to customize themes, apply dark mode, and create themed components in Naive UI.

When to Use

Use this skill when you need to:

  • Implement dark/light mode switching
  • Customize theme colors and variables
  • Create themed components that respond to theme changes
  • Access theme variables in your components

Prerequisites

  • Basic understanding of Naive UI setup
  • Vue 3 Composition API knowledge
  • CSS custom properties (CSS variables) understanding

Basic Usage

Theme Switching

Use n-config-provider to control the theme of all descendant components:

<template>
  <n-config-provider :theme="theme">
    <n-card>
      <n-space>
        <n-button @click="theme = darkTheme">
          Dark
        </n-button>
        <n-button @click="theme = null">
          Light
        </n-button>
      </n-space>
    </n-card>
  </n-config-provider>
</template>

<script setup>
import { ref } from 'vue'
import { darkTheme } from 'naive-ui'

const theme = ref(null)
</script>

Using n-element for Theme-Aware Styling

The n-element component allows you to apply theme-aware styles using CSS variables:

<template>
  <n-space vertical>
    <n-space>
      <n-button @click="theme = darkTheme">Dark</n-button>
      <n-button @click="theme = null">Light</n-button>
    </n-space>
    <n-config-provider :theme="theme">
      <n-card>
        <n-el
          tag="span"
          style="
            color: var(--primary-color);
            transition: 0.3s var(--cubic-bezier-ease-in-out);
          "
        >
          I am a Span with theme-aware styling.
        </n-el>
      </n-card>
    </n-config-provider>
  </n-space>
</template>

<script setup>
import { ref } from 'vue'
import { darkTheme } from 'naive-ui'

const theme = ref(null)
</script>

Using Theme Variables with useThemeVars

Access theme variables programmatically using the useThemeVars composable:

<template>
  <div :style="{ color: themeVars.primaryColor }">
    Primary colored text
  </div>
  <pre style="overflow: auto">{{ themeVars }}</pre>
</template>

<script setup>
import { useThemeVars } from 'naive-ui'

const themeVars = useThemeVars()
</script>

API Reference

n-config-provider Theme Props

Property Type Default Description
theme object | null null Theme object (use darkTheme for dark mode, null for light)
theme-overrides object - Custom theme overrides

Available Theme Variables

Common theme variables accessible via useThemeVars():

Variable Description
primaryColor Primary color
primaryColorHover Primary color on hover
primaryColorPressed Primary color when pressed
successColor Success state color
warningColor Warning state color
errorColor Error state color
infoColor Info state color
textColorBase Base text color
textColor1 Primary text color
textColor2 Secondary text color
textColor3 Tertiary text color
borderColor Border color
borderRadius Border radius

n-element Props

Property Type Default Description
tag string 'div' HTML tag to render

Common Patterns

Persistent Theme with Local Storage

<template>
  <n-config-provider :theme="theme">
    <n-button @click="toggleTheme">
      Toggle Theme
    </n-button>
    <slot />
  </n-config-provider>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { darkTheme } from 'naive-ui'

const theme = ref(null)

const toggleTheme = () => {
  theme.value = theme.value ? null : darkTheme
  localStorage.setItem('theme', theme.value ? 'dark' : 'light')
}

onMounted(() => {
  const savedTheme = localStorage.getItem('theme')
  theme.value = savedTheme === 'dark' ? darkTheme : null
})
</script>

Custom Theme Overrides

<template>
  <n-config-provider :theme-overrides="themeOverrides">
    <App />
  </n-config-provider>
</template>

<script setup>
import { ref } from 'vue'

const themeOverrides = ref({
  common: {
    primaryColor: '#18a058',
    primaryColorHover: '#36ad6a',
    primaryColorPressed: '#0c7a43'
  },
  Button: {
    textColor: '#18a058'
  }
})
</script>

Theme-Aware Component

<template>
  <n-config-provider :theme="theme">
    <div :style="containerStyle">
      <n-card :style="cardStyle">
        <n-text :depth="1">
          Theme-aware content
        </n-text>
      </n-card>
    </div>
  </n-config-provider>
</template>

<script setup>
import { computed, ref } from 'vue'
import { darkTheme, useThemeVars } from 'naive-ui'

const theme = ref(null)
const themeVars = useThemeVars()

const containerStyle = computed(() => ({
  backgroundColor: themeVars.value.bodyColor,
  padding: '20px',
  transition: 'background-color 0.3s'
}))

const cardStyle = computed(() => ({
  borderColor: themeVars.value.borderColor
}))
</script>

Best Practices

  1. Use CSS Variables: Leverage CSS custom properties for smooth theme transitions
  2. Wrap at Root Level: Place n-config-provider at the top of your component tree
  3. Persist User Preference: Store theme preference in localStorage for better UX
  4. Test Both Themes: Always test your components in both light and dark modes
  5. Use Transitions: Add CSS transitions for smooth theme switching animations
  6. Override Selectively: Only override the theme variables you need to customize

CSS Variable Reference

Naive UI provides numerous CSS variables that automatically update with theme changes:

/* Common theme variables */
--primary-color
--primary-color-hover
--primary-color-pressed
--success-color
--warning-color
--error-color
--info-color

/* Text colors */
--text-color-base
--text-color-1
--text-color-2
--text-color-3

/* Background colors */
--body-color
--card-color
--modal-color

/* Border */
--border-color
--border-radius

/* Animation */
--cubic-bezier-ease-in-out
--cubic-bezier-ease-out
--cubic-bezier-ease-in

Use these variables in your styles for consistent theming:

<template>
  <div class="custom-component">
    Themed content
  </div>
</template>

<style scoped>
.custom-component {
  background-color: var(--card-color);
  border: 1px solid var(--border-color);
  color: var(--text-color-1);
  transition: all 0.3s var(--cubic-bezier-ease-in-out);
}
</style>