--- name: "naive-ui-dark-mode" description: "Dark mode implementation and theme switching for Naive UI applications. Invoke when user needs to implement dark/light theme switching, follow system preferences, or customize dark theme variables." metadata: author: jiaiyan version: "1.0.0" --- # Naive UI Dark Mode Naive UI provides built-in support for dark mode through the `n-config-provider` component. This skill covers implementing dark mode, following system preferences, and customizing dark theme variables. ## When to Use Use this skill when: - **Theme switching**: Implementing dark/light mode toggle - **System preference**: Following OS dark mode settings - **Dark theme customization**: Customizing dark theme variables - **Global dark styles**: Applying dark mode to the entire page - **Persistent dark mode**: Saving user theme preference ## When to Invoke Invoke this skill when: - User asks how to implement dark mode in Naive UI - User wants to toggle between light and dark themes - User needs to follow system dark mode preference - User wants to customize dark theme colors - User asks about applying dark mode globally - User encounters issues with dark mode styling ## Prerequisites - Naive UI installed (`npm install naive-ui`) - Vue 3 application setup - Basic understanding of `n-config-provider` ## API Reference ### Theme Objects | Theme | Import | Description | |-------|--------|-------------| | Light Theme | `import { lightTheme } from 'naive-ui'` | Default light theme (used when theme is `null`) | | Dark Theme | `import { darkTheme } from 'naive-ui'` | Built-in dark theme | ### Theme Prop Values | Value | Behavior | |-------|----------| | `undefined` | Inherits from parent `n-config-provider` | | `null` | Uses default light theme | | `darkTheme` | Applies dark theme | ### useOsTheme Hook ```ts import { useOsTheme } from 'naive-ui' const osTheme = useOsTheme() // Returns: Ref<'dark' | 'light' | 'no-preference' | 'unknown'> ``` ### useThemeVars Hook ```ts import { useThemeVars } from 'naive-ui' const themeVars = useThemeVars() // Returns: Reactive theme variables object ``` ## Basic Usage ### Simple Dark Mode Toggle ```vue ``` ### Follow System Theme Preference ```vue ``` ### Dark Mode with Global Styles ```vue ``` ## Common Patterns ### Persistent Dark Mode with localStorage ```vue ``` ### Dark Mode with Custom Theme Overrides ```vue ``` ### System Preference with Manual Override ```vue ``` ### Using Theme Variables ```vue ``` ### Nested Theme Configuration ```vue ``` ## Best Practices 1. **Use n-global-style**: Always include `` to apply theme to body ```vue ``` 2. **Persist user preference**: Save theme choice to localStorage ```js watch(isDark, (value) => { localStorage.setItem('theme', value ? 'dark' : 'light') }) ``` 3. **Provide system option**: Allow users to follow OS preference ```js import { useOsTheme } from 'naive-ui' const osTheme = useOsTheme() ``` 4. **Customize dark theme separately**: Use different overrides for light and dark ```js const themeOverrides = computed(() => isDark.value ? darkOverrides : lightOverrides ) ``` 5. **Use computed for reactivity**: Make theme reactive with computed properties ```js const theme = computed(() => isDark.value ? darkTheme : null) ``` 6. **Avoid flash of wrong theme**: Set theme before app mounts ```js const savedTheme = localStorage.getItem('theme') const isDark = ref(savedTheme === 'dark') ``` 7. **Test both themes**: Verify all components look correct in both modes 8. **Consider SSR**: Handle dark mode properly in server-side rendering ```vue ``` ## Common Dark Theme Variables ```ts const darkThemeOverrides = { common: { bodyColor: '#1c1c1e', cardColor: '#2c2c2e', modalColor: '#2c2c2e', popoverColor: '#2c2c2e', tableColor: '#2c2c2e', textColorBase: '#ffffff', textColor1: '#ffffff', textColor2: 'rgba(255, 255, 255, 0.82)', textColor3: 'rgba(255, 255, 255, 0.56)', primaryColor: '#63E2B7', primaryColorHover: '#7FE7C5', primaryColorPressed: '#5acea7', infoColor: '#70C0E8', successColor: '#63E2B7', warningColor: '#F2C97D', errorColor: '#E88080', borderColor: 'rgba(255, 255, 255, 0.12)', dividerColor: 'rgba(255, 255, 255, 0.12)' } } ``` ## Troubleshooting ### Body Background Not Changing **Problem**: Dark mode applies to components but body remains light **Solution**: Add `` inside `n-config-provider` ```vue ``` ### Flash of Light Theme on Load **Problem**: Page briefly shows light theme before switching to dark **Solution**: Load theme preference before app renders ```js const savedTheme = localStorage.getItem('theme') const isDark = ref(savedTheme === 'dark') ``` ### Theme Not Persisting **Problem**: Theme resets on page reload **Solution**: Watch and save theme changes ```js watch(isDark, (value) => { localStorage.setItem('theme', value ? 'dark' : 'light') }, { immediate: true }) ``` ## Related Skills - [n-config-provider](../components/n-config-provider/SKILL.md): Global configuration component - [n-global-style](../components/n-global-style/SKILL.md): Global style synchronization - [naive-ui-theming](../naive-ui-theming/SKILL.md): Theme customization guide - [naive-ui-ssr](../naive-ui-ssr/SKILL.md): SSR considerations for dark mode