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.
This commit is contained in:
@@ -0,0 +1,420 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-components"
|
||||||
|
description: "Comprehensive overview of all Naive UI components organized by category. Invoke when user needs to discover available components, understand component categories, or find the right component for their use case."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naive UI Components Overview
|
||||||
|
|
||||||
|
Naive UI is a Vue 3 component library with over 90 components. All components are tree-shakable, written in TypeScript, and fully themeable. This skill provides a comprehensive index of all available components organized by category.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this skill when:
|
||||||
|
- **Component discovery**: Finding the right component for a specific use case
|
||||||
|
- **Project planning**: Understanding available UI building blocks
|
||||||
|
- **Component selection**: Choosing between similar components
|
||||||
|
- **Learning Naive UI**: Getting an overview of the component library
|
||||||
|
- **Migration planning**: Understanding component equivalents from other libraries
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
Invoke this skill when:
|
||||||
|
- User asks what components are available in Naive UI
|
||||||
|
- User needs to find a component for a specific UI pattern
|
||||||
|
- User wants to understand component categories
|
||||||
|
- User is new to Naive UI and needs an overview
|
||||||
|
- User asks about component count or coverage
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Naive UI installed (`npm install naive-ui`)
|
||||||
|
- Vue 3 application setup
|
||||||
|
- Basic understanding of Vue 3 composition API
|
||||||
|
|
||||||
|
## Component Library Overview
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Total Components | 90+ |
|
||||||
|
| Tree-shakable | Yes |
|
||||||
|
| TypeScript | Full support |
|
||||||
|
| Theme System | Built-in CSS-in-JS |
|
||||||
|
| SSR Support | Yes |
|
||||||
|
|
||||||
|
## Component Categories
|
||||||
|
|
||||||
|
### 1. Common Components (18)
|
||||||
|
|
||||||
|
Basic UI elements used throughout applications.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Button | `n-button` | Buttons with various types and states | [n-button](../components/n-button/SKILL.md) |
|
||||||
|
| Button Group | `n-button-group` | Button group container | [n-button-group](../components/n-button-group/SKILL.md) |
|
||||||
|
| Icon | `n-icon` | Icon wrapper component | [n-icon](../components/n-icon/SKILL.md) |
|
||||||
|
| Icon Wrapper | `n-icon-wrapper` | Icon with background | [n-icon-wrapper](../components/n-icon-wrapper/SKILL.md) |
|
||||||
|
| Tag | `n-tag` | Tags and labels | [n-tag](../components/n-tag/SKILL.md) |
|
||||||
|
| Badge | `n-badge` | Badges and marks | [n-badge](../components/n-badge/SKILL.md) |
|
||||||
|
| Avatar | `n-avatar` | User avatars | [n-avatar](../components/n-avatar/SKILL.md) |
|
||||||
|
| Avatar Group | `n-avatar-group` | Avatar group display | [n-avatar-group](../components/n-avatar-group/SKILL.md) |
|
||||||
|
| Card | `n-card` | Card containers | [n-card](../components/n-card/SKILL.md) |
|
||||||
|
| Divider | `n-divider` | Dividing lines | [n-divider](../components/n-divider/SKILL.md) |
|
||||||
|
| Collapse | `n-collapse` | Collapsible panels | [n-collapse](../components/n-collapse/SKILL.md) |
|
||||||
|
| Collapse Transition | `n-collapse-transition` | Collapse animation | [n-collapse-transition](../components/n-collapse-transition/SKILL.md) |
|
||||||
|
| Ellipsis | `n-ellipsis` | Text ellipsis | [n-ellipsis](../components/n-ellipsis/SKILL.md) |
|
||||||
|
| Typography | `n-typography` | Typography components | [n-typography](../components/n-typography/SKILL.md) |
|
||||||
|
| Gradient Text | `n-gradient-text` | Gradient text effect | [n-gradient-text](../components/n-gradient-text/SKILL.md) |
|
||||||
|
| Thing | `n-thing` | Thing container | [n-thing](../components/n-thing/SKILL.md) |
|
||||||
|
| Element | `n-element` | Element wrapper | [n-element](../components/n-element/SKILL.md) |
|
||||||
|
| Code | `n-code` | Code display | [n-code](../components/n-code/SKILL.md) |
|
||||||
|
|
||||||
|
### 2. Data Input Components (26)
|
||||||
|
|
||||||
|
Form controls and input components.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Input | `n-input` | Text input | [n-input](../components/n-input/SKILL.md) |
|
||||||
|
| Input Number | `n-input-number` | Number input | [n-input-number](../components/n-input-number/SKILL.md) |
|
||||||
|
| Input OTP | `n-input-otp` | OTP input | [n-input-otp](../components/n-input-otp/SKILL.md) |
|
||||||
|
| Auto Complete | `n-auto-complete` | Input with suggestions | [n-auto-complete](../components/n-auto-complete/SKILL.md) |
|
||||||
|
| Select | `n-select` | Dropdown select | [n-select](../components/n-select/SKILL.md) |
|
||||||
|
| Tree Select | `n-tree-select` | Tree select | [n-tree-select](../components/n-tree-select/SKILL.md) |
|
||||||
|
| Cascader | `n-cascader` | Cascading selection | [n-cascader](../components/n-cascader/SKILL.md) |
|
||||||
|
| Checkbox | `n-checkbox` | Checkboxes | [n-checkbox](../components/n-checkbox/SKILL.md) |
|
||||||
|
| Radio | `n-radio` | Radio buttons | [n-radio](../components/n-radio/SKILL.md) |
|
||||||
|
| Switch | `n-switch` | Toggle switch | [n-switch](../components/n-switch/SKILL.md) |
|
||||||
|
| Slider | `n-slider` | Slider input | [n-slider](../components/n-slider/SKILL.md) |
|
||||||
|
| Rate | `n-rate` | Star rating | [n-rate](../components/n-rate/SKILL.md) |
|
||||||
|
| Color Picker | `n-color-picker` | Color picker | [n-color-picker](../components/n-color-picker/SKILL.md) |
|
||||||
|
| Date Picker | `n-date-picker` | Date picker | [n-date-picker](../components/n-date-picker/SKILL.md) |
|
||||||
|
| Time Picker | `n-time-picker` | Time picker | [n-time-picker](../components/n-time-picker/SKILL.md) |
|
||||||
|
| Form | `n-form` | Form management | [n-form](../components/n-form/SKILL.md) |
|
||||||
|
| Dynamic Input | `n-dynamic-input` | Dynamic input fields | [n-dynamic-input](../components/n-dynamic-input/SKILL.md) |
|
||||||
|
| Dynamic Tags | `n-dynamic-tags` | Dynamic tags input | [n-dynamic-tags](../components/n-dynamic-tags/SKILL.md) |
|
||||||
|
| Mention | `n-mention` | Mention input | [n-mention](../components/n-mention/SKILL.md) |
|
||||||
|
| Transfer | `n-transfer` | Transfer panels | [n-transfer](../components/n-transfer/SKILL.md) |
|
||||||
|
| Upload | `n-upload` | File upload | [n-upload](../components/n-upload/SKILL.md) |
|
||||||
|
| QR Code | `n-qr-code` | QR code generator | [n-qr-code](../components/n-qr-code/SKILL.md) |
|
||||||
|
| Float Button | `n-float-button` | Floating button | [n-float-button](../components/n-float-button/SKILL.md) |
|
||||||
|
| Float Button Group | `n-float-button-group` | Floating button group | [n-float-button-group](../components/n-float-button-group/SKILL.md) |
|
||||||
|
|
||||||
|
### 3. Data Display Components (20)
|
||||||
|
|
||||||
|
Components for presenting data.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| DataTable | `n-data-table` | Advanced data table | [n-data-table](../components/n-data-table/SKILL.md) |
|
||||||
|
| Table | `n-table` | Basic table | [n-table](../components/n-table/SKILL.md) |
|
||||||
|
| Tree | `n-tree` | Tree view | [n-tree](../components/n-tree/SKILL.md) |
|
||||||
|
| List | `n-list` | List container | [n-list](../components/n-list/SKILL.md) |
|
||||||
|
| Descriptions | `n-descriptions` | Description list | [n-descriptions](../components/n-descriptions/SKILL.md) |
|
||||||
|
| Statistic | `n-statistic` | Statistics display | [n-statistic](../components/n-statistic/SKILL.md) |
|
||||||
|
| Number Animation | `n-number-animation` | Animated numbers | [n-number-animation](../components/n-number-animation/SKILL.md) |
|
||||||
|
| Countdown | `n-countdown` | Countdown timer | [n-countdown](../components/n-countdown/SKILL.md) |
|
||||||
|
| Time | `n-time` | Time display | [n-time](../components/n-time/SKILL.md) |
|
||||||
|
| Timeline | `n-timeline` | Timeline display | [n-timeline](../components/n-timeline/SKILL.md) |
|
||||||
|
| Calendar | `n-calendar` | Calendar view | [n-calendar](../components/n-calendar/SKILL.md) |
|
||||||
|
| Image | `n-image` | Image with preview | [n-image](../components/n-image/SKILL.md) |
|
||||||
|
| Empty | `n-empty` | Empty state | [n-empty](../components/n-empty/SKILL.md) |
|
||||||
|
| Result | `n-result` | Result page | [n-result](../components/n-result/SKILL.md) |
|
||||||
|
| Skeleton | `n-skeleton` | Loading skeleton | [n-skeleton](../components/n-skeleton/SKILL.md) |
|
||||||
|
| Progress | `n-progress` | Progress bar | [n-progress](../components/n-progress/SKILL.md) |
|
||||||
|
| Spin | `n-spin` | Loading spinner | [n-spin](../components/n-spin/SKILL.md) |
|
||||||
|
| Log | `n-log` | Log display | [n-log](../components/n-log/SKILL.md) |
|
||||||
|
| Heatmap | `n-heatmap` | Heatmap visualization | [n-heatmap](../components/n-heatmap/SKILL.md) |
|
||||||
|
| Equation | `n-equation` | Math equation | [n-equation](../components/n-equation/SKILL.md) |
|
||||||
|
|
||||||
|
### 4. Navigation Components (12)
|
||||||
|
|
||||||
|
Navigation and wayfinding components.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Menu | `n-menu` | Navigation menu | [n-menu](../components/n-menu/SKILL.md) |
|
||||||
|
| Tabs | `n-tabs` | Tabs | [n-tabs](../components/n-tabs/SKILL.md) |
|
||||||
|
| Breadcrumb | `n-breadcrumb` | Breadcrumb navigation | [n-breadcrumb](../components/n-breadcrumb/SKILL.md) |
|
||||||
|
| Anchor | `n-anchor` | Anchor navigation | [n-anchor](../components/n-anchor/SKILL.md) |
|
||||||
|
| Dropdown | `n-dropdown` | Dropdown menu | [n-dropdown](../components/n-dropdown/SKILL.md) |
|
||||||
|
| Popselect | `n-popselect` | Popover select | [n-popselect](../components/n-popselect/SKILL.md) |
|
||||||
|
| Steps | `n-steps` | Steps guide | [n-steps](../components/n-steps/SKILL.md) |
|
||||||
|
| Pagination | `n-pagination` | Pagination | [n-pagination](../components/n-pagination/SKILL.md) |
|
||||||
|
| Affix | `n-affix` | Sticky positioning | [n-affix](../components/n-affix/SKILL.md) |
|
||||||
|
| Back Top | `n-back-top` | Back to top button | [n-back-top](../components/n-back-top/SKILL.md) |
|
||||||
|
| Page Header | `n-page-header` | Page header | [n-page-header](../components/n-page-header/SKILL.md) |
|
||||||
|
|
||||||
|
### 5. Feedback Components (11)
|
||||||
|
|
||||||
|
User feedback and notification components.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Dialog | `n-dialog` | Modal dialog | [n-dialog](../components/n-dialog/SKILL.md) |
|
||||||
|
| Modal | `n-modal` | Modal container | [n-modal](../components/n-modal/SKILL.md) |
|
||||||
|
| Drawer | `n-drawer` | Drawer panel | [n-drawer](../components/n-drawer/SKILL.md) |
|
||||||
|
| Message | `n-message` | Toast message | [n-message](../components/n-message/SKILL.md) |
|
||||||
|
| Notification | `n-notification` | Notification | [n-notification](../components/n-notification/SKILL.md) |
|
||||||
|
| Popconfirm | `n-popconfirm` | Popconfirm | [n-popconfirm](../components/n-popconfirm/SKILL.md) |
|
||||||
|
| Popover | `n-popover` | Popover | [n-popover](../components/n-popover/SKILL.md) |
|
||||||
|
| Tooltip | `n-tooltip` | Tooltip | [n-tooltip](../components/n-tooltip/SKILL.md) |
|
||||||
|
| Alert | `n-alert` | Alert messages | [n-alert](../components/n-alert/SKILL.md) |
|
||||||
|
| Loading Bar | `n-loading-bar` | Loading bar | [n-loading-bar](../components/n-loading-bar/SKILL.md) |
|
||||||
|
| Discrete | `n-discrete` | Discrete API | [n-discrete](../components/n-discrete/SKILL.md) |
|
||||||
|
|
||||||
|
### 6. Layout Components (9)
|
||||||
|
|
||||||
|
Page structure and layout components.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Layout | `n-layout` | Layout container | [n-layout](../components/n-layout/SKILL.md) |
|
||||||
|
| Grid | `n-grid` | Grid system | [n-grid](../components/n-grid/SKILL.md) |
|
||||||
|
| Legacy Grid | `n-legacy-grid` | Legacy grid | [n-legacy-grid](../components/n-legacy-grid/SKILL.md) |
|
||||||
|
| Flex | `n-flex` | Flex container | [n-flex](../components/n-flex/SKILL.md) |
|
||||||
|
| Space | `n-space` | Spacing | [n-space](../components/n-space/SKILL.md) |
|
||||||
|
| Split | `n-split` | Split panels | [n-split](../components/n-split/SKILL.md) |
|
||||||
|
| Carousel | `n-carousel` | Image carousel | [n-carousel](../components/n-carousel/SKILL.md) |
|
||||||
|
| Marquee | `n-marquee` | Marquee animation | [n-marquee](../components/n-marquee/SKILL.md) |
|
||||||
|
|
||||||
|
### 7. Utility Components (8)
|
||||||
|
|
||||||
|
Helper and configuration components.
|
||||||
|
|
||||||
|
| Component | Tag | Description | Skill Path |
|
||||||
|
|-----------|-----|-------------|------------|
|
||||||
|
| Config Provider | `n-config-provider` | Global config | [n-config-provider](../components/n-config-provider/SKILL.md) |
|
||||||
|
| Scrollbar | `n-scrollbar` | Custom scrollbar | [n-scrollbar](../components/n-scrollbar/SKILL.md) |
|
||||||
|
| Virtual List | `n-virtual-list` | Virtual scroll list | [n-virtual-list](../components/n-virtual-list/SKILL.md) |
|
||||||
|
| Infinite Scroll | `n-infinite-scroll` | Infinite scroll | [n-infinite-scroll](../components/n-infinite-scroll/SKILL.md) |
|
||||||
|
| Watermark | `n-watermark` | Watermark | [n-watermark](../components/n-watermark/SKILL.md) |
|
||||||
|
| Global Style | `n-global-style` | Global styles | [n-global-style](../components/n-global-style/SKILL.md) |
|
||||||
|
| Highlight | `n-highlight` | Code highlight | [n-highlight](../components/n-highlight/SKILL.md) |
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Importing Components
|
||||||
|
|
||||||
|
Naive UI supports both global and on-demand imports:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Global import
|
||||||
|
import naive from 'naive-ui'
|
||||||
|
app.use(naive)
|
||||||
|
|
||||||
|
// On-demand import (tree-shakable)
|
||||||
|
import { NButton, NInput, NCard } from 'naive-ui'
|
||||||
|
|
||||||
|
app.component('NButton', NButton)
|
||||||
|
app.component('NInput', NInput)
|
||||||
|
app.component('NCard', NCard)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Components in Templates
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-space vertical>
|
||||||
|
<n-card title="Welcome">
|
||||||
|
<n-input v-model:value="text" placeholder="Type something" />
|
||||||
|
<n-button type="primary" @click="handleClick">
|
||||||
|
Submit
|
||||||
|
</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const text = ref('')
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
console.log(text.value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Form with Validation
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-form ref="formRef" :model="model" :rules="rules">
|
||||||
|
<n-form-item label="Name" path="name">
|
||||||
|
<n-input v-model:value="model.name" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="Email" path="email">
|
||||||
|
<n-input v-model:value="model.email" />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item>
|
||||||
|
<n-button type="primary" @click="submit">Submit</n-button>
|
||||||
|
</n-form-item>
|
||||||
|
</n-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
|
||||||
|
const formRef = ref()
|
||||||
|
const model = reactive({ name: '', email: '' })
|
||||||
|
const rules = {
|
||||||
|
name: [{ required: true, message: 'Name required' }],
|
||||||
|
email: [{ required: true, type: 'email', message: 'Valid email required' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Table with Actions
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-data-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="data"
|
||||||
|
:pagination="pagination"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { NButton, useMessage } from 'naive-ui'
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{ title: 'Name', key: 'name' },
|
||||||
|
{ title: 'Age', key: 'age' },
|
||||||
|
{
|
||||||
|
title: 'Actions',
|
||||||
|
key: 'actions',
|
||||||
|
render(row) {
|
||||||
|
return h(NButton, {
|
||||||
|
size: 'small',
|
||||||
|
onClick: () => message.info(`Edit ${row.name}`)
|
||||||
|
}, { default: () => 'Edit' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ name: 'John', age: 30 },
|
||||||
|
{ name: 'Jane', age: 25 }
|
||||||
|
]
|
||||||
|
|
||||||
|
const pagination = { pageSize: 10 }
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modal Dialog
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-button @click="showModal = true">Open Modal</n-button>
|
||||||
|
|
||||||
|
<n-modal v-model:show="showModal" preset="dialog" title="Confirm">
|
||||||
|
<p>Are you sure you want to proceed?</p>
|
||||||
|
<template #action>
|
||||||
|
<n-button @click="showModal = false">Cancel</n-button>
|
||||||
|
<n-button type="primary" @click="confirm">Confirm</n-button>
|
||||||
|
</template>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const showModal = ref(false)
|
||||||
|
|
||||||
|
const confirm = () => {
|
||||||
|
showModal.value = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Component Selection Guide
|
||||||
|
|
||||||
|
### When to Use Which Component
|
||||||
|
|
||||||
|
| Use Case | Recommended Component |
|
||||||
|
|----------|----------------------|
|
||||||
|
| Primary action | `n-button` with `type="primary"` |
|
||||||
|
| Text input | `n-input` |
|
||||||
|
| Selection from list | `n-select` |
|
||||||
|
| Boolean toggle | `n-switch` or `n-checkbox` |
|
||||||
|
| Date selection | `n-date-picker` |
|
||||||
|
| Form layout | `n-form` with `n-form-item` |
|
||||||
|
| Data grid | `n-data-table` |
|
||||||
|
| Navigation | `n-menu` or `n-tabs` |
|
||||||
|
| Modal content | `n-modal` or `n-dialog` |
|
||||||
|
| User feedback | `n-message` or `n-notification` |
|
||||||
|
| Page layout | `n-layout` with `n-layout-header`, `n-layout-content` |
|
||||||
|
| Card container | `n-card` |
|
||||||
|
| Loading state | `n-spin` or `n-skeleton` |
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use on-demand imports**: Import only needed components for smaller bundles
|
||||||
|
```ts
|
||||||
|
import { NButton, NInput } from 'naive-ui'
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Wrap app with n-config-provider**: Configure theme, locale, and defaults globally
|
||||||
|
```vue
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Use n-global-style with themes**: Sync global styles when using dark mode
|
||||||
|
```vue
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Leverage provider components**: Use message, dialog, notification providers
|
||||||
|
```vue
|
||||||
|
<n-message-provider>
|
||||||
|
<n-dialog-provider>
|
||||||
|
<n-notification-provider>
|
||||||
|
<App />
|
||||||
|
</n-notification-provider>
|
||||||
|
</n-dialog-provider>
|
||||||
|
</n-message-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Use TypeScript**: Take advantage of full type definitions
|
||||||
|
```ts
|
||||||
|
import type { DataTableColumns, FormRules } from 'naive-ui'
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Follow naming conventions**: Use `n-` prefix in templates
|
||||||
|
```vue
|
||||||
|
<n-button>Click</n-button>
|
||||||
|
```
|
||||||
|
|
||||||
|
7. **Use composition API**: Components work best with Vue 3 composition API
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
const value = ref('')
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- [naive-ui-quickstart](../naive-ui-quickstart/SKILL.md): Installation and setup
|
||||||
|
- [naive-ui-theming](../naive-ui-theming/SKILL.md): Theme customization
|
||||||
|
- [naive-ui-dark-mode](../naive-ui-dark-mode/SKILL.md): Dark mode implementation
|
||||||
|
- [naive-ui-ssr](../naive-ui-ssr/SKILL.md): Server-side rendering
|
||||||
|
- [n-config-provider](../components/n-config-provider/SKILL.md): Global configuration
|
||||||
@@ -0,0 +1,440 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-space vertical>
|
||||||
|
<n-space>
|
||||||
|
<n-button @click="theme = darkTheme">Dark Mode</n-button>
|
||||||
|
<n-button @click="theme = null">Light Mode</n-button>
|
||||||
|
</n-space>
|
||||||
|
<n-card title="Theme Demo">
|
||||||
|
<n-button type="primary">Primary Button</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const theme = ref(null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Follow System Theme Preference
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-card>
|
||||||
|
<p>Current system theme: {{ osTheme }}</p>
|
||||||
|
<n-button type="primary">
|
||||||
|
Button adapts to system theme
|
||||||
|
</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useOsTheme, darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const osTheme = useOsTheme()
|
||||||
|
|
||||||
|
const theme = computed(() => {
|
||||||
|
return osTheme.value === 'dark' ? darkTheme : null
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dark Mode with Global Styles
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<n-space vertical>
|
||||||
|
<n-switch v-model:value="isDark">
|
||||||
|
<template #checked>Dark</template>
|
||||||
|
<template #unchecked>Light</template>
|
||||||
|
</n-switch>
|
||||||
|
<n-card title="Global Dark Mode">
|
||||||
|
<p>Body background also changes!</p>
|
||||||
|
</n-card>
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const isDark = ref(false)
|
||||||
|
|
||||||
|
const theme = computed(() => isDark.value ? darkTheme : null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Persistent Dark Mode with localStorage
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<n-space vertical>
|
||||||
|
<n-switch v-model:value="isDark">
|
||||||
|
<template #checked>Dark</template>
|
||||||
|
<template #unchecked>Light</template>
|
||||||
|
</n-switch>
|
||||||
|
<router-view />
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'naive-ui-theme'
|
||||||
|
|
||||||
|
const savedTheme = localStorage.getItem(STORAGE_KEY)
|
||||||
|
const isDark = ref(savedTheme === 'dark')
|
||||||
|
|
||||||
|
const theme = computed(() => isDark.value ? darkTheme : null)
|
||||||
|
|
||||||
|
watch(isDark, (value) => {
|
||||||
|
localStorage.setItem(STORAGE_KEY, value ? 'dark' : 'light')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dark Mode with Custom Theme Overrides
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider
|
||||||
|
:theme="theme"
|
||||||
|
:theme-overrides="themeOverrides"
|
||||||
|
>
|
||||||
|
<n-global-style />
|
||||||
|
<n-space vertical>
|
||||||
|
<n-switch v-model:value="isDark" />
|
||||||
|
<n-card title="Custom Dark Theme">
|
||||||
|
<n-button type="primary">Custom Primary Color</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const isDark = ref(false)
|
||||||
|
|
||||||
|
const theme = computed(() => isDark.value ? darkTheme : null)
|
||||||
|
|
||||||
|
const lightThemeOverrides = {
|
||||||
|
common: {
|
||||||
|
primaryColor: '#18A058'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const darkThemeOverrides = {
|
||||||
|
common: {
|
||||||
|
primaryColor: '#63E2B7',
|
||||||
|
primaryColorHover: '#7FE7C5',
|
||||||
|
primaryColorPressed: '#5acea7'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const themeOverrides = computed(() => {
|
||||||
|
return isDark.value ? darkThemeOverrides : lightThemeOverrides
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Preference with Manual Override
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<n-space vertical>
|
||||||
|
<n-radio-group v-model:value="themeMode">
|
||||||
|
<n-radio-button value="light">Light</n-radio-button>
|
||||||
|
<n-radio-button value="dark">Dark</n-radio-button>
|
||||||
|
<n-radio-button value="system">System</n-radio-button>
|
||||||
|
</n-radio-group>
|
||||||
|
<n-card>
|
||||||
|
<n-button type="primary">Theme Button</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { useOsTheme, darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'theme-mode'
|
||||||
|
|
||||||
|
const osTheme = useOsTheme()
|
||||||
|
const savedMode = localStorage.getItem(STORAGE_KEY) || 'system'
|
||||||
|
const themeMode = ref(savedMode)
|
||||||
|
|
||||||
|
const theme = computed(() => {
|
||||||
|
if (themeMode.value === 'dark') {
|
||||||
|
return darkTheme
|
||||||
|
}
|
||||||
|
if (themeMode.value === 'light') {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return osTheme.value === 'dark' ? darkTheme : null
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(themeMode, (value) => {
|
||||||
|
localStorage.setItem(STORAGE_KEY, value)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Theme Variables
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-card :style="{ backgroundColor: themeVars.bodyColor }">
|
||||||
|
<p :style="{ color: themeVars.textColorBase }">
|
||||||
|
Current primary color: {{ themeVars.primaryColor }}
|
||||||
|
</p>
|
||||||
|
<n-button type="primary">Primary</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { darkTheme, useThemeVars } from 'naive-ui'
|
||||||
|
|
||||||
|
const theme = ref(null)
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nested Theme Configuration
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="darkTheme">
|
||||||
|
<n-card title="Dark Theme Area">
|
||||||
|
<n-config-provider :theme="null">
|
||||||
|
<n-card title="Light Theme Nested Area">
|
||||||
|
<n-button type="primary">Light Button</n-button>
|
||||||
|
</n-card>
|
||||||
|
</n-config-provider>
|
||||||
|
</n-card>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use n-global-style**: Always include `<n-global-style />` to apply theme to body
|
||||||
|
```vue
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
<n-config-provider :theme="isDark ? darkTheme : null">
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 `<n-global-style />` inside `n-config-provider`
|
||||||
|
```vue
|
||||||
|
<n-config-provider :theme="theme">
|
||||||
|
<n-global-style />
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-design-border"
|
||||||
|
description: "Border design specifications for Naive UI components. Invoke when user needs to understand border styles, radius options, or shadow styles used throughout Naive UI."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Border Design Specifications
|
||||||
|
|
||||||
|
Naive UI standardizes borders used in buttons, cards, pop-ups, and other components for consistent visual design.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Understanding border style options
|
||||||
|
- Applying consistent radius styles
|
||||||
|
- Using shadow styles for depth
|
||||||
|
- Maintaining design consistency
|
||||||
|
- Creating themed components with proper borders
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Border Radius
|
||||||
|
|
||||||
|
Naive UI provides standardized border radius values for consistent rounded corners.
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--border-radius` | `3px` | Base radius for components |
|
||||||
|
| `--border-radius-small` | `2px` | Small radius for buttons, tags |
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :style="{ borderRadius: themeVars.borderRadius }">
|
||||||
|
Base radius element
|
||||||
|
</div>
|
||||||
|
<div :style="{ borderRadius: themeVars.borderRadiusSmall }">
|
||||||
|
Small radius element
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### In CSS with n-element
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-el
|
||||||
|
tag="div"
|
||||||
|
style="
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Rounded container
|
||||||
|
</n-el>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Border Colors
|
||||||
|
|
||||||
|
Naive UI uses semantic border colors that adapt to light and dark themes.
|
||||||
|
|
||||||
|
### Light Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--border-color` | `rgb(224, 224, 230)` | Default border color |
|
||||||
|
| `--divider-color` | `rgb(239, 239, 245)` | Divider lines |
|
||||||
|
|
||||||
|
### Dark Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--border-color` | `rgba(255, 255, 255, 0.24)` | Default border color |
|
||||||
|
| `--divider-color` | `rgba(255, 255, 255, 0.09)` | Divider lines |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Box Shadows
|
||||||
|
|
||||||
|
Naive UI provides three levels of shadow styles for depth and elevation.
|
||||||
|
|
||||||
|
| CSS Variable | Usage |
|
||||||
|
|--------------|-------|
|
||||||
|
| `--box-shadow-1` | Light shadow for cards, dropdowns |
|
||||||
|
| `--box-shadow-2` | Medium shadow for popovers, modals |
|
||||||
|
| `--box-shadow-3` | Heavy shadow for dialogs, overlays |
|
||||||
|
|
||||||
|
### Shadow Values
|
||||||
|
|
||||||
|
#### Light Theme
|
||||||
|
|
||||||
|
```css
|
||||||
|
--box-shadow-1: 0 1px 2px -2px rgba(0, 0, 0, .08),
|
||||||
|
0 3px 6px 0 rgba(0, 0, 0, .06),
|
||||||
|
0 5px 12px 4px rgba(0, 0, 0, .04);
|
||||||
|
|
||||||
|
--box-shadow-2: 0 3px 6px -4px rgba(0, 0, 0, .12),
|
||||||
|
0 6px 16px 0 rgba(0, 0, 0, .08),
|
||||||
|
0 9px 28px 8px rgba(0, 0, 0, .05);
|
||||||
|
|
||||||
|
--box-shadow-3: 0 6px 16px -9px rgba(0, 0, 0, .08),
|
||||||
|
0 9px 28px 0 rgba(0, 0, 0, .05),
|
||||||
|
0 12px 48px 16px rgba(0, 0, 0, .03);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Dark Theme
|
||||||
|
|
||||||
|
```css
|
||||||
|
--box-shadow-1: 0 1px 2px -2px rgba(0, 0, 0, .24),
|
||||||
|
0 3px 6px 0 rgba(0, 0, 0, .18),
|
||||||
|
0 5px 12px 4px rgba(0, 0, 0, .12);
|
||||||
|
|
||||||
|
--box-shadow-2: 0 3px 6px -4px rgba(0, 0, 0, .24),
|
||||||
|
0 6px 12px 0 rgba(0, 0, 0, .16),
|
||||||
|
0 9px 18px 8px rgba(0, 0, 0, .10);
|
||||||
|
|
||||||
|
--box-shadow-3: 0 6px 16px -9px rgba(0, 0, 0, .08),
|
||||||
|
0 9px 28px 0 rgba(0, 0, 0, .05),
|
||||||
|
0 12px 48px 16px rgba(0, 0, 0, .03);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :style="{ boxShadow: themeVars.boxShadow1 }">
|
||||||
|
Light elevation
|
||||||
|
</div>
|
||||||
|
<div :style="{ boxShadow: themeVars.boxShadow2 }">
|
||||||
|
Medium elevation
|
||||||
|
</div>
|
||||||
|
<div :style="{ boxShadow: themeVars.boxShadow3 }">
|
||||||
|
Heavy elevation
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scrollbar Styles
|
||||||
|
|
||||||
|
Naive UI provides customizable scrollbar styles.
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--scrollbar-color` | Light: `rgba(0, 0, 0, 0.25)` | Scrollbar thumb color |
|
||||||
|
| `--scrollbar-color-hover` | Light: `rgba(0, 0, 0, 0.4)` | Scrollbar thumb hover |
|
||||||
|
| `--scrollbar-width` | `5px` | Scrollbar width |
|
||||||
|
| `--scrollbar-height` | `5px` | Scrollbar height |
|
||||||
|
| `--scrollbar-border-radius` | `5px` | Scrollbar thumb radius |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Variables Summary
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--border-radius: 3px;
|
||||||
|
--border-radius-small: 2px;
|
||||||
|
|
||||||
|
--border-color: rgb(224, 224, 230);
|
||||||
|
--divider-color: rgb(239, 239, 245);
|
||||||
|
|
||||||
|
--box-shadow-1: 0 1px 2px -2px rgba(0, 0, 0, .08),
|
||||||
|
0 3px 6px 0 rgba(0, 0, 0, .06),
|
||||||
|
0 5px 12px 4px rgba(0, 0, 0, .04);
|
||||||
|
--box-shadow-2: 0 3px 6px -4px rgba(0, 0, 0, .12),
|
||||||
|
0 6px 16px 0 rgba(0, 0, 0, .08),
|
||||||
|
0 9px 28px 8px rgba(0, 0, 0, .05);
|
||||||
|
--box-shadow-3: 0 6px 16px -9px rgba(0, 0, 0, .08),
|
||||||
|
0 9px 28px 0 rgba(0, 0, 0, .05),
|
||||||
|
0 12px 48px 16px rgba(0, 0, 0, .03);
|
||||||
|
|
||||||
|
--scrollbar-width: 5px;
|
||||||
|
--scrollbar-height: 5px;
|
||||||
|
--scrollbar-border-radius: 5px;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Transition Timing
|
||||||
|
|
||||||
|
Naive UI uses standardized cubic-bezier timing functions for smooth transitions.
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--cubic-bezier-ease-in-out` | `cubic-bezier(.4, 0, .2, 1)` | General transitions |
|
||||||
|
| `--cubic-bezier-ease-out` | `cubic-bezier(0, 0, .2, 1)` | Enter animations |
|
||||||
|
| `--cubic-bezier-ease-in` | `cubic-bezier(.4, 0, 1, 1)` | Exit animations |
|
||||||
|
|
||||||
|
### Usage Example
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-el
|
||||||
|
tag="div"
|
||||||
|
style="
|
||||||
|
transition: all 0.3s var(--cubic-bezier-ease-in-out);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Smooth transition element
|
||||||
|
</n-el>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use CSS Variables**: Always use predefined CSS variables for consistency
|
||||||
|
2. **Match Context**: Choose appropriate shadow depth based on element importance
|
||||||
|
3. **Dark Mode**: Border and shadow colors automatically adjust in dark mode
|
||||||
|
4. **Consistent Radius**: Use `--border-radius` for most components, `--border-radius-small` for compact elements
|
||||||
|
5. **Smooth Transitions**: Use the provided cubic-bezier functions for consistent animation feel
|
||||||
|
6. **Accessibility**: Ensure sufficient contrast for borders in both themes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
| Resource | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| [useThemeVars](https://www.naiveui.com/en-US/os-theme/docs/theme) | Access theme variables in JavaScript |
|
||||||
|
| [n-element](https://www.naiveui.com/en-US/os-theme/components/element) | Use CSS variables in templates |
|
||||||
|
| [Color Design](./naive-ui-design-color/SKILL.md) | Color specifications |
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-design-color"
|
||||||
|
description: "Color design specifications for Naive UI. Invoke when user needs to understand the color palette, main colors, semantic colors, or neutral colors used in Naive UI."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Color Design Specifications
|
||||||
|
|
||||||
|
Naive UI uses a carefully designed color system with primary green color and semantic colors for different states, providing a consistent look and feel for the products you build.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Understanding the color system
|
||||||
|
- Applying brand colors correctly
|
||||||
|
- Using semantic colors (success, warning, error, info)
|
||||||
|
- Working with neutral colors for text and backgrounds
|
||||||
|
- Creating themed components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Primary Color
|
||||||
|
|
||||||
|
The main color of Naive UI is a vibrant green (#18a058) that conveys freshness and growth.
|
||||||
|
|
||||||
|
| Color | CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|-------|--------------|-------------|------------|-------|
|
||||||
|
| Primary | `--primary-color` | `#18a058` | `#63e2b7` | Main brand color |
|
||||||
|
| Primary Hover | `--primary-color-hover` | `#36ad6a` | `#7fe7c4` | Hover state |
|
||||||
|
| Primary Pressed | `--primary-color-pressed` | `#0c7a43` | `#5acea7` | Active/pressed state |
|
||||||
|
| Primary Suppl | `--primary-color-suppl` | `#36ad6a` | `rgb(42, 148, 125)` | Supplementary |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Semantic Colors
|
||||||
|
|
||||||
|
Semantic colors are used in different scenarios to convey meaning.
|
||||||
|
|
||||||
|
### Success
|
||||||
|
|
||||||
|
| CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|--------------|-------------|------------|-------|
|
||||||
|
| `--success-color` | `#18a058` | `#63e2b7` | Success operations |
|
||||||
|
| `--success-color-hover` | `#36ad6a` | `#7fe7c4` | Hover state |
|
||||||
|
| `--success-color-pressed` | `#0c7a43` | `#5acea7` | Active state |
|
||||||
|
| `--success-color-suppl` | `#36ad6a` | `rgb(42, 148, 125)` | Supplementary |
|
||||||
|
|
||||||
|
### Info
|
||||||
|
|
||||||
|
| CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|--------------|-------------|------------|-------|
|
||||||
|
| `--info-color` | `#2080f0` | `#70c0e8` | Information operations |
|
||||||
|
| `--info-color-hover` | `#4098fc` | `#8acbec` | Hover state |
|
||||||
|
| `--info-color-pressed` | `#1060c9` | `#66afd3` | Active state |
|
||||||
|
| `--info-color-suppl` | `#4098fc` | `rgb(56, 137, 197)` | Supplementary |
|
||||||
|
|
||||||
|
### Warning
|
||||||
|
|
||||||
|
| CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|--------------|-------------|------------|-------|
|
||||||
|
| `--warning-color` | `#f0a020` | `#f2c97d` | Warning operations |
|
||||||
|
| `--warning-color-hover` | `#fcb040` | `#f5d599` | Hover state |
|
||||||
|
| `--warning-color-pressed` | `#c97c10` | `#e6c260` | Active state |
|
||||||
|
| `--warning-color-suppl` | `#fcb040` | `rgb(240, 138, 0)` | Supplementary |
|
||||||
|
|
||||||
|
### Error
|
||||||
|
|
||||||
|
| CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|--------------|-------------|------------|-------|
|
||||||
|
| `--error-color` | `#d03050` | `#e88080` | Error/danger operations |
|
||||||
|
| `--error-color-hover` | `#de576d` | `#e98b8b` | Hover state |
|
||||||
|
| `--error-color-pressed` | `#ab1f3f` | `#e57272` | Active state |
|
||||||
|
| `--error-color-suppl` | `#de576d` | `rgb(208, 58, 82)` | Supplementary |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Text Colors
|
||||||
|
|
||||||
|
Naive UI uses a hierarchical text color system for visual clarity.
|
||||||
|
|
||||||
|
### Light Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--text-color-base` | `#000` | Base text color |
|
||||||
|
| `--text-color-1` | `rgb(31, 34, 37)` | Primary text - headings, important content |
|
||||||
|
| `--text-color-2` | `rgb(51, 54, 57)` | Secondary text - body content |
|
||||||
|
| `--text-color-3` | `rgb(118, 124, 130)` | Tertiary text - captions, hints |
|
||||||
|
| `--text-color-disabled` | `rgba(0, 0, 0, 0.24)` | Disabled text |
|
||||||
|
| `--placeholder-color` | `rgba(0, 0, 0, 0.24)` | Placeholder text |
|
||||||
|
| `--placeholder-color-disabled` | `rgba(0, 0, 0, 0.18)` | Disabled placeholder |
|
||||||
|
|
||||||
|
### Dark Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--text-color-base` | `#fff` | Base text color |
|
||||||
|
| `--text-color-1` | `rgba(255, 255, 255, 0.9)` | Primary text |
|
||||||
|
| `--text-color-2` | `rgba(255, 255, 255, 0.82)` | Secondary text |
|
||||||
|
| `--text-color-3` | `rgba(255, 255, 255, 0.52)` | Tertiary text |
|
||||||
|
| `--text-color-disabled` | `rgba(255, 255, 255, 0.38)` | Disabled text |
|
||||||
|
| `--placeholder-color` | `rgba(255, 255, 255, 0.38)` | Placeholder text |
|
||||||
|
| `--placeholder-color-disabled` | `rgba(255, 255, 255, 0.28)` | Disabled placeholder |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Background Colors
|
||||||
|
|
||||||
|
### Light Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--base-color` | `#fff` | Base background |
|
||||||
|
| `--body-color` | `#fff` | Body background |
|
||||||
|
| `--card-color` | `#fff` | Card background |
|
||||||
|
| `--modal-color` | `#fff` | Modal background |
|
||||||
|
| `--popover-color` | `#fff` | Popover background |
|
||||||
|
| `--table-color` | `#fff` | Table background |
|
||||||
|
| `--hover-color` | `rgb(243, 243, 245)` | Hover state background |
|
||||||
|
| `--pressed-color` | `rgb(237, 237, 239)` | Pressed state background |
|
||||||
|
| `--action-color` | `rgb(250, 250, 252)` | Action area background |
|
||||||
|
| `--input-color` | `#fff` | Input background |
|
||||||
|
|
||||||
|
### Dark Theme
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--base-color` | `#000` | Base background |
|
||||||
|
| `--body-color` | `rgb(16, 16, 20)` | Body background |
|
||||||
|
| `--card-color` | `rgb(24, 24, 28)` | Card background |
|
||||||
|
| `--modal-color` | `rgb(44, 44, 50)` | Modal background |
|
||||||
|
| `--popover-color` | `rgb(72, 72, 78)` | Popover background |
|
||||||
|
| `--table-color` | `rgb(24, 24, 28)` | Table background |
|
||||||
|
| `--hover-color` | `rgba(255, 255, 255, 0.09)` | Hover state background |
|
||||||
|
| `--pressed-color` | `rgba(255, 255, 255, 0.05)` | Pressed state background |
|
||||||
|
| `--action-color` | `rgba(255, 255, 255, 0.06)` | Action area background |
|
||||||
|
| `--input-color` | `rgba(255, 255, 255, 0.1)` | Input background |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Border & Divider Colors
|
||||||
|
|
||||||
|
| CSS Variable | Light Theme | Dark Theme | Usage |
|
||||||
|
|--------------|-------------|------------|-------|
|
||||||
|
| `--border-color` | `rgb(224, 224, 230)` | `rgba(255, 255, 255, 0.24)` | Default border |
|
||||||
|
| `--divider-color` | `rgb(239, 239, 245)` | `rgba(255, 255, 255, 0.09)` | Divider lines |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Using Theme Variables
|
||||||
|
|
||||||
|
### In CSS (with n-element)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<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);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Styled with theme variables
|
||||||
|
</n-el>
|
||||||
|
</n-card>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### In JavaScript (with useThemeVars)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :style="{ color: themeVars.primaryColor }">
|
||||||
|
Primary color text
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Variables Summary
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--primary-color: #18a058;
|
||||||
|
--primary-color-hover: #36ad6a;
|
||||||
|
--primary-color-pressed: #0c7a43;
|
||||||
|
|
||||||
|
--success-color: #18a058;
|
||||||
|
--info-color: #2080f0;
|
||||||
|
--warning-color: #f0a020;
|
||||||
|
--error-color: #d03050;
|
||||||
|
|
||||||
|
--text-color-1: rgb(31, 34, 37);
|
||||||
|
--text-color-2: rgb(51, 54, 57);
|
||||||
|
--text-color-3: rgb(118, 124, 130);
|
||||||
|
|
||||||
|
--base-color: #fff;
|
||||||
|
--body-color: #fff;
|
||||||
|
--card-color: #fff;
|
||||||
|
--modal-color: #fff;
|
||||||
|
|
||||||
|
--border-color: rgb(224, 224, 230);
|
||||||
|
--divider-color: rgb(239, 239, 245);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use CSS Variables**: Always use predefined color variables via `useThemeVars()` or `var(--xxx)` for consistency
|
||||||
|
2. **Semantic Colors**: Use appropriate semantic colors for their intended purpose
|
||||||
|
3. **Text Hierarchy**: Use text color variables to establish visual hierarchy
|
||||||
|
4. **Dark Mode Support**: Colors automatically adjust when using dark theme
|
||||||
|
5. **Customization**: Override theme variables via `n-config-provider` to match your brand
|
||||||
|
6. **State Colors**: Use hover/pressed variants for interactive elements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
| Resource | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| [useThemeVars](https://www.naiveui.com/en-US/os-theme/docs/theme) | Access theme variables in JavaScript |
|
||||||
|
| [n-element](https://www.naiveui.com/en-US/os-theme/components/element) | Use CSS variables in templates |
|
||||||
|
| [n-config-provider](https://www.naiveui.com/en-US/os-theme/components/config-provider) | Theme customization |
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-design-layout"
|
||||||
|
description: "Layout system for Naive UI including Grid, Flex, Space, and Layout components. Invoke when user needs to create responsive layouts, grid systems, or understand layout components."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Layout System
|
||||||
|
|
||||||
|
Naive UI provides a comprehensive layout system including CSS Grid-based layout, Flexbox, Space, and Layout components for building responsive page structures.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Creating responsive grid layouts
|
||||||
|
- Building page structures with header, sidebar, content, and footer
|
||||||
|
- Implementing flexible layouts with Flexbox
|
||||||
|
- Adding consistent spacing between elements
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Grid System (n-grid)
|
||||||
|
|
||||||
|
Naive UI uses a CSS Grid-based layout system with 24 columns by default.
|
||||||
|
|
||||||
|
### Basic Concepts
|
||||||
|
|
||||||
|
- **24-column system**: Default is 24 columns, configurable
|
||||||
|
- **CSS Grid**: Uses native CSS Grid for layout
|
||||||
|
- **Responsive**: Supports responsive breakpoints
|
||||||
|
- **Flexible**: Items can span multiple columns
|
||||||
|
|
||||||
|
### Basic Grid
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-grid :cols="24">
|
||||||
|
<n-gi :span="24">Full width</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
|
||||||
|
<n-grid :cols="24">
|
||||||
|
<n-gi :span="12">Half width</n-gi>
|
||||||
|
<n-gi :span="12">Half width</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
|
||||||
|
<n-grid :cols="24">
|
||||||
|
<n-gi :span="8">One third</n-gi>
|
||||||
|
<n-gi :span="8">One third</n-gi>
|
||||||
|
<n-gi :span="8">One third</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grid with Gaps
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-grid :cols="4" :x-gap="12" :y-gap="8">
|
||||||
|
<n-gi v-for="i in 8" :key="i">
|
||||||
|
<div class="item">{{ i }}</div>
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responsive Grid
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-grid :cols="4" responsive="screen">
|
||||||
|
<n-gi :span="4" :xs="24" :sm="12" :md="8" :lg="6" :xl="4">
|
||||||
|
Responsive item
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grid Item Offset
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-grid :cols="24">
|
||||||
|
<n-gi :span="6" :offset="6">Offset by 6</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Grid Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| cols | Number of columns | `number \| string` | `24` |
|
||||||
|
| x-gap | Horizontal gap | `number \| string` | `0` |
|
||||||
|
| y-gap | Vertical gap | `number \| string` | `0` |
|
||||||
|
| responsive | Responsive mode | `'self' \| 'screen'` | `'self'` |
|
||||||
|
| collapsed | Collapsed state | `boolean` | `false` |
|
||||||
|
| collapsedRows | Rows when collapsed | `number` | `1` |
|
||||||
|
|
||||||
|
### Grid Item Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| span | Number of columns to span | `number \| string` | `1` |
|
||||||
|
| offset | Number of columns to offset | `number` | `0` |
|
||||||
|
| suffix | Whether it's a suffix item | `boolean` | `false` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Flex Component (n-flex)
|
||||||
|
|
||||||
|
A flexible flexbox layout component.
|
||||||
|
|
||||||
|
### Basic Flex
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-flex>
|
||||||
|
<div>Item 1</div>
|
||||||
|
<div>Item 2</div>
|
||||||
|
<div>Item 3</div>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flex with Justify
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-flex justify="center">
|
||||||
|
<div>Centered</div>
|
||||||
|
</n-flex>
|
||||||
|
|
||||||
|
<n-flex justify="space-between">
|
||||||
|
<div>Left</div>
|
||||||
|
<div>Right</div>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flex Vertical
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-flex vertical>
|
||||||
|
<div>Item 1</div>
|
||||||
|
<div>Item 2</div>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flex Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| justify | Horizontal alignment | `'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'` | `'start'` |
|
||||||
|
| align | Vertical alignment | `'start' \| 'end' \| 'center' \| 'stretch' \| 'baseline'` | — |
|
||||||
|
| vertical | Vertical direction | `boolean` | `false` |
|
||||||
|
| reverse | Reverse direction | `boolean` | `false` |
|
||||||
|
| wrap | Enable wrapping | `boolean` | `true` |
|
||||||
|
| inline | Inline flex | `boolean` | `false` |
|
||||||
|
| size | Gap size | `'small' \| 'medium' \| 'large' \| number \| [number, number]` | `'medium'` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Space Component (n-space)
|
||||||
|
|
||||||
|
Add consistent spacing between elements.
|
||||||
|
|
||||||
|
### Basic Space
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-space>
|
||||||
|
<n-button>Button 1</n-button>
|
||||||
|
<n-button>Button 2</n-button>
|
||||||
|
<n-button>Button 3</n-button>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Space Sizes
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-space size="small">Small gap</n-space>
|
||||||
|
<n-space size="medium">Medium gap</n-space>
|
||||||
|
<n-space size="large">Large gap</n-space>
|
||||||
|
<n-space :size="24">Custom 24px gap</n-space>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vertical Space
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-space vertical>
|
||||||
|
<n-button>Top</n-button>
|
||||||
|
<n-button>Bottom</n-button>
|
||||||
|
</n-space>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Space Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| size | Gap size | `'small' \| 'medium' \| 'large' \| number \| [number, number]` | `'small'` |
|
||||||
|
| vertical | Vertical direction | `boolean` | `false` |
|
||||||
|
| wrap | Enable wrapping | `boolean` | `true` |
|
||||||
|
| inline | Inline mode | `boolean` | `false` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Layout Components (n-layout)
|
||||||
|
|
||||||
|
Build complete page layouts with header, sidebar, content, and footer.
|
||||||
|
|
||||||
|
### Basic Layout
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-layout>
|
||||||
|
<n-layout-header>Header</n-layout-header>
|
||||||
|
<n-layout-content>Content</n-layout-content>
|
||||||
|
<n-layout-footer>Footer</n-layout-footer>
|
||||||
|
</n-layout>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Layout with Sidebar
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-layout has-sider>
|
||||||
|
<n-layout-sider>Sidebar</n-layout-sider>
|
||||||
|
<n-layout>
|
||||||
|
<n-layout-header>Header</n-layout-header>
|
||||||
|
<n-layout-content>Content</n-layout-content>
|
||||||
|
<n-layout-footer>Footer</n-layout-footer>
|
||||||
|
</n-layout>
|
||||||
|
</n-layout>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Collapsible Sidebar
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
const collapsed = ref(false)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-layout has-sider>
|
||||||
|
<n-layout-sider
|
||||||
|
bordered
|
||||||
|
collapse-mode="width"
|
||||||
|
:collapsed-width="64"
|
||||||
|
:width="240"
|
||||||
|
:collapsed="collapsed"
|
||||||
|
show-trigger
|
||||||
|
@collapse="collapsed = true"
|
||||||
|
@expand="collapsed = false"
|
||||||
|
>
|
||||||
|
Sidebar
|
||||||
|
</n-layout-sider>
|
||||||
|
<n-layout-content>Content</n-layout-content>
|
||||||
|
</n-layout>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Layout Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| embedded | Embedded mode (no background) | `boolean` | `false` |
|
||||||
|
| position | Position mode | `'static' \| 'absolute'` | `'static'` |
|
||||||
|
| native-scrollbar | Use native scrollbar | `boolean` | `true` |
|
||||||
|
| has-sider | Has sidebar | `boolean` | `false` |
|
||||||
|
| sider-placement | Sidebar placement | `'left' \| 'right'` | `'left'` |
|
||||||
|
|
||||||
|
### Layout Sider Props
|
||||||
|
|
||||||
|
| Name | Description | Type | Default |
|
||||||
|
|------|-------------|------|---------|
|
||||||
|
| bordered | Show border | `boolean` | `false` |
|
||||||
|
| collapsed | Collapsed state | `boolean` | `false` |
|
||||||
|
| collapse-mode | Collapse mode | `'width' \| 'transform'` | `'transform'` |
|
||||||
|
| collapsed-width | Width when collapsed | `number` | `48` |
|
||||||
|
| width | Sidebar width | `number` | `272` |
|
||||||
|
| show-trigger | Show collapse trigger | `boolean` | `false` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Responsive Breakpoints
|
||||||
|
|
||||||
|
Naive UI uses default breakpoints for responsive design:
|
||||||
|
|
||||||
|
| Breakpoint | Screen Width |
|
||||||
|
|------------|--------------|
|
||||||
|
| `xs` | `< 640px` |
|
||||||
|
| `s` | `≥ 640px` |
|
||||||
|
| `m` | `≥ 1024px` |
|
||||||
|
| `l` | `≥ 1280px` |
|
||||||
|
| `xl` | `≥ 1536px` |
|
||||||
|
| `xxl` | `≥ 1920px` |
|
||||||
|
|
||||||
|
### Using Breakpoints
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-grid :cols="4" responsive="screen">
|
||||||
|
<n-gi :span="1" :xs="4" :s="2" :m="1">
|
||||||
|
Responsive grid item
|
||||||
|
</n-gi>
|
||||||
|
</n-grid>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use Grid for 2D layouts**: Use `n-grid` when you need both rows and columns
|
||||||
|
2. **Use Flex for 1D layouts**: Use `n-flex` for single-row or single-column layouts
|
||||||
|
3. **Use Space for simple gaps**: Use `n-space` for consistent spacing between elements
|
||||||
|
4. **Layout composition**: Combine Layout components for full-page structures
|
||||||
|
5. **Responsive design**: Use responsive props for mobile-first design
|
||||||
|
6. **Collapsed sidebar**: Use `collapse-mode="width"` for better animation performance
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
| Resource | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| [Grid Component](https://www.naiveui.com/en-US/os-theme/components/grid) | Grid documentation |
|
||||||
|
| [Flex Component](https://www.naiveui.com/en-US/os-theme/components/flex) | Flex documentation |
|
||||||
|
| [Space Component](https://www.naiveui.com/en-US/os-theme/components/space) | Space documentation |
|
||||||
|
| [Layout Component](https://www.naiveui.com/en-US/os-theme/components/layout) | Layout documentation |
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-design-overview"
|
||||||
|
description: "Overview of all Naive UI components organized by category. Invoke when user needs a quick reference to all available components or wants to explore the component library."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naive UI Component Overview
|
||||||
|
|
||||||
|
Quick reference to all Naive UI components organized by category. Naive UI is a Vue 3 component library that is fairly complete, themeable, written in TypeScript, and fast.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Exploring available components
|
||||||
|
- Quick component reference
|
||||||
|
- Understanding component categories
|
||||||
|
- Planning UI implementation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Component Categories
|
||||||
|
|
||||||
|
### Basic Components (18)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **Affix** | Fixes elements to a specific visible area |
|
||||||
|
| **Avatar** | User avatars with images, icons, or characters |
|
||||||
|
| **AvatarGroup** | Group of avatars with overlap display |
|
||||||
|
| **Badge** | Numbers or status marks on elements |
|
||||||
|
| **Button** | Basic button with various types and sizes |
|
||||||
|
| **ButtonGroup** | Group of buttons |
|
||||||
|
| **Card** | Information in card containers |
|
||||||
|
| **Carousel** | Image/text carousels |
|
||||||
|
| **Collapse** | Expandable panels |
|
||||||
|
| **CollapseTransition** | Collapse transition wrapper |
|
||||||
|
| **Divider** | Content separation lines |
|
||||||
|
| **Drawer** | Slide-out panels from screen edge |
|
||||||
|
| **Dropdown** | Dropdown menus |
|
||||||
|
| **Ellipsis** | Text with ellipsis and tooltip |
|
||||||
|
| **Empty** | Empty state placeholder |
|
||||||
|
| **Icon** | Icon component |
|
||||||
|
| **IconWrapper** | Icon wrapper for consistent sizing |
|
||||||
|
| **Tag** | Labels and tags |
|
||||||
|
|
||||||
|
### Form Components (18)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **AutoComplete** | Input with autocomplete suggestions |
|
||||||
|
| **Cascader** | Hierarchical selection |
|
||||||
|
| **Checkbox** | Multiple selection |
|
||||||
|
| **ColorPicker** | Color selection |
|
||||||
|
| **DatePicker** | Date selection |
|
||||||
|
| **DynamicInput** | Dynamic input fields |
|
||||||
|
| **DynamicTags** | Dynamic tag input |
|
||||||
|
| **Form** | Form management and validation |
|
||||||
|
| **Input** | Text input |
|
||||||
|
| **InputNumber** | Numeric input |
|
||||||
|
| **InputOTP** | One-time password input |
|
||||||
|
| **Mention** | @mentions in inputs |
|
||||||
|
| **Radio** | Single selection |
|
||||||
|
| **Rate** | Star rating |
|
||||||
|
| **Select** | Dropdown selection |
|
||||||
|
| **Slider** | Range slider |
|
||||||
|
| **Switch** | Toggle switch |
|
||||||
|
| **TimePicker** | Time selection |
|
||||||
|
| **Transfer** | Dual-column selection |
|
||||||
|
| **TreeSelect** | Tree-based selection |
|
||||||
|
| **Upload** | File upload |
|
||||||
|
|
||||||
|
### Data Display Components (22)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **Avatar** | User avatars |
|
||||||
|
| **AvatarGroup** | Avatar groups |
|
||||||
|
| **Badge** | Status marks |
|
||||||
|
| **Calendar** | Date display |
|
||||||
|
| **Card** | Card containers |
|
||||||
|
| **Carousel** | Carousels |
|
||||||
|
| **Code** | Code display with syntax highlighting |
|
||||||
|
| **DataTable** | Advanced data tables |
|
||||||
|
| **Descriptions** | Key-value displays |
|
||||||
|
| **Empty** | Empty state placeholder |
|
||||||
|
| **Equation** | Mathematical equations |
|
||||||
|
| **GradientText** | Gradient text effect |
|
||||||
|
| **Heatmap** | Heatmap visualization |
|
||||||
|
| **Highlight** | Text highlighting |
|
||||||
|
| **Image** | Images with preview |
|
||||||
|
| **List** | List container |
|
||||||
|
| **Log** | Console log display |
|
||||||
|
| **NumberAnimation** | Animated number display |
|
||||||
|
| **Progress** | Progress indicators |
|
||||||
|
| **QRCode** | QR code generation |
|
||||||
|
| **Statistic** | Numerical statistics |
|
||||||
|
| **Table** | Basic data tables |
|
||||||
|
| **Thing** | Thing card component |
|
||||||
|
| **Timeline** | Chronological events |
|
||||||
|
| **Tree** | Hierarchical data |
|
||||||
|
| **VirtualList** | Virtual scrolling list |
|
||||||
|
|
||||||
|
### Navigation Components (7)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **Affix** | Sticky elements |
|
||||||
|
| **Anchor** | Page navigation |
|
||||||
|
| **Breadcrumb** | Location display |
|
||||||
|
| **Dropdown** | Dropdown menus |
|
||||||
|
| **Menu** | Navigation menu |
|
||||||
|
| **PageHeader** | Page headers |
|
||||||
|
| **Pagination** | Page navigation |
|
||||||
|
| **Steps** | Step guide |
|
||||||
|
| **Tabs** | Tabbed content |
|
||||||
|
|
||||||
|
### Feedback Components (11)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **Alert** | Alert messages |
|
||||||
|
| **Dialog** | Modal dialogs |
|
||||||
|
| **Drawer** | Slide-out panels |
|
||||||
|
| **LoadingBar** | Top loading bar |
|
||||||
|
| **Message** | Toast messages |
|
||||||
|
| **Modal** | Modal dialogs |
|
||||||
|
| **Notification** | Corner notifications |
|
||||||
|
| **Popconfirm** | Confirmation dialogs |
|
||||||
|
| **Popover** | Rich popups |
|
||||||
|
| **Result** | Result pages |
|
||||||
|
| **Spin** | Loading spinner |
|
||||||
|
| **Tooltip** | Hover tooltips |
|
||||||
|
|
||||||
|
### Layout Components (7)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **Divider** | Content separation |
|
||||||
|
| **Flex** | Flexbox layout |
|
||||||
|
| **Grid** | CSS Grid layout |
|
||||||
|
| **Layout** | Page layout containers |
|
||||||
|
| **LegacyGrid** | Legacy 24-column grid |
|
||||||
|
| **Space** | Element spacing |
|
||||||
|
| **Split** | Resizable panels |
|
||||||
|
|
||||||
|
### Typography Components (6)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **H1-H6** | Header components |
|
||||||
|
| **P** | Paragraph |
|
||||||
|
| **Text** | Styled text |
|
||||||
|
| **A** | Anchor/link |
|
||||||
|
| **Hr** | Horizontal rule |
|
||||||
|
| **Ul/Ol/Li** | List elements |
|
||||||
|
| **Blockquote** | Blockquote |
|
||||||
|
|
||||||
|
### Utility Components (9)
|
||||||
|
|
||||||
|
| Component | Description |
|
||||||
|
|-----------|-------------|
|
||||||
|
| **ConfigProvider** | Global configuration |
|
||||||
|
| **Discrete** | Discrete component mounting |
|
||||||
|
| **Element** | Theme variable container |
|
||||||
|
| **FloatButton** | Floating action button |
|
||||||
|
| **FloatButtonGroup** | Floating button group |
|
||||||
|
| **GlobalStyle** | Global style injection |
|
||||||
|
| **InfiniteScroll** | Infinite scrolling |
|
||||||
|
| **Marquee** | Marquee scrolling text |
|
||||||
|
| **Scrollbar** | Custom scrollbars |
|
||||||
|
| **Watermark** | Watermarks |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Resources
|
||||||
|
|
||||||
|
| Resource | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| **Color** | Color palette and semantics |
|
||||||
|
| **Border** | Border styles, radius, shadows |
|
||||||
|
| **Layout** | Grid and flexbox systems |
|
||||||
|
| **Typography** | Font conventions |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
### TypeScript Support
|
||||||
|
|
||||||
|
All components are written in TypeScript with full type definitions.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import type { ButtonProps, InputProps } from 'naive-ui'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tree-shaking
|
||||||
|
|
||||||
|
All components support tree-shaking for optimal bundle size.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { NButton, NInput } from 'naive-ui'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Theme Customization
|
||||||
|
|
||||||
|
Advanced type-safe theme system built with TypeScript.
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme-overrides="themeOverrides">
|
||||||
|
<app />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const themeOverrides = {
|
||||||
|
common: {
|
||||||
|
primaryColor: '#18a058'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dark Mode
|
||||||
|
|
||||||
|
Built-in dark theme support.
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :theme="darkTheme">
|
||||||
|
<app />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### useThemeVars Hook
|
||||||
|
|
||||||
|
Access theme variables in JavaScript.
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :style="{ color: themeVars.primaryColor }">
|
||||||
|
Primary color text
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
| Skill | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| [naive-ui-design-color](./naive-ui-design-color/SKILL.md) | Color design specifications |
|
||||||
|
| [naive-ui-design-border](./naive-ui-design-border/SKILL.md) | Border design specifications |
|
||||||
|
| [naive-ui-design-typography](./naive-ui-design-typography/SKILL.md) | Typography specifications |
|
||||||
|
| [naive-ui-design-layout](./naive-ui-design-layout/SKILL.md) | Layout system documentation |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## External Resources
|
||||||
|
|
||||||
|
| Resource | URL |
|
||||||
|
|----------|-----|
|
||||||
|
| Official Documentation | https://www.naiveui.com |
|
||||||
|
| GitHub Repository | https://github.com/tusen-ai/naive-ui |
|
||||||
|
| Design Resources (Sketch) | [Download](https://naive-ui.oss-accelerate.aliyuncs.com/NaiveUI-Design-Library-en-US.sketch) |
|
||||||
|
| xicons (Recommended Icons) | https://www.xicons.org |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use ConfigProvider**: Wrap your app with `n-config-provider` for global configuration
|
||||||
|
2. **Tree-shaking**: Import only the components you need
|
||||||
|
3. **Theme Variables**: Use `useThemeVars()` for consistent theming
|
||||||
|
4. **Dark Mode**: Test your app in both light and dark themes
|
||||||
|
5. **Accessibility**: Use appropriate ARIA attributes and semantic HTML
|
||||||
|
6. **Responsive Design**: Use responsive props for mobile-first design
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-design-typography"
|
||||||
|
description: "Typography design specifications for Naive UI. Invoke when user needs to understand font conventions, font-family settings, or text styling guidelines."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Typography Design Specifications
|
||||||
|
|
||||||
|
Naive UI creates font conventions to ensure the best presentation across different platforms. Typography is an art that enhances readability and visual hierarchy.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- Understanding font conventions
|
||||||
|
- Applying consistent text styles
|
||||||
|
- Setting font-family for cross-platform compatibility
|
||||||
|
- Managing font sizes and line heights
|
||||||
|
- Using typography components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Font Family
|
||||||
|
|
||||||
|
Naive UI uses a carefully selected font stack for optimal cross-platform display.
|
||||||
|
|
||||||
|
### Sans-serif Font (Default)
|
||||||
|
|
||||||
|
```css
|
||||||
|
font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont,
|
||||||
|
"Segoe UI", sans-serif, "Apple Color Emoji",
|
||||||
|
"Segoe UI Emoji", "Segoe UI Symbol";
|
||||||
|
```
|
||||||
|
|
||||||
|
### Monospace Font
|
||||||
|
|
||||||
|
```css
|
||||||
|
font-family: v-mono, SFMono-Regular, Menlo, Consolas, Courier, monospace;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Font Stack Explanation
|
||||||
|
|
||||||
|
| Font | Platform | Purpose |
|
||||||
|
|------|----------|---------|
|
||||||
|
| v-sans | All | Custom sans-serif font (can be configured) |
|
||||||
|
| system-ui | All | System UI font |
|
||||||
|
| -apple-system | macOS/iOS | Apple system font |
|
||||||
|
| BlinkMacSystemFont | macOS | Chrome on macOS |
|
||||||
|
| Segoe UI | Windows | Windows system font |
|
||||||
|
| Apple Color Emoji | macOS/iOS | Emoji support |
|
||||||
|
| Segoe UI Emoji | Windows | Emoji support |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Font Sizes
|
||||||
|
|
||||||
|
Naive UI provides standardized font size variables for different contexts.
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--font-size` | `14px` | Base body text |
|
||||||
|
| `--font-size-mini` | `12px` | Mini text, tiny labels |
|
||||||
|
| `--font-size-tiny` | `12px` | Tiny text |
|
||||||
|
| `--font-size-small` | `14px` | Small text |
|
||||||
|
| `--font-size-medium` | `14px` | Medium text |
|
||||||
|
| `--font-size-large` | `15px` | Large text |
|
||||||
|
| `--font-size-huge` | `16px` | Huge text |
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { useThemeVars } from 'naive-ui'
|
||||||
|
const themeVars = useThemeVars()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<p :style="{ fontSize: themeVars.fontSize }">Base text</p>
|
||||||
|
<span :style="{ fontSize: themeVars.fontSizeMini }">Mini text</span>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Font Weight
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--font-weight` | `400` | Normal text weight |
|
||||||
|
| `--font-weight-strong` | `500` | Emphasized text |
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-el style="font-weight: var(--font-weight-strong)">
|
||||||
|
Strong text
|
||||||
|
</n-el>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Line Height
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--line-height` | `1.6` | Default line height for body text |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Header Typography
|
||||||
|
|
||||||
|
Naive UI provides typography components with predefined header styles.
|
||||||
|
|
||||||
|
### Header Font Sizes
|
||||||
|
|
||||||
|
| Level | Font Size | Margin |
|
||||||
|
|-------|-----------|--------|
|
||||||
|
| H1 | `30px` | `28px 0 20px 0` |
|
||||||
|
| H2 | `22px` | `28px 0 20px 0` |
|
||||||
|
| H3 | `18px` | `28px 0 20px 0` |
|
||||||
|
| H4 | `16px` | `28px 0 18px 0` |
|
||||||
|
| H5 | `16px` | `28px 0 18px 0` |
|
||||||
|
| H6 | `16px` | `28px 0 18px 0` |
|
||||||
|
|
||||||
|
### Header Components
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-h1>Heading 1</n-h1>
|
||||||
|
<n-h2>Heading 2</n-h2>
|
||||||
|
<n-h3>Heading 3</n-h3>
|
||||||
|
<n-h4>Heading 4</n-h4>
|
||||||
|
<n-h5>Heading 5</n-h5>
|
||||||
|
<n-h6>Heading 6</n-h6>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Header with Prefix Bar
|
||||||
|
|
||||||
|
Headers can display a colored bar prefix for visual emphasis.
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-h1 prefix="bar">Heading with bar</n-h1>
|
||||||
|
<n-h2 prefix="bar" align-text>Aligned heading</n-h2>
|
||||||
|
<n-h3 prefix="bar" type="success">Success heading</n-h3>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Text Component
|
||||||
|
|
||||||
|
Naive UI provides a Text component for styled text display.
|
||||||
|
|
||||||
|
### Text Types
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-text>Default text</n-text>
|
||||||
|
<n-text type="primary">Primary text</n-text>
|
||||||
|
<n-text type="success">Success text</n-text>
|
||||||
|
<n-text type="info">Info text</n-text>
|
||||||
|
<n-text type="warning">Warning text</n-text>
|
||||||
|
<n-text type="error">Error text</n-text>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Text Depth
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-text>Primary depth (default)</n-text>
|
||||||
|
<n-text depth="2">Secondary depth</n-text>
|
||||||
|
<n-text depth="3">Tertiary depth</n-text>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Text with Tag
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-text tag="div">Text as div</n-text>
|
||||||
|
<n-text tag="span">Text as span</n-text>
|
||||||
|
<n-text tag="label">Text as label</n-text>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Paragraph Component
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-p>
|
||||||
|
This is a paragraph with proper spacing and typography.
|
||||||
|
Naive UI provides consistent text styling across components.
|
||||||
|
</n-p>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Other Typography Components
|
||||||
|
|
||||||
|
### Anchor (Link)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-a href="https://example.com">Link text</n-a>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Horizontal Rule
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-hr />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lists
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-ul>
|
||||||
|
<n-li>Unordered list item 1</n-li>
|
||||||
|
<n-li>Unordered list item 2</n-li>
|
||||||
|
</n-ul>
|
||||||
|
|
||||||
|
<n-ol>
|
||||||
|
<n-li>Ordered list item 1</n-li>
|
||||||
|
<n-li>Ordered list item 2</n-li>
|
||||||
|
</n-ol>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Blockquote
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-blockquote>
|
||||||
|
<n-p>This is a blockquote with proper styling.</n-p>
|
||||||
|
</n-blockquote>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Variables Summary
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--font-family: v-sans, system-ui, -apple-system, BlinkMacSystemFont,
|
||||||
|
"Segoe UI", sans-serif;
|
||||||
|
--font-family-mono: v-mono, SFMono-Regular, Menlo, Consolas, Courier, monospace;
|
||||||
|
|
||||||
|
--font-size: 14px;
|
||||||
|
--font-size-mini: 12px;
|
||||||
|
--font-size-tiny: 12px;
|
||||||
|
--font-size-small: 14px;
|
||||||
|
--font-size-medium: 14px;
|
||||||
|
--font-size-large: 15px;
|
||||||
|
--font-size-huge: 16px;
|
||||||
|
|
||||||
|
--font-weight: 400;
|
||||||
|
--font-weight-strong: 500;
|
||||||
|
|
||||||
|
--line-height: 1.6;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Component Heights
|
||||||
|
|
||||||
|
Naive UI uses standardized heights for form controls and interactive elements.
|
||||||
|
|
||||||
|
| CSS Variable | Value | Usage |
|
||||||
|
|--------------|-------|-------|
|
||||||
|
| `--height-mini` | `16px` | Mini size controls |
|
||||||
|
| `--height-tiny` | `22px` | Tiny size controls |
|
||||||
|
| `--height-small` | `28px` | Small size controls |
|
||||||
|
| `--height-medium` | `34px` | Medium size controls (default) |
|
||||||
|
| `--height-large` | `40px` | Large size controls |
|
||||||
|
| `--height-huge` | `46px` | Huge size controls |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use Typography Components**: Use `n-h1` through `n-h6`, `n-p`, `n-text` for consistent styling
|
||||||
|
2. **Cross-Platform**: The font stack ensures consistent display across platforms
|
||||||
|
3. **Hierarchy**: Use font sizes and depths to establish visual hierarchy
|
||||||
|
4. **Line Height**: Maintain readable line height (1.6) for body text
|
||||||
|
5. **Dark Mode**: Typography automatically adjusts in dark mode
|
||||||
|
6. **Semantic HTML**: Use appropriate tags (`tag` prop) for accessibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
| Resource | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| [Typography Components](https://www.naiveui.com/en-US/os-theme/components/typography) | Full typography documentation |
|
||||||
|
| [useThemeVars](https://www.naiveui.com/en-US/os-theme/docs/theme) | Access theme variables |
|
||||||
|
| [Color Design](./naive-ui-design-color/SKILL.md) | Text color variables |
|
||||||
|
| [Border Design](./naive-ui-design-border/SKILL.md) | Related design specifications |
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
---
|
||||||
|
name: naive-ui-i18n
|
||||||
|
description: Configure internationalization (i18n) in Naive UI with support for multiple languages and custom locales
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: 1.0.0
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naive UI Internationalization (i18n)
|
||||||
|
|
||||||
|
Configure internationalization in Naive UI to support multiple languages and customize component locales.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this skill when you need to:
|
||||||
|
- Set up multi-language support in your application
|
||||||
|
- Change the language of Naive UI components
|
||||||
|
- Customize existing locale strings
|
||||||
|
- Add support for new languages
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Basic understanding of Naive UI setup
|
||||||
|
- Vue 3 Composition API knowledge
|
||||||
|
- Understanding of internationalization concepts
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Setting Up Locale
|
||||||
|
|
||||||
|
Use `n-config-provider` to set the locale for all descendant components:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="enUS" :date-locale="dateEnUS">
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { NConfigProvider } from 'naive-ui'
|
||||||
|
import { enUS, dateEnUS } from 'naive-ui'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Switching Languages Dynamically
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="locale" :date-locale="dateLocale">
|
||||||
|
<n-space vertical>
|
||||||
|
<n-select
|
||||||
|
v-model:value="currentLang"
|
||||||
|
:options="langOptions"
|
||||||
|
@update:value="handleLangChange"
|
||||||
|
/>
|
||||||
|
<n-date-picker type="date" />
|
||||||
|
<n-pagination :page-count="10" />
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { enUS, dateEnUS, zhCN, dateZhCN } from 'naive-ui'
|
||||||
|
|
||||||
|
const currentLang = ref('en')
|
||||||
|
const locale = ref(enUS)
|
||||||
|
const dateLocale = ref(dateEnUS)
|
||||||
|
|
||||||
|
const langOptions = [
|
||||||
|
{ label: 'English', value: 'en' },
|
||||||
|
{ label: '中文', value: 'zh' }
|
||||||
|
]
|
||||||
|
|
||||||
|
const handleLangChange = (lang) => {
|
||||||
|
if (lang === 'en') {
|
||||||
|
locale.value = enUS
|
||||||
|
dateLocale.value = dateEnUS
|
||||||
|
} else if (lang === 'zh') {
|
||||||
|
locale.value = zhCN
|
||||||
|
dateLocale.value = dateZhCN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Supported Languages
|
||||||
|
|
||||||
|
Naive UI supports the following languages (PRs are welcome for new languages):
|
||||||
|
|
||||||
|
| Language | Config | Date Config | Version |
|
||||||
|
|----------|--------|-------------|---------|
|
||||||
|
| Arabic (العربية) | `arDZ` | `dateArDZ` | 2.34.0 |
|
||||||
|
| Azerbaijani (Azərbaycanca) | `azAZ` | `dateAzAZ` | 2.39.0 |
|
||||||
|
| Czech (Czechia) | `csCZ` | `dateCsCz` | 2.38.2 |
|
||||||
|
| Danish (Denmark) | `daDK` | `dateDaDK` | 2.43.0 |
|
||||||
|
| German (Germany) | `deDE` | `dateDeDE` | - |
|
||||||
|
| English (British) | `enGB` | `dateEnGB` | 2.25.1 |
|
||||||
|
| English | `enUS` | `dateEnUS` | - |
|
||||||
|
| Esperanto | `eo` | `dateEo` | 2.25.2 |
|
||||||
|
| Spanish (Argentina) | `esAR` | `dateEsAR` | 2.24.2 |
|
||||||
|
| Estonian | `etEE` | `dateEtEE` | 2.38.0 |
|
||||||
|
| Persian | `faIR` | `dateFaIR` | 2.34.4 |
|
||||||
|
| French | `frFR` | `dateFrFR` | - |
|
||||||
|
| Bahasa Indonesia | `idID` | `dateIdID` | - |
|
||||||
|
| Italiano | `itIT` | `dateItIT` | 2.24.2 |
|
||||||
|
| Japanese | `jaJP` | `dateJaJP` | - |
|
||||||
|
| Khmer (Cambodia) | `kmKH` | `dateKmKH` | 2.41.0 |
|
||||||
|
| Korean (South Korea) | `koKR` | `dateKoKR` | 2.28.1 |
|
||||||
|
| Norwegian Bokmål (Norway) | `nbNO` | `dateNbNO` | - |
|
||||||
|
| Dutch (Netherlands) | `nlNL` | `dateNlNL` | 2.29.0 |
|
||||||
|
| Polish (Poland) | `plPL` | `datePlPL` | 2.25.2 |
|
||||||
|
| Portuguese (Brazil) | `ptBR` | `datePtBR` | 2.28.1 |
|
||||||
|
| Russian | `ruRU` | `dateRuRU` | - |
|
||||||
|
| Slovak | `skSK` | `dateSkSK` | 2.25.3 |
|
||||||
|
| Swedish | `svSE` | `dateSvSE` | 2.35.0 |
|
||||||
|
| Thai (Thailand) | `thTH` | `dateThTH` | 2.27.0 |
|
||||||
|
| Turkish | `trTR` | `dateTrTR` | 2.34.0 |
|
||||||
|
| Uyghur (China) | `ugCN` | `dateUgCN` | - |
|
||||||
|
| Ukrainian | `ukUA` | `dateUkUA` | - |
|
||||||
|
| Uzbek (Uzbekistan) | `uzUZ` | `dateUzUZ` | 2.39.0 |
|
||||||
|
| Vietnamese (Vietnam) | `viVN` | `dateViVN` | 2.30.7 |
|
||||||
|
| Chinese (Simplified) | `zhCN` | `dateZhCN` | - |
|
||||||
|
| Chinese (Traditional) | `zhTW` | `dateZhTW` | - |
|
||||||
|
|
||||||
|
## Customizing Locales
|
||||||
|
|
||||||
|
### Using createLocale
|
||||||
|
|
||||||
|
Customize existing locale strings using `createLocale`:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="customLocale" :date-locale="dateEnUS">
|
||||||
|
<n-input placeholder="This should show 'Okay'" />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { NConfigProvider, createLocale, enUS, dateEnUS } from 'naive-ui'
|
||||||
|
|
||||||
|
const customLocale = createLocale(
|
||||||
|
{
|
||||||
|
Input: {
|
||||||
|
placeholder: 'Okay'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enUS
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Full Locale Customization Example
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="customLocale">
|
||||||
|
<n-space vertical>
|
||||||
|
<n-input :placeholder="customLocale.Input.placeholder" />
|
||||||
|
<n-empty :description="customLocale.Empty.description" />
|
||||||
|
<n-pagination :page-count="5" />
|
||||||
|
</n-space>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { createLocale, enUS } from 'naive-ui'
|
||||||
|
|
||||||
|
const customLocale = createLocale(
|
||||||
|
{
|
||||||
|
Input: {
|
||||||
|
placeholder: 'Enter text here...'
|
||||||
|
},
|
||||||
|
Empty: {
|
||||||
|
description: 'No data available'
|
||||||
|
},
|
||||||
|
Pagination: {
|
||||||
|
goto: 'Go to',
|
||||||
|
pagesize: '/page',
|
||||||
|
total: 'Total {count} items',
|
||||||
|
pageSeparator: 'of',
|
||||||
|
page: 'Page',
|
||||||
|
prev: 'Previous',
|
||||||
|
next: 'Next',
|
||||||
|
prevPage: 'Previous page',
|
||||||
|
nextPage: 'Next page',
|
||||||
|
prev: 'Prev',
|
||||||
|
next: 'Next'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enUS
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### n-config-provider Locale Props
|
||||||
|
|
||||||
|
| Property | Type | Default | Description |
|
||||||
|
|----------|------|---------|-------------|
|
||||||
|
| `locale` | `object` | `enUS` | Locale configuration for components |
|
||||||
|
| `date-locale` | `object` | `dateEnUS` | Date format locale configuration |
|
||||||
|
|
||||||
|
### createLocale Function
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function createLocale(
|
||||||
|
overrides: PartialLocale,
|
||||||
|
baseLocale: Locale
|
||||||
|
): Locale
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates a new locale by merging custom overrides with a base locale.
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Persistent Language Selection
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="locale" :date-locale="dateLocale">
|
||||||
|
<n-select
|
||||||
|
v-model:value="currentLang"
|
||||||
|
:options="langOptions"
|
||||||
|
style="width: 200px; margin-bottom: 20px;"
|
||||||
|
/>
|
||||||
|
<router-view />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import { enUS, dateEnUS, zhCN, dateZhCN, jaJP, dateJaJP } from 'naive-ui'
|
||||||
|
|
||||||
|
const langMap = {
|
||||||
|
en: { locale: enUS, dateLocale: dateEnUS },
|
||||||
|
zh: { locale: zhCN, dateLocale: dateZhCN },
|
||||||
|
ja: { locale: jaJP, dateLocale: dateJaJP }
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentLang = ref('en')
|
||||||
|
const locale = ref(enUS)
|
||||||
|
const dateLocale = ref(dateEnUS)
|
||||||
|
|
||||||
|
const langOptions = [
|
||||||
|
{ label: 'English', value: 'en' },
|
||||||
|
{ label: '中文', value: 'zh' },
|
||||||
|
{ label: '日本語', value: 'ja' }
|
||||||
|
]
|
||||||
|
|
||||||
|
watch(currentLang, (newLang) => {
|
||||||
|
const config = langMap[newLang]
|
||||||
|
if (config) {
|
||||||
|
locale.value = config.locale
|
||||||
|
dateLocale.value = config.dateLocale
|
||||||
|
localStorage.setItem('app-language', newLang)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const savedLang = localStorage.getItem('app-language') || 'en'
|
||||||
|
currentLang.value = savedLang
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration with vue-i18n
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider :locale="naiveLocale" :date-locale="naiveDateLocale">
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { enUS, dateEnUS, zhCN, dateZhCN } from 'naive-ui'
|
||||||
|
|
||||||
|
const { locale } = useI18n()
|
||||||
|
|
||||||
|
const naiveLocale = computed(() => {
|
||||||
|
return locale.value === 'zh' ? zhCN : enUS
|
||||||
|
})
|
||||||
|
|
||||||
|
const naiveDateLocale = computed(() => {
|
||||||
|
return locale.value === 'zh' ? dateZhCN : dateEnUS
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Persist Language Preference**: Store the user's language choice in localStorage
|
||||||
|
2. **Separate Date Locale**: Always set both `locale` and `date-locale` for consistent formatting
|
||||||
|
3. **Use Base Locale**: When customizing, always extend from an existing locale using `createLocale`
|
||||||
|
4. **Test All Languages**: Verify your application works correctly with all supported languages
|
||||||
|
5. **Consider RTL**: Some languages (Arabic, Persian) require right-to-left layout support
|
||||||
|
6. **Sync with App i18n**: Keep Naive UI locale in sync with your application's i18n system
|
||||||
|
|
||||||
|
## Component-Specific Locale Keys
|
||||||
|
|
||||||
|
Different components have their own locale keys that can be customized:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const customLocale = createLocale({
|
||||||
|
// Button
|
||||||
|
Button: {
|
||||||
|
loadingText: 'Loading...'
|
||||||
|
},
|
||||||
|
// Input
|
||||||
|
Input: {
|
||||||
|
placeholder: 'Please input',
|
||||||
|
clear: 'Clear'
|
||||||
|
},
|
||||||
|
// DatePicker
|
||||||
|
DatePicker: {
|
||||||
|
placeholder: 'Select date',
|
||||||
|
clear: 'Clear',
|
||||||
|
confirm: 'OK',
|
||||||
|
now: 'Now'
|
||||||
|
},
|
||||||
|
// Table
|
||||||
|
DataTable: {
|
||||||
|
check: 'Check',
|
||||||
|
clear: 'Clear',
|
||||||
|
clearFilters: 'Clear filters',
|
||||||
|
clearSorter: 'Clear sorter'
|
||||||
|
},
|
||||||
|
// Transfer
|
||||||
|
Transfer: {
|
||||||
|
source: 'Source',
|
||||||
|
target: 'Target',
|
||||||
|
searchPlaceholder: 'Search',
|
||||||
|
clear: 'Clear'
|
||||||
|
},
|
||||||
|
// Upload
|
||||||
|
Upload: {
|
||||||
|
draggerClick: 'Click to upload',
|
||||||
|
draggerDrag: 'Drag files here',
|
||||||
|
fileDrag: 'Drag files here',
|
||||||
|
accept: 'Accept: {accept}',
|
||||||
|
upload: 'Upload',
|
||||||
|
retry: 'Retry',
|
||||||
|
remove: 'Remove',
|
||||||
|
cancel: 'Cancel'
|
||||||
|
}
|
||||||
|
}, enUS)
|
||||||
|
```
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
---
|
||||||
|
name: naive-ui-quickstart
|
||||||
|
description: Get started with Naive UI - a Vue 3 component library with comprehensive installation and setup guide
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: 1.0.0
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naive UI Quickstart
|
||||||
|
|
||||||
|
A comprehensive guide to installing and setting up Naive UI in your Vue 3 project.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this skill when you need to:
|
||||||
|
- Set up Naive UI in a new Vue 3 project
|
||||||
|
- Install Naive UI dependencies
|
||||||
|
- Configure basic Naive UI usage
|
||||||
|
- Understand the prerequisites for using Naive UI
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- **Vue 3**: Naive UI only supports Vue 3. If you are using Vue 2, consider other UI libraries.
|
||||||
|
- **Node.js**: Ensure you have Node.js installed (version 14+ recommended)
|
||||||
|
- **Package Manager**: npm, yarn, or pnpm
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Install Naive UI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i -D naive-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using yarn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn add -D naive-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using pnpm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm add -D naive-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Fonts
|
||||||
|
|
||||||
|
Naive UI uses vfonts for typography:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i -D vfonts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Icons (Recommended)
|
||||||
|
|
||||||
|
Naive UI recommends using [xicons](https://www.xicons.org) as the icon library:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm i -D @vicons/ionicons5
|
||||||
|
# or other icon packs
|
||||||
|
npm i -D @vicons/fluent
|
||||||
|
npm i -D @vicons/antd
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Global Registration
|
||||||
|
|
||||||
|
Register Naive UI globally in your main entry file:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// main.js
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import naive from 'naive-ui'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
app.use(naive)
|
||||||
|
app.mount('#app')
|
||||||
|
```
|
||||||
|
|
||||||
|
### On-Demand Import
|
||||||
|
|
||||||
|
Import components as needed:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-button @click="handleClick">Click Me</n-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { NButton } from 'naive-ui'
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
console.log('Button clicked!')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tree-Shaking Support
|
||||||
|
|
||||||
|
Naive UI supports tree-shaking out of the box. When using bundlers like Vite or webpack, only the components you import will be included in the final bundle.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// This will only bundle the Button component
|
||||||
|
import { NButton } from 'naive-ui'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### Using Config Provider
|
||||||
|
|
||||||
|
Wrap your application with `n-config-provider` for global configuration:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider>
|
||||||
|
<n-message-provider>
|
||||||
|
<n-dialog-provider>
|
||||||
|
<n-notification-provider>
|
||||||
|
<App />
|
||||||
|
</n-notification-provider>
|
||||||
|
</n-dialog-provider>
|
||||||
|
</n-message-provider>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
NConfigProvider,
|
||||||
|
NMessageProvider,
|
||||||
|
NDialogProvider,
|
||||||
|
NNotificationProvider
|
||||||
|
} from 'naive-ui'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Provider Hierarchy
|
||||||
|
|
||||||
|
| Provider | Purpose |
|
||||||
|
|----------|---------|
|
||||||
|
| `NConfigProvider` | Global configuration (theme, locale, etc.) |
|
||||||
|
| `NMessageProvider` | Message notification context |
|
||||||
|
| `NDialogProvider` | Dialog/Modal context |
|
||||||
|
| `NNotificationProvider` | Notification context |
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Basic Application Setup
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<!-- App.vue -->
|
||||||
|
<template>
|
||||||
|
<n-config-provider>
|
||||||
|
<n-message-provider>
|
||||||
|
<n-dialog-provider>
|
||||||
|
<n-notification-provider>
|
||||||
|
<div class="app-container">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</n-notification-provider>
|
||||||
|
</n-dialog-provider>
|
||||||
|
</n-message-provider>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
NConfigProvider,
|
||||||
|
NMessageProvider,
|
||||||
|
NDialogProvider,
|
||||||
|
NNotificationProvider
|
||||||
|
} from 'naive-ui'
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using with TypeScript
|
||||||
|
|
||||||
|
Naive UI is written in TypeScript and provides full type definitions:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-button type="primary" @click="handleClick">
|
||||||
|
Submit
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { NButton, ButtonProps } from 'naive-ui'
|
||||||
|
|
||||||
|
const handleClick: ButtonProps['onClick'] = (e) => {
|
||||||
|
console.log('Clicked', e)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Use On-Demand Imports**: Import only the components you need to reduce bundle size
|
||||||
|
2. **Set Up Providers Early**: Configure all necessary providers at the root level of your application
|
||||||
|
3. **Install Fonts**: Always install vfonts for consistent typography
|
||||||
|
4. **Use TypeScript**: Leverage Naive UI's TypeScript support for better development experience
|
||||||
|
5. **Check Browser Compatibility**: Naive UI supports modern browsers (Chrome, Firefox, Safari, Edge)
|
||||||
|
|
||||||
|
## Design Resources
|
||||||
|
|
||||||
|
- [Naive UI Design Library (Sketch)](https://naive-ui.oss-accelerate.aliyuncs.com/NaiveUI-Design-Library-en-US.sketch)
|
||||||
|
- [Official Documentation](https://www.naiveui.com)
|
||||||
|
- [GitHub Repository](https://github.com/tusen-projects/naive-ui)
|
||||||
@@ -0,0 +1,348 @@
|
|||||||
|
---
|
||||||
|
name: "naive-ui-ssr"
|
||||||
|
description: "Server-Side Rendering configuration and best practices for Naive UI. Invoke when user needs to implement SSR with Naive UI in Nuxt.js, Vitepress, Vite SSG/SSE, or Webpack environments."
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: "1.0.0"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naive UI Server-Side Rendering (SSR)
|
||||||
|
|
||||||
|
Naive UI uses CSS-in-JS, which requires additional configuration when using Server-Side Rendering (SSR). This skill provides guidance for setting up SSR across different frameworks and build tools.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
Use this skill when:
|
||||||
|
- **Nuxt.js integration**: Setting up Naive UI in a Nuxt.js application
|
||||||
|
- **Vitepress integration**: Using Naive UI components in Vitepress documentation
|
||||||
|
- **Vite SSG/SSE**: Implementing static site generation or server-side rendering with Vite
|
||||||
|
- **Webpack SSR**: Configuring SSR with Webpack-based setups
|
||||||
|
- **SSR optimization**: Reducing SSR-rendered HTML size
|
||||||
|
- **Troubleshooting SSR issues**: Resolving common SSR-related problems
|
||||||
|
|
||||||
|
## When to Invoke
|
||||||
|
|
||||||
|
Invoke this skill when:
|
||||||
|
- User asks about SSR setup with Naive UI
|
||||||
|
- User encounters SSR build failures or hydration issues
|
||||||
|
- User wants to optimize SSR performance
|
||||||
|
- User needs to configure Naive UI for Nuxt.js, Vitepress, or Vite SSR
|
||||||
|
- User sees CSS-related errors during SSR builds
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Critical Requirements
|
||||||
|
|
||||||
|
Before implementing SSR with Naive UI, ensure the following conditions are met:
|
||||||
|
|
||||||
|
1. **css-render version**: All direct and indirect references to `@css-render/*` and `css-render` packages must be version `>=0.15.14`
|
||||||
|
|
||||||
|
2. **Single package resolution**: Each `@css-render/*` and `css-render` package should resolve to a single target (no duplicate versions or copies)
|
||||||
|
|
||||||
|
### Verifying Requirements
|
||||||
|
|
||||||
|
Check your lock file for duplicate `css-render` packages:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# For npm
|
||||||
|
npm ls css-render
|
||||||
|
|
||||||
|
# For pnpm
|
||||||
|
pnpm ls css-render
|
||||||
|
|
||||||
|
# For yarn
|
||||||
|
yarn why css-render
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resolving Duplicate Packages
|
||||||
|
|
||||||
|
If you find duplicate packages, use the `resolution` field in `package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resolutions": {
|
||||||
|
"css-render": "^0.15.14",
|
||||||
|
"@css-render/vue3-ssr": "^0.15.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For pnpm, use `pnpm.overrides`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {
|
||||||
|
"css-render": "^0.15.14",
|
||||||
|
"@css-render/vue3-ssr": "^0.15.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
### Nuxt.js Integration
|
||||||
|
|
||||||
|
For Nuxt.js applications, refer to the dedicated Nuxt.js documentation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See Nuxt.js specific guide
|
||||||
|
# Path: docs/nuxtjs.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vitepress Integration
|
||||||
|
|
||||||
|
For Vitepress documentation sites:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See Vitepress specific guide
|
||||||
|
# Path: docs/vitepress.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vite SSG/SSE
|
||||||
|
|
||||||
|
For Vite-based static site generation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See Vite SSG/SSE specific guide
|
||||||
|
# Path: docs/vite-ssge.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webpack SSR Example
|
||||||
|
|
||||||
|
Reference implementation available at:
|
||||||
|
- GitHub: [naive-ui-vite-ssr](https://github.com/07akioni/naive-ui-vite-ssr)
|
||||||
|
- Playground: [naive-ui/playground/ssr](https://github.com/tusen-ai/naive-ui/tree/main/playground/ssr)
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### Inline Theme Optimization
|
||||||
|
|
||||||
|
| Prop | Type | Default | Description |
|
||||||
|
|------|------|---------|-------------|
|
||||||
|
| inline-theme-disabled | `boolean` | `false` | Disable inline theme styles on components to reduce SSR HTML size |
|
||||||
|
|
||||||
|
### Usage with n-config-provider
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider inline-theme-disabled>
|
||||||
|
<n-button>Optimized for SSR</n-button>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### SSR-Optimized Configuration
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<n-config-provider
|
||||||
|
inline-theme-disabled
|
||||||
|
:theme="theme"
|
||||||
|
>
|
||||||
|
<n-global-style />
|
||||||
|
<router-view />
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { darkTheme } from 'naive-ui'
|
||||||
|
|
||||||
|
const theme = ref(null)
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nuxt.js Plugin Setup
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// plugins/naive-ui.ts
|
||||||
|
import { setup } from '@css-render/vue3-ssr'
|
||||||
|
import { defineNuxtPlugin } from '#app'
|
||||||
|
|
||||||
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
|
if (process.server) {
|
||||||
|
const { collect } = setup(nuxtApp.vueApp)
|
||||||
|
const originalRenderMeta = nuxtApp.ssrContext?.renderMeta
|
||||||
|
|
||||||
|
nuxtApp.ssrContext = nuxtApp.ssrContext || {}
|
||||||
|
nuxtApp.ssrContext.renderMeta = () => {
|
||||||
|
if (!originalRenderMeta) {
|
||||||
|
return {
|
||||||
|
headTags: collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const originalMeta = originalRenderMeta()
|
||||||
|
if (originalMeta && typeof originalMeta === 'object') {
|
||||||
|
return {
|
||||||
|
...originalMeta,
|
||||||
|
headTags: `${originalMeta.headTags || ''}${collect()}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalMeta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vite SSR Entry Setup
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// server-entry.ts
|
||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
import { setup } from '@css-render/vue3-ssr'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
|
||||||
|
if (import.meta.env.SSR) {
|
||||||
|
setup(app)
|
||||||
|
}
|
||||||
|
|
||||||
|
return { app }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Collecting CSS in Vite SSR
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// server.ts
|
||||||
|
import { renderToString } from 'vue/server-renderer'
|
||||||
|
import { createApp } from './server-entry'
|
||||||
|
|
||||||
|
async function render(url: string) {
|
||||||
|
const { app } = createApp()
|
||||||
|
|
||||||
|
const ctx: { modules?: string[] } = {}
|
||||||
|
const html = await renderToString(app, ctx)
|
||||||
|
|
||||||
|
// CSS will be collected automatically by css-render
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
The following components have known issues in SSR environments. Avoid using them if possible:
|
||||||
|
|
||||||
|
| Component | Issue | Status |
|
||||||
|
|-----------|-------|--------|
|
||||||
|
| `n-scrollbar` | SSR rendering issues | Fixed in Vue >= 3.2.36 |
|
||||||
|
| `n-data-table` | SSR rendering issues | Fixed in Vue >= 3.2.36 |
|
||||||
|
| `n-anchor` | SSR rendering issues | Pending fix |
|
||||||
|
| `n-avatar-group` | SSR rendering issues | Pending fix |
|
||||||
|
| `n-watermark` | SSR rendering issues | Pending fix |
|
||||||
|
| `n-affix` | SSR rendering issues | Pending fix |
|
||||||
|
| `n-transfer` | SSR rendering issues | Pending fix |
|
||||||
|
|
||||||
|
### Workaround for Known Issues
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<ClientOnly>
|
||||||
|
<n-scrollbar>
|
||||||
|
<n-data-table :data="data" />
|
||||||
|
</n-scrollbar>
|
||||||
|
</ClientOnly>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ClientOnly } from '#components'
|
||||||
|
|
||||||
|
const data = ref([])
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Verify css-render versions**: Always check that all css-render packages are >= 0.15.14 and deduplicated
|
||||||
|
```bash
|
||||||
|
npm ls css-render
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Use inline-theme-disabled**: Enable this option to reduce SSR HTML size
|
||||||
|
```vue
|
||||||
|
<n-config-provider inline-theme-disabled>
|
||||||
|
<App />
|
||||||
|
</n-config-provider>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Wrap problematic components**: Use `ClientOnly` wrapper for components with known SSR issues
|
||||||
|
```vue
|
||||||
|
<ClientOnly>
|
||||||
|
<n-watermark content="Draft" />
|
||||||
|
</ClientOnly>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Check Vue version**: Ensure Vue >= 3.2.36 for `n-scrollbar` and `n-data-table` SSR support
|
||||||
|
|
||||||
|
5. **Test hydration**: Verify that client-side hydration works correctly
|
||||||
|
```js
|
||||||
|
// Check for hydration mismatches in console
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Use resolutions field**: Prevent duplicate css-render packages
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resolutions": {
|
||||||
|
"css-render": "^0.15.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
7. **Follow framework-specific guides**: Use the appropriate guide for your framework
|
||||||
|
- Nuxt.js: See nuxtjs documentation
|
||||||
|
- Vitepress: See vitepress documentation
|
||||||
|
- Vite SSG/SSE: See vite-ssge documentation
|
||||||
|
|
||||||
|
8. **Reference examples**: Check official examples for implementation patterns
|
||||||
|
- Vite SSR: [naive-ui-vite-ssr](https://github.com/07akioni/naive-ui-vite-ssr)
|
||||||
|
- Webpack SSR: [playground/ssr](https://github.com/tusen-ai/naive-ui/tree/main/playground/ssr)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Error: CSS Not Applied
|
||||||
|
|
||||||
|
**Problem**: Styles are missing after SSR hydration
|
||||||
|
|
||||||
|
**Solution**: Ensure css-render is properly configured for SSR
|
||||||
|
```ts
|
||||||
|
import { setup } from '@css-render/vue3-ssr'
|
||||||
|
|
||||||
|
if (import.meta.env.SSR) {
|
||||||
|
setup(app)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Error: Hydration Mismatch
|
||||||
|
|
||||||
|
**Problem**: Vue hydration mismatch warnings in console
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
1. Check for browser-only APIs in setup code
|
||||||
|
2. Wrap problematic components in `ClientOnly`
|
||||||
|
3. Ensure data is consistent between server and client
|
||||||
|
|
||||||
|
### Common Error: Duplicate css-render Packages
|
||||||
|
|
||||||
|
**Problem**: Build fails or styles break due to multiple css-render versions
|
||||||
|
|
||||||
|
**Solution**: Add resolutions to package.json
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"resolutions": {
|
||||||
|
"css-render": "^0.15.14",
|
||||||
|
"@css-render/vue3-ssr": "^0.15.14"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Skills
|
||||||
|
|
||||||
|
- [n-config-provider](../components/n-config-provider/SKILL.md): Global configuration for SSR optimization
|
||||||
|
- [naive-ui-theming](../naive-ui-theming/SKILL.md): Theme customization in SSR
|
||||||
|
- [naive-ui-dark-mode](../naive-ui-dark-mode/SKILL.md): Dark mode with SSR considerations
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
---
|
||||||
|
name: naive-ui-theming
|
||||||
|
description: Customize and apply themes in Naive UI including dark mode, theme variables, and creating themed components
|
||||||
|
metadata:
|
||||||
|
author: jiaiyan
|
||||||
|
version: 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:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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:
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* 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:
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<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>
|
||||||
|
```
|
||||||
@@ -0,0 +1,368 @@
|
|||||||
|
---
|
||||||
|
name: web-design-reviewer
|
||||||
|
description: 'This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like "review website design", "check the UI", "fix the layout", "find design problems". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Web Design Reviewer
|
||||||
|
|
||||||
|
This skill enables visual inspection and validation of website design quality, identifying and fixing issues at the source code level.
|
||||||
|
|
||||||
|
## Scope of Application
|
||||||
|
|
||||||
|
- Static sites (HTML/CSS/JS)
|
||||||
|
- SPA frameworks such as React / Vue / Angular / Svelte
|
||||||
|
- Full-stack frameworks such as Next.js / Nuxt / SvelteKit
|
||||||
|
- CMS platforms such as WordPress / Drupal
|
||||||
|
- Any other web application
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Required
|
||||||
|
|
||||||
|
1. **Target website must be running**
|
||||||
|
- Local development server (e.g., `http://localhost:3000`)
|
||||||
|
- Staging environment
|
||||||
|
- Production environment (for read-only reviews)
|
||||||
|
|
||||||
|
2. **Browser automation must be available**
|
||||||
|
- Screenshot capture
|
||||||
|
- Page navigation
|
||||||
|
- DOM information retrieval
|
||||||
|
|
||||||
|
3. **Access to source code (when making fixes)**
|
||||||
|
- Project must exist within the workspace
|
||||||
|
|
||||||
|
## Workflow Overview
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A[Step 1: Information Gathering] --> B[Step 2: Visual Inspection]
|
||||||
|
B --> C[Step 3: Issue Fixing]
|
||||||
|
C --> D[Step 4: Re-verification]
|
||||||
|
D --> E{Issues Remaining?}
|
||||||
|
E -->|Yes| B
|
||||||
|
E -->|No| F[Completion Report]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 1: Information Gathering Phase
|
||||||
|
|
||||||
|
### 1.1 URL Confirmation
|
||||||
|
|
||||||
|
If the URL is not provided, ask the user:
|
||||||
|
|
||||||
|
> Please provide the URL of the website to review (e.g., `http://localhost:3000`)
|
||||||
|
|
||||||
|
### 1.2 Understanding Project Structure
|
||||||
|
|
||||||
|
When making fixes, gather the following information:
|
||||||
|
|
||||||
|
| Item | Example Question |
|
||||||
|
|------|------------------|
|
||||||
|
| Framework | Are you using React / Vue / Next.js, etc.? |
|
||||||
|
| Styling Method | CSS / SCSS / Tailwind / CSS-in-JS, etc. |
|
||||||
|
| Source Location | Where are style files and components located? |
|
||||||
|
| Review Scope | Specific pages only or entire site? |
|
||||||
|
|
||||||
|
### 1.3 Automatic Project Detection
|
||||||
|
|
||||||
|
Attempt automatic detection from files in the workspace:
|
||||||
|
|
||||||
|
```
|
||||||
|
Detection targets:
|
||||||
|
├── package.json → Framework and dependencies
|
||||||
|
├── tsconfig.json → TypeScript usage
|
||||||
|
├── tailwind.config → Tailwind CSS
|
||||||
|
├── next.config → Next.js
|
||||||
|
├── vite.config → Vite
|
||||||
|
├── nuxt.config → Nuxt
|
||||||
|
└── src/ or app/ → Source directory
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 Identifying Styling Method
|
||||||
|
|
||||||
|
| Method | Detection | Edit Target |
|
||||||
|
|--------|-----------|-------------|
|
||||||
|
| Pure CSS | `*.css` files | Global CSS or component CSS |
|
||||||
|
| SCSS/Sass | `*.scss`, `*.sass` | SCSS files |
|
||||||
|
| CSS Modules | `*.module.css` | Module CSS files |
|
||||||
|
| Tailwind CSS | `tailwind.config.*` | className in components |
|
||||||
|
| styled-components | `styled.` in code | JS/TS files |
|
||||||
|
| Emotion | `@emotion/` imports | JS/TS files |
|
||||||
|
| CSS-in-JS (other) | Inline styles | JS/TS files |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 2: Visual Inspection Phase
|
||||||
|
|
||||||
|
### 2.1 Page Traversal
|
||||||
|
|
||||||
|
1. Navigate to the specified URL
|
||||||
|
2. Capture screenshots
|
||||||
|
3. Retrieve DOM structure/snapshot (if possible)
|
||||||
|
4. If additional pages exist, traverse through navigation
|
||||||
|
|
||||||
|
### 2.2 Inspection Items
|
||||||
|
|
||||||
|
#### Layout Issues
|
||||||
|
|
||||||
|
| Issue | Description | Severity |
|
||||||
|
|-------|-------------|----------|
|
||||||
|
| Element Overflow | Content overflows from parent element or viewport | High |
|
||||||
|
| Element Overlap | Unintended overlapping of elements | High |
|
||||||
|
| Alignment Issues | Grid or flex alignment problems | Medium |
|
||||||
|
| Inconsistent Spacing | Padding/margin inconsistencies | Medium |
|
||||||
|
| Text Clipping | Long text not handled properly | Medium |
|
||||||
|
|
||||||
|
#### Responsive Issues
|
||||||
|
|
||||||
|
| Issue | Description | Severity |
|
||||||
|
|-------|-------------|----------|
|
||||||
|
| Non-mobile Friendly | Layout breaks on small screens | High |
|
||||||
|
| Breakpoint Issues | Unnatural transitions when screen size changes | Medium |
|
||||||
|
| Touch Targets | Buttons too small on mobile | Medium |
|
||||||
|
|
||||||
|
#### Accessibility Issues
|
||||||
|
|
||||||
|
| Issue | Description | Severity |
|
||||||
|
|-------|-------------|----------|
|
||||||
|
| Insufficient Contrast | Low contrast ratio between text and background | High |
|
||||||
|
| No Focus State | Cannot determine state during keyboard navigation | High |
|
||||||
|
| Missing alt Text | No alternative text for images | Medium |
|
||||||
|
|
||||||
|
#### Visual Consistency
|
||||||
|
|
||||||
|
| Issue | Description | Severity |
|
||||||
|
|-------|-------------|----------|
|
||||||
|
| Font Inconsistency | Mixed font families | Medium |
|
||||||
|
| Color Inconsistency | Non-unified brand colors | Medium |
|
||||||
|
| Spacing Inconsistency | Non-uniform spacing between similar elements | Low |
|
||||||
|
|
||||||
|
### 2.3 Viewport Testing (Responsive)
|
||||||
|
|
||||||
|
Test at the following viewports:
|
||||||
|
|
||||||
|
| Name | Width | Representative Device |
|
||||||
|
|------|-------|----------------------|
|
||||||
|
| Mobile | 375px | iPhone SE/12 mini |
|
||||||
|
| Tablet | 768px | iPad |
|
||||||
|
| Desktop | 1280px | Standard PC |
|
||||||
|
| Wide | 1920px | Large display |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 3: Issue Fixing Phase
|
||||||
|
|
||||||
|
### 3.1 Issue Prioritization
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
block-beta
|
||||||
|
columns 1
|
||||||
|
block:priority["Priority Matrix"]
|
||||||
|
P1["P1: Fix Immediately\n(Layout issues affecting functionality)"]
|
||||||
|
P2["P2: Fix Next\n(Visual issues degrading UX)"]
|
||||||
|
P3["P3: Fix If Possible\n(Minor visual inconsistencies)"]
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Identifying Source Files
|
||||||
|
|
||||||
|
Identify source files from problematic elements:
|
||||||
|
|
||||||
|
1. **Selector-based Search**
|
||||||
|
- Search codebase by class name or ID
|
||||||
|
- Explore style definitions with `grep_search`
|
||||||
|
|
||||||
|
2. **Component-based Search**
|
||||||
|
- Identify components from element text or structure
|
||||||
|
- Explore related files with `semantic_search`
|
||||||
|
|
||||||
|
3. **File Pattern Filtering**
|
||||||
|
```
|
||||||
|
Style files: src/**/*.css, styles/**/*
|
||||||
|
Components: src/components/**/*
|
||||||
|
Pages: src/pages/**, app/**
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 Applying Fixes
|
||||||
|
|
||||||
|
#### Framework-specific Fix Guidelines
|
||||||
|
|
||||||
|
See [references/framework-fixes.md](references/framework-fixes.md) for details.
|
||||||
|
|
||||||
|
#### Fix Principles
|
||||||
|
|
||||||
|
1. **Minimal Changes**: Only make the minimum changes necessary to resolve the issue
|
||||||
|
2. **Respect Existing Patterns**: Follow existing code style in the project
|
||||||
|
3. **Avoid Breaking Changes**: Be careful not to affect other areas
|
||||||
|
4. **Add Comments**: Add comments to explain the reason for fixes where appropriate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 4: Re-verification Phase
|
||||||
|
|
||||||
|
### 4.1 Post-fix Confirmation
|
||||||
|
|
||||||
|
1. Reload browser (or wait for development server HMR)
|
||||||
|
2. Capture screenshots of fixed areas
|
||||||
|
3. Compare before and after
|
||||||
|
|
||||||
|
### 4.2 Regression Testing
|
||||||
|
|
||||||
|
- Verify that fixes haven't affected other areas
|
||||||
|
- Confirm responsive display is not broken
|
||||||
|
|
||||||
|
### 4.3 Iteration Decision
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A{Issues Remaining?}
|
||||||
|
A -->|Yes| B[Return to Step 2]
|
||||||
|
A -->|No| C[Proceed to Completion Report]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Iteration Limit**: If more than 3 fix attempts are needed for a specific issue, consult the user
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
### Review Results Report
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Web Design Review Results
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Item | Value |
|
||||||
|
|------|-------|
|
||||||
|
| Target URL | {URL} |
|
||||||
|
| Framework | {Detected framework} |
|
||||||
|
| Styling | {CSS / Tailwind / etc.} |
|
||||||
|
| Tested Viewports | Desktop, Mobile |
|
||||||
|
| Issues Detected | {N} |
|
||||||
|
| Issues Fixed | {M} |
|
||||||
|
|
||||||
|
## Detected Issues
|
||||||
|
|
||||||
|
### [P1] {Issue Title}
|
||||||
|
|
||||||
|
- **Page**: {Page path}
|
||||||
|
- **Element**: {Selector or description}
|
||||||
|
- **Issue**: {Detailed description of the issue}
|
||||||
|
- **Fixed File**: `{File path}`
|
||||||
|
- **Fix Details**: {Description of changes}
|
||||||
|
- **Screenshot**: Before/After
|
||||||
|
|
||||||
|
### [P2] {Issue Title}
|
||||||
|
...
|
||||||
|
|
||||||
|
## Unfixed Issues (if any)
|
||||||
|
|
||||||
|
### {Issue Title}
|
||||||
|
- **Reason**: {Why it was not fixed/could not be fixed}
|
||||||
|
- **Recommended Action**: {Recommendations for user}
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
- {Suggestions for future improvements}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required Capabilities
|
||||||
|
|
||||||
|
| Capability | Description | Required |
|
||||||
|
|------------|-------------|----------|
|
||||||
|
| Web Page Navigation | Access URLs, page transitions | ✅ |
|
||||||
|
| Screenshot Capture | Page image capture | ✅ |
|
||||||
|
| Image Analysis | Visual issue detection | ✅ |
|
||||||
|
| DOM Retrieval | Page structure retrieval | Recommended |
|
||||||
|
| File Read/Write | Source code reading and editing | Required for fixes |
|
||||||
|
| Code Search | Code search within project | Required for fixes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reference Implementation
|
||||||
|
|
||||||
|
### Implementation with Playwright MCP
|
||||||
|
|
||||||
|
[Playwright MCP](https://github.com/microsoft/playwright-mcp) is recommended as the reference implementation for this skill.
|
||||||
|
|
||||||
|
| Capability | Playwright MCP Tool | Purpose |
|
||||||
|
|------------|---------------------|---------|
|
||||||
|
| Navigation | `browser_navigate` | Access URLs |
|
||||||
|
| Snapshot | `browser_snapshot` | Retrieve DOM structure |
|
||||||
|
| Screenshot | `browser_take_screenshot` | Images for visual inspection |
|
||||||
|
| Click | `browser_click` | Interact with interactive elements |
|
||||||
|
| Resize | `browser_resize` | Responsive testing |
|
||||||
|
| Console | `browser_console_messages` | Detect JS errors |
|
||||||
|
|
||||||
|
#### Configuration Example (MCP Server)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"playwright": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": ["-y", "@playwright/mcp@latest", "--caps=vision"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Compatible Browser Automation Tools
|
||||||
|
|
||||||
|
| Tool | Features |
|
||||||
|
|------|----------|
|
||||||
|
| Selenium | Broad browser support, multi-language support |
|
||||||
|
| Puppeteer | Chrome/Chromium focused, Node.js |
|
||||||
|
| Cypress | Easy integration with E2E testing |
|
||||||
|
| WebDriver BiDi | Standardized next-generation protocol |
|
||||||
|
|
||||||
|
The same workflow can be implemented with these tools. As long as they provide the necessary capabilities (navigation, screenshot, DOM retrieval), the choice of tool is flexible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### DO (Recommended)
|
||||||
|
|
||||||
|
- ✅ Always save screenshots before making fixes
|
||||||
|
- ✅ Fix one issue at a time and verify each
|
||||||
|
- ✅ Follow the project's existing code style
|
||||||
|
- ✅ Confirm with user before major changes
|
||||||
|
- ✅ Document fix details thoroughly
|
||||||
|
|
||||||
|
### DON'T (Not Recommended)
|
||||||
|
|
||||||
|
- ❌ Large-scale refactoring without confirmation
|
||||||
|
- ❌ Ignoring design systems or brand guidelines
|
||||||
|
- ❌ Fixes that ignore performance
|
||||||
|
- ❌ Fixing multiple issues at once (difficult to verify)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Problem: Style files not found
|
||||||
|
|
||||||
|
1. Check dependencies in `package.json`
|
||||||
|
2. Consider the possibility of CSS-in-JS
|
||||||
|
3. Consider CSS generated at build time
|
||||||
|
4. Ask user about styling method
|
||||||
|
|
||||||
|
### Problem: Fixes not reflected
|
||||||
|
|
||||||
|
1. Check if development server HMR is working
|
||||||
|
2. Clear browser cache
|
||||||
|
3. Rebuild if project requires build
|
||||||
|
4. Check CSS specificity issues
|
||||||
|
|
||||||
|
### Problem: Fixes affecting other areas
|
||||||
|
|
||||||
|
1. Rollback changes
|
||||||
|
2. Use more specific selectors
|
||||||
|
3. Consider using CSS Modules or scoped styles
|
||||||
|
4. Consult user to confirm impact scope
|
||||||
@@ -0,0 +1,475 @@
|
|||||||
|
# Framework-specific Fix Guide
|
||||||
|
|
||||||
|
This document explains specific fix techniques for each framework and styling method.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pure CSS / SCSS
|
||||||
|
|
||||||
|
### Fixing Layout Overflow
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Before: Overflow occurs */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After: Control overflow */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Text Clipping Prevention
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Single line truncation */
|
||||||
|
.text-truncate {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multi-line truncation */
|
||||||
|
.text-clamp {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Word wrapping */
|
||||||
|
.text-wrap {
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
hyphens: auto;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spacing Unification
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Unify spacing with CSS custom properties */
|
||||||
|
:root {
|
||||||
|
--spacing-xs: 0.25rem;
|
||||||
|
--spacing-sm: 0.5rem;
|
||||||
|
--spacing-md: 1rem;
|
||||||
|
--spacing-lg: 1.5rem;
|
||||||
|
--spacing-xl: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
margin-bottom: var(--spacing-lg);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Improving Contrast
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Before: Insufficient contrast */
|
||||||
|
.text {
|
||||||
|
color: #999999;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After: Meets WCAG AA standards */
|
||||||
|
.text {
|
||||||
|
color: #595959; /* Contrast ratio 7:1 */
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tailwind CSS
|
||||||
|
|
||||||
|
### Layout Fixes
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
{/* Before: Overflow */}
|
||||||
|
<div className="w-full">
|
||||||
|
<img src="..." />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* After: Overflow control */}
|
||||||
|
<div className="w-full max-w-full overflow-hidden">
|
||||||
|
<img src="..." className="w-full h-auto object-contain" />
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Text Clipping Prevention
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
{/* Single line truncation */}
|
||||||
|
<p className="truncate">Long text...</p>
|
||||||
|
|
||||||
|
{/* Multi-line truncation */}
|
||||||
|
<p className="line-clamp-3">Long text...</p>
|
||||||
|
|
||||||
|
{/* Allow wrapping */}
|
||||||
|
<p className="break-words">Long text...</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responsive Support
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
{/* Mobile-first responsive */}
|
||||||
|
<div className="
|
||||||
|
flex flex-col gap-4
|
||||||
|
md:flex-row md:gap-6
|
||||||
|
lg:gap-8
|
||||||
|
">
|
||||||
|
<div className="w-full md:w-1/2 lg:w-1/3">
|
||||||
|
Content
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Spacing Unification (Tailwind Config)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// tailwind.config.js
|
||||||
|
module.exports = {
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
spacing: {
|
||||||
|
'18': '4.5rem',
|
||||||
|
'22': '5.5rem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessibility Improvements
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
{/* Add focus state */}
|
||||||
|
<button className="
|
||||||
|
bg-blue-500 text-white
|
||||||
|
hover:bg-blue-600
|
||||||
|
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
|
||||||
|
">
|
||||||
|
Button
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Improve contrast */}
|
||||||
|
<p className="text-gray-700 bg-white"> {/* Changed from text-gray-500 */}
|
||||||
|
Readable text
|
||||||
|
</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## React + CSS Modules
|
||||||
|
|
||||||
|
### Fixes in Module Scope
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Component.module.css */
|
||||||
|
|
||||||
|
/* Before */
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After: Add overflow control */
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component-side Fixes
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// Component.jsx
|
||||||
|
import styles from './Component.module.css';
|
||||||
|
|
||||||
|
// Before
|
||||||
|
<div className={styles.container}>
|
||||||
|
|
||||||
|
// After: Add conditional class
|
||||||
|
<div className={`${styles.container} ${isOverflow ? styles.overflow : ''}`}>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## styled-components / Emotion
|
||||||
|
|
||||||
|
### Style Fixes
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// Before
|
||||||
|
const Container = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// After
|
||||||
|
const Container = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responsive Support
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
const Card = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 1.5rem;
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Consistency with Theme
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// theme.js
|
||||||
|
export const theme = {
|
||||||
|
colors: {
|
||||||
|
primary: '#2563eb',
|
||||||
|
text: '#1f2937',
|
||||||
|
textLight: '#4b5563', // Improved contrast
|
||||||
|
},
|
||||||
|
spacing: {
|
||||||
|
sm: '0.5rem',
|
||||||
|
md: '1rem',
|
||||||
|
lg: '1.5rem',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
const Text = styled.p`
|
||||||
|
color: ${({ theme }) => theme.colors.text};
|
||||||
|
margin-bottom: ${({ theme }) => theme.spacing.md};
|
||||||
|
`;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vue (Scoped Styles)
|
||||||
|
|
||||||
|
### Fixing Scoped Styles
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<p class="text">Content</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Applied only to this component */
|
||||||
|
.container {
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
/* Fix: Improve contrast */
|
||||||
|
color: #374151; /* Was: #9ca3af */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deep Selectors (Affecting Child Components)
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<style scoped>
|
||||||
|
/* Override child component styles (use cautiously) */
|
||||||
|
:deep(.child-class) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next.js / App Router
|
||||||
|
|
||||||
|
### Global Style Fixes
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* app/globals.css */
|
||||||
|
:root {
|
||||||
|
--foreground: #171717;
|
||||||
|
--background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent layout overflow */
|
||||||
|
html, body {
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent image overflow */
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fixes in Layout Components
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// app/layout.tsx
|
||||||
|
export default function RootLayout({ children }) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body className="min-h-screen flex flex-col">
|
||||||
|
<header className="sticky top-0 z-50">
|
||||||
|
{/* Header */}
|
||||||
|
</header>
|
||||||
|
<main className="flex-1 container mx-auto px-4 py-8">
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
<footer>
|
||||||
|
{/* Footer */}
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Fixing Flexbox Layout Issues
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Before: Items overflow */
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After: Wrap and size control */
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-item {
|
||||||
|
flex: 1 1 300px; /* grow, shrink, basis */
|
||||||
|
min-width: 0; /* Prevent flexbox overflow issues */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fixing Grid Layout Issues
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Before: Fixed column count */
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After: Auto-adjust */
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Organizing z-index
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Systematize z-index */
|
||||||
|
:root {
|
||||||
|
--z-dropdown: 100;
|
||||||
|
--z-sticky: 200;
|
||||||
|
--z-modal-backdrop: 300;
|
||||||
|
--z-modal: 400;
|
||||||
|
--z-tooltip: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
z-index: var(--z-modal);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding Focus States
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Add focus state to all interactive elements */
|
||||||
|
button:focus-visible,
|
||||||
|
a:focus-visible,
|
||||||
|
input:focus-visible,
|
||||||
|
select:focus-visible,
|
||||||
|
textarea:focus-visible {
|
||||||
|
outline: 2px solid #2563eb;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Customize focus ring */
|
||||||
|
.custom-focus:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.5);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Debugging Techniques
|
||||||
|
|
||||||
|
### Visualizing Element Boundaries
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* Use only during development */
|
||||||
|
* {
|
||||||
|
outline: 1px solid red !important;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Detecting Overflow
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Run in console to detect overflow elements
|
||||||
|
document.querySelectorAll('*').forEach(el => {
|
||||||
|
if (el.scrollWidth > el.clientWidth) {
|
||||||
|
console.log('Horizontal overflow:', el);
|
||||||
|
}
|
||||||
|
if (el.scrollHeight > el.clientHeight) {
|
||||||
|
console.log('Vertical overflow:', el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checking Contrast Ratio
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Use Chrome DevTools Lighthouse or axe DevTools
|
||||||
|
// Or check at the following site:
|
||||||
|
// https://webaim.org/resources/contrastchecker/
|
||||||
|
```
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
# Visual Inspection Checklist
|
||||||
|
|
||||||
|
This document is a comprehensive checklist of items to verify during web design visual inspection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Layout Verification
|
||||||
|
|
||||||
|
### Structural Integrity
|
||||||
|
|
||||||
|
- [ ] Header is correctly fixed/positioned at the top of the screen
|
||||||
|
- [ ] Footer is positioned at the bottom of the screen or end of content
|
||||||
|
- [ ] Main content area is center-aligned with appropriate width
|
||||||
|
- [ ] Sidebar (if present) is positioned correctly
|
||||||
|
- [ ] Navigation is displayed in the intended position
|
||||||
|
|
||||||
|
### Overflow
|
||||||
|
|
||||||
|
- [ ] Horizontal scrollbar is not unintentionally displayed
|
||||||
|
- [ ] Content does not overflow from parent elements
|
||||||
|
- [ ] Images fit within parent containers
|
||||||
|
- [ ] Tables do not exceed container width
|
||||||
|
- [ ] Code blocks wrap or scroll appropriately
|
||||||
|
|
||||||
|
### Alignment
|
||||||
|
|
||||||
|
- [ ] Grid items are evenly distributed
|
||||||
|
- [ ] Flex item alignment is correct
|
||||||
|
- [ ] Text alignment (left/center/right) is consistent
|
||||||
|
- [ ] Icons and text are vertically aligned
|
||||||
|
- [ ] Form labels and input fields are correctly positioned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Typography Verification
|
||||||
|
|
||||||
|
### Readability
|
||||||
|
|
||||||
|
- [ ] Body text font size is sufficient (minimum 16px recommended)
|
||||||
|
- [ ] Line height is appropriate (1.5-1.8 recommended)
|
||||||
|
- [ ] Characters per line is appropriate (40-80 characters recommended)
|
||||||
|
- [ ] Spacing between paragraphs is sufficient
|
||||||
|
- [ ] Heading size hierarchy is clear
|
||||||
|
|
||||||
|
### Text Handling
|
||||||
|
|
||||||
|
- [ ] Long words wrap appropriately
|
||||||
|
- [ ] URLs and code are handled properly
|
||||||
|
- [ ] No text clipping occurs
|
||||||
|
- [ ] Ellipsis (...) displays correctly
|
||||||
|
- [ ] Language-specific line breaking rules work correctly
|
||||||
|
|
||||||
|
### Fonts
|
||||||
|
|
||||||
|
- [ ] Web fonts load correctly
|
||||||
|
- [ ] Fallback fonts are appropriate
|
||||||
|
- [ ] Font weights are as intended
|
||||||
|
- [ ] Special characters and emoji display correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Color & Contrast Verification
|
||||||
|
|
||||||
|
### Accessibility (WCAG Standards)
|
||||||
|
|
||||||
|
- [ ] Body text: Contrast ratio 4.5:1 or higher (AA)
|
||||||
|
- [ ] Large text (18px+ bold or 24px+): 3:1 or higher
|
||||||
|
- [ ] Interactive element borders: 3:1 or higher
|
||||||
|
- [ ] Focus indicators: Sufficient contrast with background
|
||||||
|
|
||||||
|
### Color Consistency
|
||||||
|
|
||||||
|
- [ ] Brand colors are unified
|
||||||
|
- [ ] Link colors are consistent
|
||||||
|
- [ ] Error state red is unified
|
||||||
|
- [ ] Success state green is unified
|
||||||
|
- [ ] Hover/active state colors are appropriate
|
||||||
|
|
||||||
|
### Color Vision Diversity
|
||||||
|
|
||||||
|
- [ ] Information conveyed by shape and text, not just color
|
||||||
|
- [ ] Charts and diagrams consider color vision diversity
|
||||||
|
- [ ] Error messages don't rely solely on color
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Responsive Verification
|
||||||
|
|
||||||
|
### Mobile (~640px)
|
||||||
|
|
||||||
|
- [ ] Content fits within screen width
|
||||||
|
- [ ] Touch targets are 44x44px or larger
|
||||||
|
- [ ] Text is readable size
|
||||||
|
- [ ] No horizontal scrolling occurs
|
||||||
|
- [ ] Navigation is mobile-friendly (hamburger menu, etc.)
|
||||||
|
- [ ] Form inputs are easy to use
|
||||||
|
|
||||||
|
### Tablet (641px~1024px)
|
||||||
|
|
||||||
|
- [ ] Layout is optimized for tablet
|
||||||
|
- [ ] Two-column layouts display appropriately
|
||||||
|
- [ ] Image sizes are appropriate
|
||||||
|
- [ ] Sidebar show/hide is appropriate
|
||||||
|
|
||||||
|
### Desktop (1025px~)
|
||||||
|
|
||||||
|
- [ ] Maximum width is set and doesn't break on extra-large screens
|
||||||
|
- [ ] Spacing is sufficient
|
||||||
|
- [ ] Multi-column layouts function correctly
|
||||||
|
- [ ] Hover states are implemented
|
||||||
|
|
||||||
|
### Breakpoint Transitions
|
||||||
|
|
||||||
|
- [ ] Layout transitions smoothly when screen size changes
|
||||||
|
- [ ] Layout doesn't break at intermediate sizes
|
||||||
|
- [ ] No content disappears or duplicates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Interactive Element Verification
|
||||||
|
|
||||||
|
### Buttons
|
||||||
|
|
||||||
|
- [ ] Default state is clear
|
||||||
|
- [ ] Hover state exists (desktop)
|
||||||
|
- [ ] Focus state is visually clear
|
||||||
|
- [ ] Active (pressed) state exists
|
||||||
|
- [ ] Disabled state is distinguishable
|
||||||
|
- [ ] Loading state (if applicable)
|
||||||
|
|
||||||
|
### Links
|
||||||
|
|
||||||
|
- [ ] Links are visually identifiable
|
||||||
|
- [ ] Visited links are distinguishable (if needed)
|
||||||
|
- [ ] Hover state exists
|
||||||
|
- [ ] Focus state is clear
|
||||||
|
|
||||||
|
### Form Elements
|
||||||
|
|
||||||
|
- [ ] Input field boundaries are clear
|
||||||
|
- [ ] Placeholder text contrast is appropriate
|
||||||
|
- [ ] Visual feedback on focus
|
||||||
|
- [ ] Error state display
|
||||||
|
- [ ] Required field indication
|
||||||
|
- [ ] Dropdowns function correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Images & Media Verification
|
||||||
|
|
||||||
|
### Images
|
||||||
|
|
||||||
|
- [ ] Images display at appropriate size
|
||||||
|
- [ ] Aspect ratio is maintained
|
||||||
|
- [ ] High resolution display support (@2x)
|
||||||
|
- [ ] Display when image fails to load
|
||||||
|
- [ ] Lazy loading behavior works
|
||||||
|
|
||||||
|
### Video & Embeds
|
||||||
|
|
||||||
|
- [ ] Videos fit within containers
|
||||||
|
- [ ] Aspect ratio is maintained
|
||||||
|
- [ ] Embedded content is responsive
|
||||||
|
- [ ] iframes don't overflow
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Accessibility Verification
|
||||||
|
|
||||||
|
### Keyboard Navigation
|
||||||
|
|
||||||
|
- [ ] All interactive elements accessible via Tab key
|
||||||
|
- [ ] Focus order is logical
|
||||||
|
- [ ] Focus traps are appropriate (modals, etc.)
|
||||||
|
- [ ] Skip to content link exists
|
||||||
|
|
||||||
|
### Screen Reader Support
|
||||||
|
|
||||||
|
- [ ] Images have alt text
|
||||||
|
- [ ] Forms have labels
|
||||||
|
- [ ] ARIA labels are appropriately set
|
||||||
|
- [ ] Heading hierarchy is correct (h1→h2→h3...)
|
||||||
|
|
||||||
|
### Motion
|
||||||
|
|
||||||
|
- [ ] Animations are not excessive
|
||||||
|
- [ ] prefers-reduced-motion is supported (if possible)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Performance-related Visual Issues
|
||||||
|
|
||||||
|
### Loading
|
||||||
|
|
||||||
|
- [ ] Font FOUT/FOIT is minimal
|
||||||
|
- [ ] No layout shift (CLS) occurs
|
||||||
|
- [ ] No jumping when images load
|
||||||
|
- [ ] Skeleton screens are appropriate (if applicable)
|
||||||
|
|
||||||
|
### Animation
|
||||||
|
|
||||||
|
- [ ] Animations are smooth (60fps)
|
||||||
|
- [ ] No performance issues when scrolling
|
||||||
|
- [ ] Transitions are natural
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Priority Matrix
|
||||||
|
|
||||||
|
| Priority | Category | Examples |
|
||||||
|
|----------|----------|----------|
|
||||||
|
| P0 (Critical) | Functionality breaking | Complete element overlap, content disappearance |
|
||||||
|
| P1 (High) | Serious UX issues | Unreadable text, inoperable buttons |
|
||||||
|
| P2 (Medium) | Moderate issues | Alignment issues, spacing inconsistencies |
|
||||||
|
| P3 (Low) | Minor issues | Slight positioning differences, minor color variations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification Tools
|
||||||
|
|
||||||
|
### Browser DevTools
|
||||||
|
|
||||||
|
- Elements panel: DOM and style inspection
|
||||||
|
- Lighthouse: Performance and accessibility audits
|
||||||
|
- Device toolbar: Responsive testing
|
||||||
|
|
||||||
|
### Accessibility Tools
|
||||||
|
|
||||||
|
- axe DevTools
|
||||||
|
- WAVE
|
||||||
|
- Color Contrast Analyzer
|
||||||
|
|
||||||
|
### Automation Tools
|
||||||
|
|
||||||
|
- Playwright (screenshot comparison)
|
||||||
|
- Percy / Chromatic (Visual Regression Testing)
|
||||||
Reference in New Issue
Block a user