feat(menu): inlineThemeDisabled

This commit is contained in:
07akioni 2022-02-16 01:34:43 +08:00
parent 4b76544bc0
commit 591fb4b646
27 changed files with 541 additions and 486 deletions

View File

@ -28,7 +28,7 @@
"gen-volar-dts": "esno scripts/gen-component-declaration",
"build:site:ts": "./scripts/pre-build-site/pre-build-site.sh && cross-env TUSIMPLE=true NODE_ENV=production NODE_OPTIONS=--max-old-space-size=4096 vite build && ./scripts/post-build-site/post-build-site.sh",
"prepare": "husky install",
"transpile-docs": "node scripts/md-to-vue slider",
"transpile-docs": "node scripts/md-to-vue menu",
"release:site": "cross-env TUSIMPLE=true pnpm run build:site && node build-doc/generate-deploy-sh.js && sudo bash build-doc/deploy-doc.sh"
},
"author": "07akioni",

View File

@ -21,7 +21,7 @@ import { VResizeObserver } from 'vueuc'
import { on, off } from 'evtd'
import { useConfig, useTheme, useThemeClass } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { flatten, keep } from '../../_utils'
import { flatten, keep, resolveSlotWithProps } from '../../_utils'
import type { ExtractPublicPropTypes } from '../../_utils'
import { carouselLight } from '../styles'
import type { CarouselTheme } from '../styles'
@ -930,20 +930,22 @@ export default defineComponent({
}}
</VResizeObserver>
{this.showDots &&
(dotsSlot
? dotsSlot(dotSlotProps)
: dotSlotProps.total > 1 && (
<NCarouselDots
key={dotType + dotPlacement}
total={dotSlotProps.total}
currentIndex={dotSlotProps.currentIndex}
dotType={dotType}
trigger={this.trigger}
keyboard={this.keyboard}
/>
))}
resolveSlotWithProps(dotsSlot, dotSlotProps, () => [
dotSlotProps.total > 1 && (
<NCarouselDots
key={dotType + dotPlacement}
total={dotSlotProps.total}
currentIndex={dotSlotProps.currentIndex}
dotType={dotType}
trigger={this.trigger}
keyboard={this.keyboard}
/>
)
])}
{showArrow &&
(arrowSlot ? arrowSlot(arrowSlotProps) : <NCarouselArrow />)}
resolveSlotWithProps(arrowSlot, arrowSlotProps, () => [
<NCarouselArrow />
])}
</div>
)
}

View File

@ -1,17 +1,19 @@
<markdown>
# Accordion
Like an accordion. You can use `accordion` prop to switch this mode for the first-level menu.
</markdown>
```html
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
accordion
/>
```
<template>
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
accordion
/>
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
FishOutline as FishIcon,
@ -19,7 +21,7 @@ import {
BagOutline as BagOutlineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -83,4 +85,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,38 +1,40 @@
<markdown>
# Collapsed Menu
Use collapsable vertical menu with layout sider. Use `collapsed` to control collapse status of menu. You must set `collapsed-width` to make it collapse in a right manner. There are still some other collapse related props you can modify: `icon-size`, `collapsed-icon-size`. For details see API table at the bottom of the page.
</markdown>
```html
<n-space vertical>
<n-switch v-model:value="collapsed" />
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-space vertical>
<n-switch v-model:value="collapsed" />
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
v-model:value="activeKey"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
v-model:value="activeKey"
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -40,7 +42,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -128,4 +130,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,35 +1,37 @@
<markdown>
# Customizing Field
Various data would come from backend, you can customize `key`, `label` and `children`'s field name.
</markdown>
```html
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
key-field="whateverKey"
label-field="whateverLabel"
children-field="whateverChildren"
/>
</n-layout-sider>
<n-layout />
</n-layout>
```
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
key-field="whateverKey"
label-field="whateverLabel"
children-field="whateverChildren"
/>
</n-layout-sider>
<n-layout />
</n-layout>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -37,7 +39,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -124,4 +126,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,19 +1,19 @@
<markdown>
# Expand Submenu
You can set `default-expanded-keys` to make menu work in an uncontrolled manner or use `expanded-keys` and `@update:expanded-keys` to make it work in a controlled manner.
If you don't set `default-expanded-keys`, menu will expand all the ascendant of selected option by default.
</markdown>
```html
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
```
<template>
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon, useMessage } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -21,7 +21,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -107,10 +107,10 @@ export default defineComponent({
return {
menuOptions,
defaultExpandedKeys: ['dance-dance-dance', 'food'],
handleUpdateExpandedKeys (value) {
handleUpdateExpandedKeys (value: string[]) {
message.info('[onUpdate:expandedKeys]: ' + JSON.stringify(value))
}
}
}
})
```
</script>

View File

@ -1,13 +1,15 @@
<markdown>
# Horizontal
A horiziontal menu.
</markdown>
```html
<n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />
```
<template>
<n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -15,7 +17,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -111,4 +113,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,18 +1,20 @@
<markdown>
# Indent
You can specify `indent` & `root-indent` of the menu. `root-indent` only determines the first-leveled children.
</markdown>
```html
<n-menu
v-model:value="activeKey"
:root-indent="36"
:indent="12"
:options="menuOptions"
/>
```
<template>
<n-menu
v-model:value="activeKey"
:root-indent="36"
:indent="12"
:options="menuOptions"
/>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -20,7 +22,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -107,4 +109,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -7,17 +7,17 @@ No Food.
## Demos
```demo
horizontal
select
render-label
default-expanded-keys
indent
collapse
inverted
long-label
accordion
router-link
customize-field
horizontal.vue
select.vue
render-label.vue
default-expanded-keys.vue
indent.vue
collapse.vue
inverted.vue
long-label.vue
accordion.vue
router-link.vue
customize-field.vue
```
## API

View File

@ -1,35 +1,37 @@
<markdown>
# Inverted
Set `inverted` to add contrast. Usually used with `n-layout`.
</markdown>
```html
<n-space vertical>
<n-space><n-switch v-model:value="inverted" />inverted</n-space>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:width="240"
show-trigger
:inverted="inverted"
>
<n-menu
:inverted="inverted"
<template>
<n-space vertical>
<n-space><n-switch v-model:value="inverted" />inverted</n-space>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
:width="240"
show-trigger
:inverted="inverted"
>
<n-menu
:inverted="inverted"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
import { h, defineComponent, ref } from 'vue'
<script lang="ts">
import { h, defineComponent, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -37,7 +39,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -124,4 +126,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,12 +1,14 @@
<markdown>
# Long Label
Set `label` to render function that renders `n-ellipsis`.
</markdown>
```html
<n-menu :options="options" style="width: 180px;" default-value="1" />
```
<template>
<n-menu :options="options" style="width: 180px" default-value="1" />
</template>
```js
<script lang="ts">
import { defineComponent, h } from 'vue'
import { NEllipsis } from 'naive-ui'
@ -34,4 +36,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,41 +1,43 @@
<markdown>
# Batch Customizing Menu Options
The `render-label`, `render-icon`, `expand-icon` can be used to batch render menu options.
</markdown>
```html
<n-space vertical>
<n-switch v-model:value="collapsed" />
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-space vertical>
<n-switch v-model:value="collapsed" />
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
:expand-icon="expandIcon"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
:expand-icon="expandIcon"
/>
</n-layout-sider>
<n-layout>
<span>Content</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
<script lang="ts">
import { h, ref, defineComponent } from 'vue'
import { NIcon } from 'naive-ui'
import { NIcon, MenuOption } from 'naive-ui'
import { BookmarkOutline, CaretDownOutline } from '@vicons/ionicons5'
const menuOptions = [
@ -113,13 +115,15 @@ export default defineComponent({
return {
menuOptions,
collapsed: ref(true),
renderMenuLabel (option) {
renderMenuLabel (option: MenuOption) {
if ('href' in option) {
return h('a', { href: option.href, target: '_blank' }, option.label)
return h('a', { href: option.href, target: '_blank' }, [
option.label as string
])
}
return option.label
return option.label as string
},
renderMenuIcon (option) {
renderMenuIcon (option: MenuOption) {
// return render placeholder for indent
if (option.key === 'sheep-man') return true
// return falsy, don't render icon placeholder
@ -132,4 +136,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,13 +1,15 @@
<markdown>
# Use vue-router
Usually you can use vue-router here to accomplish routing. You can render `label` as `<router-link />` to set route.
</markdown>
```html
<n-menu :options="menuOptions" />
```
<template>
<n-menu :options="menuOptions" />
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon } from 'naive-ui'
import { RouterLink } from 'vue-router'
import {
@ -15,7 +17,7 @@ import {
LogOutOutline as HomeIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -60,4 +62,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,16 +1,17 @@
<markdown>
# Select & Routing
Use `@update:value` to listen to the select action of the menu. The first argument of the callback is the `key` of the selected menu item. The second is the orginal data of the menu item.
Usually you can use vue-router here to accomplish routing. Also, you can render `label` as `<router-link />` or `<a />` to set route.
</markdown>
```html
<n-menu @update:value="handleUpdateValue" :options="menuOptions" />
```
<template>
<n-menu :options="menuOptions" @update:value="handleUpdateValue" />
</template>
```js
import { defineComponent, h, resolveComponent } from 'vue'
import { NIcon, useMessage } from 'naive-ui'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { RouterLink } from 'vue-router'
import { NIcon, useMessage, MenuOption } from 'naive-ui'
import {
BookOutline as BookIcon,
PersonOutline as PersonIcon,
@ -18,7 +19,7 @@ import {
HomeOutline as HomeIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -26,7 +27,7 @@ const menuOptions = [
{
label: () =>
h(
resolveComponent('router-link'),
RouterLink,
{
to: {
name: 'home',
@ -137,11 +138,11 @@ export default defineComponent({
const message = useMessage()
return {
menuOptions,
handleUpdateValue (key, item) {
handleUpdateValue (key: string, item: MenuOption) {
message.info('[onUpdate:value]: ' + JSON.stringify(key))
message.info('[onUpdate:value]: ' + JSON.stringify(item))
}
}
}
})
```
</script>

View File

@ -1,17 +1,19 @@
<markdown>
# 手风琴
像一个手风琴使用 `accordion` 属性对一级菜单使用该模式
</markdown>
```html
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
accordion
/>
```
<template>
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
accordion
/>
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
FishOutline as FishIcon,
@ -19,7 +21,7 @@ import {
BagOutline as BagOutlineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -83,4 +85,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,38 +1,40 @@
<markdown>
# 压缩菜单
可以让垂直菜单随着边栏压缩使用 `collapsed` 属性控制菜单状态必需设定 `collapsed-width` 来确保菜单正常显示除此之外还有一些其他和压缩有关的属性`icon-size``collapsed-icon-size`详细信息参考页面底下的 API 文档
</markdown>
```html
<n-space vertical>
<n-switch v-model:value="collapsed" />
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-space vertical>
<n-switch v-model:value="collapsed" />
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
v-model:value="activeKey"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
v-model:value="activeKey"
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -40,7 +42,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -128,4 +130,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,35 +1,37 @@
<markdown>
# 自定义字段
后端会传来各种各样的数据你可以自定义 `key``label` `children` 的字段
</markdown>
```html
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
key-field="whateverKey"
label-field="whateverLabel"
children-field="whateverChildren"
/>
</n-layout-sider>
<n-layout />
</n-layout>
```
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
key-field="whateverKey"
label-field="whateverLabel"
children-field="whateverChildren"
/>
</n-layout-sider>
<n-layout />
</n-layout>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -37,7 +39,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -124,4 +126,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,19 +1,19 @@
<markdown>
# 展开子菜单
你可以设定 `default-expanded-keys` 让菜单工作在非受控状态下或者使用 `expanded-keys` `@update:expanded-keys` 以受控的方式控制菜单
如果你不设定 `default-expanded-keys`菜单会默认展开选中项的全部父级
</markdown>
```html
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
```
<template>
<n-menu
:options="menuOptions"
:default-expanded-keys="defaultExpandedKeys"
@update:expanded-keys="handleUpdateExpandedKeys"
/>
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon, useMessage } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -21,7 +21,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -106,10 +106,10 @@ export default defineComponent({
return {
menuOptions,
defaultExpandedKeys: ['dance-dance-dance', 'food'],
handleUpdateExpandedKeys (keys) {
handleUpdateExpandedKeys (keys: string[]) {
message.info('[onUpdate:expandedKeys]: ' + JSON.stringify(keys))
}
}
}
})
```
</script>

View File

@ -1,13 +1,15 @@
<markdown>
# 水平菜单
一个水平菜单
</markdown>
```html
<n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />
```
<template>
<n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -15,7 +17,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -111,4 +113,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,18 +1,20 @@
<markdown>
# 缩进
你可以设定菜单的 `indent` & `root-indent``root-indent` 只决定第一层项目的缩进
</markdown>
```html
<n-menu
v-model:value="activeKey"
:root-indent="36"
:indent="12"
:options="menuOptions"
/>
```
<template>
<n-menu
v-model:value="activeKey"
:root-indent="36"
:indent="12"
:options="menuOptions"
/>
</template>
```js
import { defineComponent, h, ref } from 'vue'
<script lang="ts">
import { defineComponent, h, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -20,7 +22,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -107,4 +109,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -7,17 +7,17 @@
## 演示
```demo
horizontal
select
render-label
default-expanded-keys
indent
collapse
inverted
long-label
accordion
router-link
customize-field
horizontal.vue
select.vue
render-label.vue
default-expanded-keys.vue
indent.vue
collapse.vue
inverted.vue
long-label.vue
accordion.vue
router-link.vue
customize-field.vue
```
## API

View File

@ -1,35 +1,37 @@
<markdown>
# 反转
通过 `inverted` 来增加对比一般和 `n-layout` 配合使用
</markdown>
```html
<n-space vertical>
<n-space> <n-switch v-model:value="inverted" />inverted</n-space>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:width="240"
show-trigger
:inverted="inverted"
>
<n-menu
:inverted="inverted"
<template>
<n-space vertical>
<n-space> <n-switch v-model:value="inverted" />inverted</n-space>
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
:width="240"
show-trigger
:inverted="inverted"
>
<n-menu
:inverted="inverted"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
import { h, defineComponent, ref } from 'vue'
<script lang="ts">
import { h, defineComponent, ref, Component } from 'vue'
import { NIcon } from 'naive-ui'
import {
BookOutline as BookIcon,
@ -37,7 +39,7 @@ import {
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -124,4 +126,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,12 +1,14 @@
<markdown>
# 菜单内容很长
`label` 设为渲染函数结合 `n-ellipsis`
</markdown>
```html
<n-menu :options="options" style="width: 180px;" default-value="1" />
```
<template>
<n-menu :options="options" style="width: 180px" default-value="1" />
</template>
```js
<script lang="ts">
import { defineComponent, h } from 'vue'
import { NEllipsis } from 'naive-ui'
@ -28,4 +30,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,41 +1,43 @@
<markdown>
# 批量处理菜单渲染
使用 `render-label``render-icon``expand-icon` 可以批量控制菜单的选项渲染
</markdown>
```html
<n-space vertical>
<n-switch v-model:value="collapsed" />
<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"
>
<n-menu
:collapsed="collapsed"
<template>
<n-space vertical>
<n-switch v-model:value="collapsed" />
<n-layout has-sider>
<n-layout-sider
bordered
collapse-mode="width"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
:expand-icon="expandIcon"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
:width="240"
:collapsed="collapsed"
show-trigger
@collapse="collapsed = true"
@expand="collapsed = false"
>
<n-menu
:collapsed="collapsed"
:collapsed-width="64"
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
:expand-icon="expandIcon"
/>
</n-layout-sider>
<n-layout>
<span>内容</span>
</n-layout>
</n-layout>
</n-layout>
</n-space>
```
</n-space>
</template>
```js
<script lang="ts">
import { h, ref, defineComponent } from 'vue'
import { NIcon } from 'naive-ui'
import { NIcon, MenuOption } from 'naive-ui'
import { BookmarkOutline, CaretDownOutline } from '@vicons/ionicons5'
const menuOptions = [
@ -113,13 +115,17 @@ export default defineComponent({
return {
collapsed: ref(true),
menuOptions,
renderMenuLabel (option) {
renderMenuLabel (option: MenuOption) {
if ('href' in option) {
return h('a', { href: option.href, target: '_blank' }, option.label)
return h(
'a',
{ href: option.href, target: '_blank' },
option.label as string
)
}
return option.label
return option.label as string
},
renderMenuIcon (option) {
renderMenuIcon (option: MenuOption) {
//
if (option.key === 'sheep-man') return true
// falsy
@ -132,4 +138,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,13 +1,15 @@
<markdown>
# 使用 vue-router
你可以在这个地方配合 vue-router 完成路由通过将 `label` 渲染为 `<router-link />` 来改变路由
</markdown>
```html
<n-menu :options="menuOptions" />
```
<template>
<n-menu :options="menuOptions" />
</template>
```js
import { defineComponent, h } from 'vue'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon } from 'naive-ui'
import { RouterLink } from 'vue-router'
import {
@ -15,7 +17,7 @@ import {
LogOutOutline as HomeIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -60,4 +62,4 @@ export default defineComponent({
}
}
})
```
</script>

View File

@ -1,16 +1,17 @@
<markdown>
# 选中 & 路由
使用 `@update:value` 监听菜单选择变化这个回调首个参数为选中菜单项的 `key`第二个参数为菜单项的原数据
你通常可以在这个地方配合 vue-router 完成路由当然你也可以通过将 `label` 渲染为 `<router-link />` `<a />` 来改变路由
</markdown>
```html
<n-menu @update:value="handleUpdateValue" :options="menuOptions" />
```
<template>
<n-menu :options="menuOptions" @update:value="handleUpdateValue" />
</template>
```js
import { defineComponent, h, resolveComponent } from 'vue'
import { NIcon, useMessage } from 'naive-ui'
<script lang="ts">
import { defineComponent, h, Component } from 'vue'
import { NIcon, useMessage, MenuOption } from 'naive-ui'
import { RouterLink } from 'vue-router'
import {
BookOutline as BookIcon,
PersonOutline as PersonIcon,
@ -18,7 +19,7 @@ import {
HomeOutline as HomeIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
function renderIcon (icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
@ -26,7 +27,7 @@ const menuOptions = [
{
label: () =>
h(
resolveComponent('router-link'),
RouterLink,
{
to: {
name: 'home',
@ -137,11 +138,11 @@ export default defineComponent({
const message = useMessage()
return {
menuOptions,
handleUpdateValue (key, item) {
handleUpdateValue (key: string, item: MenuOption) {
message.info('[onUpdate:value]: ' + JSON.stringify(key))
message.info('[onUpdate:value]: ' + JSON.stringify(item))
}
}
}
})
```
</script>

View File

@ -7,14 +7,13 @@ import {
provide,
PropType,
ExtractPropTypes,
CSSProperties,
inject,
VNodeChild,
watchEffect
} from 'vue'
import { createTreeMate, Key } from 'treemate'
import { useCompitable, useMergedState } from 'vooks'
import { useConfig, useTheme } from '../../_mixins'
import { useConfig, useTheme, useThemeClass } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { call } from '../../_utils'
import type { MaybeArray } from '../../_utils'
@ -138,7 +137,7 @@ export default defineComponent({
if (__DEV__) {
useCheckDeprecated(props)
}
const { mergedClsPrefixRef } = useConfig(props)
const { mergedClsPrefixRef, inlineThemeDisabled } = useConfig(props)
const themeRef = useTheme(
'Menu',
'-menu',
@ -296,6 +295,79 @@ export default defineComponent({
}
doUpdateExpandedKeys(currentExpandedKeys)
}
const cssVarsRef = computed(() => {
const { inverted } = props
const {
common: { cubicBezierEaseInOut },
self
} = themeRef.value
const {
borderRadius,
borderColorHorizontal,
fontSize,
itemHeight,
dividerColor
} = self
const vars: any = {
'--n-divider-color': dividerColor,
'--n-bezier': cubicBezierEaseInOut,
'--n-font-size': fontSize,
'--n-border-color-horizontal': borderColorHorizontal,
'--n-border-radius': borderRadius,
'--n-item-height': itemHeight
}
if (inverted) {
vars['--n-group-text-color'] = self.groupTextColorInverted
vars['--n-color'] = self.colorInverted
vars['--n-item-text-color'] = self.itemTextColorInverted
vars['--n-arrow-color'] = self.arrowColorInverted
vars['--n-arrow-color-hover'] = self.arrowColorHoverInverted
vars['--n-arrow-color-active'] = self.arrowColorActiveInverted
vars['--n-arrow-color-child-active'] =
self.arrowColorChildActiveInverted
vars['--n-item-icon-color'] = self.itemIconColorInverted
vars['--n-item-text-color-hover'] = self.itemTextColorHoverInverted
vars['--n-item-icon-color-hover'] = self.itemIconColorHoverInverted
vars['--n-item-text-color-active'] = self.itemTextColorActiveInverted
vars['--n-item-icon-color-active'] = self.itemIconColorActiveInverted
vars['--n-item-icon-color-collapsed'] =
self.itemIconColorCollapsedInverted
vars['--n-item-color-active'] = self.itemColorActiveInverted
vars['--n-item-color-active-collapsed'] =
self.itemColorActiveCollapsedInverted
vars['--n-item-text-color-child-active'] =
self.itemTextColorChildActiveInverted
vars['--n-item-icon-color-child-active'] =
self.itemIconColorChildActiveInverted
} else {
vars['--n-group-text-color'] = self.groupTextColor
vars['--n-color'] = self.color
vars['--n-item-text-color'] = self.itemTextColor
vars['--n-arrow-color'] = self.arrowColor
vars['--n-arrow-color-hover'] = self.arrowColorHover
vars['--n-arrow-color-active'] = self.arrowColorActive
vars['--n-arrow-color-child-active'] = self.arrowColorChildActive
vars['--n-item-icon-color'] = self.itemIconColor
vars['--n-item-text-color-hover'] = self.itemTextColorHover
vars['--n-item-icon-color-hover'] = self.itemIconColorHover
vars['--n-item-text-color-active'] = self.itemTextColorActive
vars['--n-item-icon-color-active'] = self.itemIconColorActive
vars['--n-item-icon-color-collapsed'] = self.itemIconColorCollapsed
vars['--n-item-color-active'] = self.itemColorActive
vars['--n-item-color-active-collapsed'] = self.itemColorActiveCollapsed
vars['--n-item-text-color-child-active'] = self.itemTextColorChildActive
vars['--n-item-icon-color-child-active'] = self.itemIconColorChildActive
}
return vars
})
const themeClassHandle = inlineThemeDisabled
? useThemeClass(
'menu',
computed(() => (props.inverted ? 'a' : 'b')),
cssVarsRef,
props
)
: undefined
return {
mergedClsPrefix: mergedClsPrefixRef,
controlledExpandedKeys: controlledExpandedKeysRef,
@ -307,87 +379,24 @@ export default defineComponent({
tmNodes: tmNodesRef,
mergedTheme: themeRef,
mergedCollapsed: mergedCollapsedRef,
cssVars: computed(() => {
const { inverted } = props
const {
common: { cubicBezierEaseInOut },
self
} = themeRef.value
const {
borderRadius,
borderColorHorizontal,
fontSize,
itemHeight,
dividerColor
} = self
const vars: any = {
'--n-divider-color': dividerColor,
'--n-bezier': cubicBezierEaseInOut,
'--n-font-size': fontSize,
'--n-border-color-horizontal': borderColorHorizontal,
'--n-border-radius': borderRadius,
'--n-item-height': itemHeight
}
if (inverted) {
vars['--n-group-text-color'] = self.groupTextColorInverted
vars['--n-color'] = self.colorInverted
vars['--n-item-text-color'] = self.itemTextColorInverted
vars['--n-arrow-color'] = self.arrowColorInverted
vars['--n-arrow-color-hover'] = self.arrowColorHoverInverted
vars['--n-arrow-color-active'] = self.arrowColorActiveInverted
vars['--n-arrow-color-child-active'] =
self.arrowColorChildActiveInverted
vars['--n-item-icon-color'] = self.itemIconColorInverted
vars['--n-item-text-color-hover'] = self.itemTextColorHoverInverted
vars['--n-item-icon-color-hover'] = self.itemIconColorHoverInverted
vars['--n-item-text-color-active'] = self.itemTextColorActiveInverted
vars['--n-item-icon-color-active'] = self.itemIconColorActiveInverted
vars['--n-item-icon-color-collapsed'] =
self.itemIconColorCollapsedInverted
vars['--n-item-color-active'] = self.itemColorActiveInverted
vars['--n-item-color-active-collapsed'] =
self.itemColorActiveCollapsedInverted
vars['--n-item-text-color-child-active'] =
self.itemTextColorChildActiveInverted
vars['--n-item-icon-color-child-active'] =
self.itemIconColorChildActiveInverted
} else {
vars['--n-group-text-color'] = self.groupTextColor
vars['--n-color'] = self.color
vars['--n-item-text-color'] = self.itemTextColor
vars['--n-arrow-color'] = self.arrowColor
vars['--n-arrow-color-hover'] = self.arrowColorHover
vars['--n-arrow-color-active'] = self.arrowColorActive
vars['--n-arrow-color-child-active'] = self.arrowColorChildActive
vars['--n-item-icon-color'] = self.itemIconColor
vars['--n-item-text-color-hover'] = self.itemTextColorHover
vars['--n-item-icon-color-hover'] = self.itemIconColorHover
vars['--n-item-text-color-active'] = self.itemTextColorActive
vars['--n-item-icon-color-active'] = self.itemIconColorActive
vars['--n-item-icon-color-collapsed'] = self.itemIconColorCollapsed
vars['--n-item-color-active'] = self.itemColorActive
vars['--n-item-color-active-collapsed'] =
self.itemColorActiveCollapsed
vars['--n-item-text-color-child-active'] =
self.itemTextColorChildActive
vars['--n-item-icon-color-child-active'] =
self.itemIconColorChildActive
}
return vars
})
cssVars: inlineThemeDisabled ? undefined : cssVarsRef,
themeClass: themeClassHandle?.themeClass,
onRender: themeClassHandle?.onRender
}
},
render () {
const { mergedClsPrefix, mode } = this
const { mergedClsPrefix, mode, themeClass, onRender } = this
onRender?.()
return (
<div
role={mode === 'horizontal' ? 'menubar' : 'menu'}
class={[
`${mergedClsPrefix}-menu`,
themeClass,
`${mergedClsPrefix}-menu--${mode}`,
this.mergedCollapsed && `${mergedClsPrefix}-menu--collapsed`
]}
style={this.cssVars as CSSProperties}
style={this.cssVars as any}
>
{this.tmNodes.map((tmNode) => itemRenderer(tmNode, this.$props))}
</div>