Revert "Merge branch 'main' into fix/541"

This reverts commit 6420680336, reversing
changes made to 2b0e637425.
This commit is contained in:
马泽坤 2021-07-23 15:51:54 +08:00
parent 6420680336
commit 23c20ac101
58 changed files with 171 additions and 530 deletions

View File

@ -1,30 +1,22 @@
# CHANGELOG
## 2.15.6 (2021-07-23)
## Pending
### Feats
- `n-menu` add `render-icon` prop.
- `n-upload` add `show-file-list` prop.
- `n-dropdown` add `render-icon` prop.
- `n-checkbox-group` add `min` and `max` prop.
- `n-mention` add `empty` slot.
- `useDialog` option add `on-mask-click` prop, closes [#419](https://github.com/TuSimple/naive-ui/issues/419).
- `n-space` `justify` prop supports `center`, `space-around` and `space-between`.
- `n-date-picker` add `close-on-select` prop, closes [#541](https://github.com/TuSimple/naive-ui/issues/541).
- `n-dialog` add `action` prop, closes [#550](https://github.com/TuSimple/naive-ui/issues/550).
- `n-mention`s `option.label` support render function.
- `n-color-picker` add `actions` prop, closes [#319](https://github.com/TuSimple/naive-ui/issues/319).
### Fixes
- Fix `n-space`'s inner `display: grid` element breaks item height, closes `https://github.com/TuSimple/naive-ui/issues/546`.
- Fix `n-dropdown`'s `render-label` prop is invalid for group type option.
- Fix `n-datatable`'s `scroll-x` prop is setted, the table content width is not full of the container width, closes [#518](https://github.com/TuSimple/naive-ui/issues/518).
- Fix `n-descriptions` doesn't work with `v-for` children.
- Fix `n-dialog` display an empty button when `positive-text` is not set, closes [#549](https://github.com/TuSimple/naive-ui/issues/549).
- Fix `n-pagination` `PaginationInfo`'s `endIndex` data error, closes [#584](https://github.com/TuSimple/naive-ui/issues/584).
- Fix `n-data-table` `rowClassName` doesn't work when type is string, closes [#582](https://github.com/TuSimple/naive-ui/issues/582).
## 2.15.5 (2021-07-16)

View File

@ -1,30 +1,22 @@
# CHANGELOG
## 2.15.6 (2021-07-23)
## Pending
### Feats
- `n-menu` 新增 `render-icon` 属性
- `n-upload` 新增 `show-file-list` 属性
- `n-dropdown` 新增 `render-icon` 属性
- `n-checkbox-group` 新增 `min``max` 属性
- `n-mention` 新增 `empty` slot
- `useDialog` 选项新增 `on-mask-click`属性, 关闭 [#419](https://github.com/TuSimple/naive-ui/issues/419)
- `n-space` `justify` 属性支持 `center`、`space-around` 和 `space-between`
- `n-date-picker` 新增 `close-on-select` 属性, 关闭 [#541](https://github.com/TuSimple/naive-ui/issues/541)
- `n-dialog` 新增 `action` 属性,关闭 [#550](https://github.com/TuSimple/naive-ui/issues/550)
- `n-mention``option.label` 支持使用渲染函数
- `n-color-picker` 新增 `actions` 属性,关闭 [#319](https://github.com/TuSimple/naive-ui/issues/319)
### Fixes
- 修复 `n-space``display: grid` 的元素显示不正确,关闭 `https://github.com/TuSimple/naive-ui/issues/546`
- 修复 `n-dropdown``render-label` 属性对 group 类型 option 失效
- 修复 `n-datatable``scroll-x` 属性设置后 table 内容宽度未沾满容器宽度,关闭 [#518](https://github.com/TuSimple/naive-ui/issues/518)
- 修复 `n-descriptions` 无法使用 `v-for` 的子元素
- 修复 `n-dialog` `positive-text` 为空仍然显示按钮,关闭 [#549](https://github.com/TuSimple/naive-ui/issues/549)
- 修复 `n-pagination` `PaginationInfo``endIndex` 数据错误,关闭 [#584](https://github.com/TuSimple/naive-ui/issues/584)
- 修复 `n-data-table` `rowClassName` 的类型是 string 的时候不生效问题,关闭 [#582](https://github.com/TuSimple/naive-ui/issues/582)
## 2.15.5 (2021-07-16)

View File

@ -113,7 +113,7 @@ module.exports = {
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
setupFilesAfterEnv: ['<rootDir>/src/jest-setup.ts'],
// setupFilesAfterEnv: [],
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],

View File

@ -1,6 +1,6 @@
{
"name": "naive-ui",
"version": "2.15.6",
"version": "2.15.5",
"description": "A Vue 3 Component Library. Fairly Complete, Customizable Themes, Uses TypeScript, Not Too Slow",
"main": "lib/index.js",
"module": "es/index.js",

View File

@ -24,7 +24,7 @@ event
| disabled | `boolean` | `false` | Whether to disable. |
| focusable | `boolean` | `true` | Whether to focus on selection. |
| indeterminate | `boolean` | `false` | Whether partly selected. |
| label | `string` | `undefined` | Checkbox label. |
| label | `string \| (() => VNodeChild)` | `undefined` | Checkbox label. |
| value | `string \| number` | `undefined` | The value of the checkbox to be used in checkbox group. |
| on-update:checked | `(checked: boolean) => void` | `undefined` | Callback function triggered on checked status changes. |

View File

@ -24,7 +24,7 @@ event
| disabled | `boolean` | `false` | 是否禁用 |
| focusable | `boolean` | `true` | 是否可被 focus |
| indeterminate | `boolean` | `false` | 是否部分选中 |
| label | `string` | `undefined` | Checkbox 的标签 |
| label | `string \| (() => VNodeChild)` | `undefined` | Checkbox 的标签 |
| value | `string \| number` | `undefined` | Checkbox 在 checkbox group 中使用的值 |
| on-update:checked | `(checked: boolean) => void` | `undefined` | 当 checked 改变时触发的回调函数 |

View File

@ -27,4 +27,3 @@ form
| on-complete | `(value: string) => void` | `undefined` | Callback once the value is changed completely (not called during mousemove). |
| on-update:show | `(value: boolean) => void` | `undefined` | Callback once panel show status is changed. |
| on-update:value | `(value: string) => void` | `undefined` | Callback once the value is changed. |
| actions | `Array<'confirm'> \| null` | `null` | Show the type of button |

View File

@ -3,5 +3,5 @@
`show-alpha` 设定是否可调节 alpha 通道。
```html
<n-color-picker :show-alpha="false" :actions="['confirm']" />
<n-color-picker :show-alpha="false" />
```

View File

@ -27,4 +27,3 @@ form
| on-complete | `(value: string) => void` | `undefined` | 颜色完成改变后的回调(在鼠标移动时候不会调用) |
| on-update:show | `(value: boolean) => void` | `undefined` | 面板可见状态改变的回调 |
| on-update:value | `(value: string) => void` | `undefined` | 颜色改变时的回调 |
| actions | `Array<'confirm'> \| null` | `null` | 显示按钮 |

View File

@ -59,7 +59,7 @@ import Pallete from './Pallete'
import ColorInput from './ColorInput'
import ColorPickerTrigger from './ColorPickerTrigger'
import { deriveDefaultValue, getModeFromValue } from './utils'
import type { ColorPickerMode, ActionType } from './utils'
import type { ColorPickerMode } from './utils'
import style from './styles/index.cssr'
import { OnUpdateValue, OnUpdateValueImpl } from './interface'
import { NButton } from '../../button'
@ -86,10 +86,6 @@ export const colorPickerPanelProps = {
type: Boolean,
default: true
},
actions: {
type: Array as PropType<ActionType[]>,
default: null
},
internalActions: Array as PropType<ReadonlyArray<'redo' | 'undo'>>,
size: String as PropType<'small' | 'medium' | 'large'>,
onComplete: Function as PropType<OnUpdateValue>,
@ -425,11 +421,6 @@ export default defineComponent({
handleComplete(false)
valueIndexRef.value = valueIndex + 1
}
function handleConfirm (): void {
doUpdateShow(false)
}
const undoableRef = computed(() => valueIndexRef.value >= 1)
const redoableRef = computed(() => {
const { value: undoStack } = undoStackRef
@ -490,7 +481,7 @@ export default defineComponent({
function renderPanel (): VNode {
const { value: rgba } = rgbaRef
const { value: displayedHue } = displayedHueRef
const { internalActions, modes, actions } = props
const { internalActions, modes } = props
const { value: mergedTheme } = themeRef
const { value: mergedClsPrefix } = mergedClsPrefixRef
return (
@ -536,20 +527,6 @@ export default defineComponent({
onUpdateValue={handleInputUpdateValue}
/>
</div>
{actions?.length ? (
<div class={`${mergedClsPrefix}-color-picker-action`}>
{actions.includes('confirm') && (
<NButton
size="small"
onClick={handleConfirm}
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
>
{{ default: () => localeRef.value.confirm }}
</NButton>
)}
</div>
) : null}
{slots.action ? (
<div class={`${mergedClsPrefix}-color-picker-action`}>
{{ default: slots.action }}

View File

@ -2,8 +2,6 @@ import { warn } from '../../_utils'
export type ColorPickerMode = 'rgb' | 'hsl' | 'hsv' | 'hex'
export type ActionType = 'confirm'
export function deriveDefaultValue (
modes: ColorPickerMode[],
showAlpha: boolean

View File

@ -2,7 +2,6 @@ import { nextTick } from 'vue'
import { mount } from '@vue/test-utils'
import { NColorPicker } from '../index'
import { ColorPickerMode } from '../src/utils'
import { NButton } from '../../button'
describe('n-color-picker', () => {
it('should work with import on demand', () => {
@ -73,24 +72,4 @@ describe('n-color-picker', () => {
})
})
})
describe('props.control', () => {
it('confirm and cancel button', async () => {
const wrapper = mount(NColorPicker, {
attachTo: document.body,
props: {
actions: ['confirm']
}
})
await wrapper.find('.n-color-picker-trigger').trigger('click')
expect(document.querySelector('.n-color-picker-panel')).not.toEqual(null)
expect(document.querySelector('.n-color-picker-pallete')).not.toEqual(
null
)
expect(document.querySelector('.n-button')).not.toEqual(null)
await wrapper.findComponent(NButton).trigger('click')
expect(document.querySelector('.n-color-picker-panel')).toEqual(null)
expect(document.querySelector('.n-color-picker-pallete')).toEqual(null)
wrapper.unmount()
})
})
})

View File

@ -60,7 +60,7 @@ tree
| row-key | `(rowData: object) => (number \| string)` | `undefined` | Generate the key of the row by row data (if you don't want to set the key). |
| row-props | `(rowData: object, rowIndex : number) => object` | `undefined` | Customize row attributes. |
| scroll-x | `number \| string` | `undefined` | If columns are horizontal fixed, scroll-x need to be set. |
| single-column | `boolean` | `false` | Whether to display as a column (when true, each column has border-right). |
| single-column | `boolean` | `false` | Whether to display as a column (when true, each column has border-bottom). |
| single-line | `boolean` | `true` | Whether to display as a line (when true, each row has border-bottom). |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Table size. |
| summary | `CreateSummary` | `undefined` | Data of table summary row. For types, see <n-a href="#CreateSummary-Type">CreateSummary Type</n-a>. |

View File

@ -60,7 +60,7 @@ tree
| row-key | `(rowData: object) => (number \| string)` | `undefined` | 通过行数据创建行的 key如果你不想给每一行加上 key |
| row-props | `(rowData: object, rowIndex : number) => object` | `undefined` | 自定义行属性 |
| scroll-x | `number \| string` | `undefined` | 表格内容的横向宽度,如果列被水平固定了,则需要设定它 |
| single-column | `boolean` | `false` | 是否展示为一列true 时每一列都有 border-right |
| single-column | `boolean` | `false` | 是否展示为一列true 时每一列都有 border-bottom |
| single-line | `boolean` | `true` | 是否展示为一行true 时每一行都有 border-bottom |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 表格的尺寸 |
| summary | `CreateSummary` | `undefined` | 表格总结栏的数据,类型见 <n-a href="#CreateSummary-Type">CreateSummary Type</n-a> |

View File

@ -286,7 +286,6 @@ export default defineComponent({
setHeaderScrollLeft
} = this
const contentStyle = {
width: '100%',
minWidth: formatLength(scrollX)
}
return (
@ -541,10 +540,6 @@ export default defineComponent({
)
})
const props = rowProps ? rowProps(rowData, rowIndex) : undefined
const mergedRowClassName =
typeof rowClassName === 'string'
? rowClassName
: createRowClassName(rowData, rowIndex, rowClassName)
const row = (
<tr
onMouseenter={() => {
@ -553,7 +548,7 @@ export default defineComponent({
key={rowKey}
class={[
`${mergedClsPrefix}-data-table-tr`,
mergedRowClassName
createRowClassName(rowData, rowIndex, rowClassName)
]}
{...props}
>

View File

@ -9,13 +9,7 @@ import {
import { useCompitable } from 'vooks'
import { useConfig, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import {
warn,
getSlot,
getVNodeChildren,
createKey,
flatten
} from '../../_utils'
import { warn, getSlot, getVNodeChildren, createKey, flatten } from '../../_utils'
import type { ExtractPublicPropTypes } from '../../_utils'
import { descriptionsLight } from '../styles'
import type { DescriptionsTheme } from '../styles'
@ -88,10 +82,14 @@ export default defineComponent({
borderRadius,
lineHeight,
[createKey('fontSize', size)]: fontSize,
[createKey(bordered ? 'thPaddingBordered' : 'thPadding', size)]:
thPadding,
[createKey(bordered ? 'tdPaddingBordered' : 'tdPadding', size)]:
tdPadding
[createKey(
bordered ? 'thPaddingBordered' : 'thPadding',
size
)]: thPadding,
[createKey(
bordered ? 'tdPaddingBordered' : 'tdPadding',
size
)]: tdPadding
}
} = themeRef.value
return {

View File

@ -1,31 +0,0 @@
# Custom Action
Sometimes you may want to customize `action` and `content` .
```html
<n-space>
<n-button @click="handleConfirm">Use Render Function</n-button>
</n-space>
```
```js
import { useDialog, NTag } from 'naive-ui'
export default {
components: {
NTag
},
setup () {
const dialog = useDialog()
return {
handleConfirm () {
dialog.warning({
title: 'Use Render Function',
content: () => 'Content',
action: () => 'Action'
})
}
}
}
}
```

View File

@ -36,8 +36,6 @@ export default {
basic
async
use-component
mask
action
```
## API
@ -57,7 +55,6 @@ action
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| action | `() => VNodeChild` | `undefined` | Content of the operation area, must be a render function. |
| bordered | `boolean` | `false` | Whether to show border. |
| closable | `boolean` | `true` | Whether to show close icon. |
| content | `string \| (() => VNodeChild)` | `undefined` | Content, can be a render function. |
@ -73,7 +70,6 @@ action
| onClose | `() => boolean \| Promise<boolean> \| any` | `undefined` | The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior. |
| onNegativeClick | `() => boolean \| Promise<boolean> \| any` | `undefined` | The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior. |
| onPositiveClick | `() => boolean \| Promise<boolean> \| any` | `undefined` | The default behavior is closing the confirm. Return `false` or resolve `false` or Promise rejected will prevent the default behavior. |
| onMaskClick | `() => void` | `undefined` | Callback triggered when click the mask. |
### DialogReactive API

View File

@ -1,32 +0,0 @@
# Click on Mask
I think user is smart enough that they know if nothing happens after mask is clicked, they should click at confirm or cancel button.
```html
<n-button @click="handleButtonClick">Callback on Mask Clicked</n-button>
```
```js
import { useMessage, useDialog } from 'naive-ui'
export default {
setup () {
const message = useMessage()
const dialog = useDialog()
return {
handleButtonClick () {
dialog.success({
title: 'Close',
content: 'Are you sure?',
positiveText: 'Sure',
negativeText: 'Not Sure',
maskClosable: false,
onMaskClick: (e) => {
message.success('cannot close')
}
})
}
}
}
}
```

View File

@ -1,31 +0,0 @@
# 自定义 Action
有的时候你想自定义 `action``content`
```html
<n-space>
<n-button @click="handleButtonClick">使用渲染函数</n-button>
</n-space>
```
```js
import { useDialog, NTag } from 'naive-ui'
export default {
components: {
NTag
},
setup () {
const dialog = useDialog()
return {
handleButtonClick () {
dialog.warning({
title: '使用渲染函数',
content: () => 'Content',
action: () => 'Action'
})
}
}
}
}
```

View File

@ -37,8 +37,6 @@ export default {
basic
async
use-component
mask
action
```
## API
@ -58,7 +56,6 @@ action
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| action | `() => VNodeChild` | `undefined` | 操作区域的内容,需要是 render 函数 |
| bordered | `boolean` | `false` | 是否显示 border |
| closable | `boolean` | `true` | 是否显示 close 图标 |
| content | `string \| (() => VNodeChild)` | `undefined` | 对话框内容,可以是 render 函数 |
@ -74,7 +71,6 @@ action
| onClose | `() => boolean \| Promise<boolean> \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 |
| onNegativeClick | `() => boolean \| Promise<boolean> \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 |
| onPositiveClick | `() => boolean \| Promise<boolean> \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 |
| onMaskClick | `() => void` | `undefined` | 点击蒙层后执行的回调 |
### DialogReactive API

View File

@ -1,32 +0,0 @@
# 点击遮罩
我觉得用户应该聪明到点遮罩没用的时候就去点确认了。
```html
<n-button @click="handleButtonClick">点击遮罩的事件</n-button>
```
```js
import { useMessage, useDialog } from 'naive-ui'
export default {
setup () {
const message = useMessage()
const dialog = useDialog()
return {
handleButtonClick () {
dialog.success({
title: '关闭',
content: '你确定?',
positiveText: '确定',
negativeText: '不确定',
maskClosable: false,
onMaskClick: (e) => {
message.success('不能关闭')
}
})
}
}
}
}
```

View File

@ -50,7 +50,6 @@ const dialogProps = {
negativeText: String,
positiveText: String,
content: [String, Function] as PropType<string | (() => VNodeChild)>,
action: Function as PropType<() => VNodeChild>,
showIcon: {
type: Boolean,
default: true
@ -185,7 +184,6 @@ export default defineComponent({
showIcon,
title,
content,
action,
negativeText,
positiveText,
handlePositiveClick,
@ -245,45 +243,38 @@ export default defineComponent({
<div class={`${mergedClsPrefix}-dialog__content`}>
{renderSlot($slots, 'default', undefined, () => [render(content)])}
</div>
{$slots.action || positiveText || negativeText || action ? (
{$slots.action || (!$slots.action && (positiveText || negativeText)) ? (
<div class={`${mergedClsPrefix}-dialog__action`}>
{renderSlot(
$slots,
'action',
undefined,
action
? () => [render(action)]
: () => [
this.negativeText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
ghost
size="small"
onClick={handleNegativeClick}
>
{{
default: () => render(this.negativeText)
}}
</NButton>
),
this.positiveText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
disabled={loading}
loading={loading}
size="small"
type={type === 'default' ? 'primary' : type}
onClick={handlePositiveClick}
>
{{
default: () => render(this.positiveText)
}}
</NButton>
)
]
)}
{renderSlot($slots, 'action', undefined, () => [
this.negativeText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
ghost
size="small"
onClick={handleNegativeClick}
>
{{
default: () => render(this.negativeText)
}}
</NButton>
),
this.positiveText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
disabled={loading}
loading={loading}
size="small"
type={type === 'default' ? 'primary' : type}
onClick={handlePositiveClick}
>
{{
default: () => render(this.positiveText)
}}
</NButton>
)
])}
</div>
) : null}
</div>

View File

@ -17,8 +17,7 @@ export const exposedDialogEnvProps = {
onNegativeClick: Function as PropType<
(e: MouseEvent) => Promise<boolean> | boolean | unknown
>,
onClose: Function as PropType<() => Promise<boolean> | boolean | unknown>,
onMaskClick: Function as PropType<(e: MouseEvent) => void>
onClose: Function as PropType<() => Promise<boolean> | boolean | unknown>
}
export default defineComponent({
@ -74,13 +73,6 @@ export default defineComponent({
hide()
}
}
function handleMaskClick (e: MouseEvent): void {
const { onMaskClick, maskClosable } = props
if (onMaskClick) {
onMaskClick(e)
maskClosable && hide()
}
}
function hide (): void {
showRef.value = false
}
@ -94,8 +86,7 @@ export default defineComponent({
handleAfterLeave,
handleCloseClick,
handleNegativeClick,
handlePositiveClick,
handleMaskClick
handlePositiveClick
}
},
render () {
@ -105,7 +96,6 @@ export default defineComponent({
handleNegativeClick,
handleCloseClick,
handleAfterLeave,
handleMaskClick,
to,
maskClosable,
show
@ -114,7 +104,6 @@ export default defineComponent({
<NModal
show={show}
onUpdateShow={handleUpdateShow}
onMaskClick={handleMaskClick}
appear
dialog
to={to}

View File

@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils'
import { defineComponent, h, nextTick } from 'vue'
import { defineComponent, h } from 'vue'
import { NDialogProvider, useDialog, NDialog } from '../index'
const Provider = defineComponent({
@ -51,14 +51,13 @@ describe('n-dialog', () => {
expect(wrapper.find('button').exists()).toEqual(false)
})
it('loading', async () => {
it('async', async () => {
const Test = defineComponent({
setup () {
const dialog = useDialog()
dialog.success({
title: 'Loading',
title: 'Async',
content: 'Content',
positiveText: '确认',
loading: true
})
},
@ -69,51 +68,4 @@ describe('n-dialog', () => {
await mount(() => <Provider>{{ default: () => <Test /> }}</Provider>)
expect(document.querySelector('.n-button__icon')).not.toEqual(null)
})
it('maskClosable', async () => {
const mousedownEvent = new MouseEvent('mousedown', { bubbles: true })
const mouseupEvent = new MouseEvent('mouseup', { bubbles: true })
const Test = defineComponent({
setup () {
const dialog = useDialog()
dialog.success({
title: 'Close by mask',
content: 'Content',
maskClosable: false
})
},
render () {
return null
}
})
mount(() => <Provider>{{ default: () => <Test /> }}</Provider>)
document.body.dispatchEvent(mousedownEvent)
document.body.dispatchEvent(mouseupEvent)
await nextTick(() => {
expect(document.querySelector('.n-dialog')).not.toBeNull()
})
})
it('onMaskClick', async () => {
const onMaskClick = jest.fn()
const mousedownEvent = new MouseEvent('mousedown', { bubbles: true })
const mouseupEvent = new MouseEvent('mouseup', { bubbles: true })
const Test = defineComponent({
setup () {
const dialog = useDialog()
dialog.success({
title: 'Close by mask',
content: 'Content',
onMaskClick
})
},
render () {
return null
}
})
await mount(() => <Provider>{{ default: () => <Test /> }}</Provider>)
document.body.dispatchEvent(mousedownEvent)
document.body.dispatchEvent(mouseupEvent)
expect(onMaskClick).toHaveBeenCalled()
})
})

View File

@ -20,6 +20,6 @@ depth
## Slots
| Name | Parameters | Description |
| ------- | ---------- | ------------------------ |
| default | `()` | The content of the icon. |
| Name | Parameters | Description |
| ------- | ---------- | ----------- |
| default | `()` | |

View File

@ -20,8 +20,8 @@ depth
## Slots
| 名称 | 参数 | 说明 |
| ------- | ---- | ---------- |
| default | `()` | 图标的内容 |
| 名称 | 参数 | 说明 |
| ------- | ---- | ---- |
| default | `()` | |
<!-- icons -->

View File

@ -1,2 +0,0 @@
// https://github.com/jsdom/jsdom/issues/1422
HTMLDivElement.prototype.scrollTo = () => {}

View File

@ -2,8 +2,7 @@ const enUS = {
name: 'en-US',
global: {
undo: 'Undo',
redo: 'Redo',
confirm: 'Confirm'
redo: 'Redo'
},
Popconfirm: {
positiveText: 'Confirm',

View File

@ -4,8 +4,7 @@ const zhCN: NLocale = {
name: 'zh-CN',
global: {
undo: '撤销',
redo: '重做',
confirm: '确认'
redo: '重做'
},
Popconfirm: {
positiveText: '确认',

View File

@ -53,21 +53,21 @@ loading
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| font-size | `number` | `14` | Font size. |
| hljs | `Object` | `undefined` | If you want to set `hljs` locally, pass it using this prop. |
| language | `string` | `undefined` | The language of the log in `highlightjs`. |
| line-height | `number` | `1.25` | Line height. |
| lines | `Array<string>` | `undefined` | Display the log content by line. When the `log` parameter exists at the same time, the parameter is invalid. |
| loading | `boolean` | `false` | Whether to show loading. |
| log | `string` | `undefined` | The content of the log. |
| rows | `number` | `15` | Log size. |
| trim | `boolean` | `false` | Whether to display the log after `trim`. |
| on-require-more | `(from: 'top' \| 'bottom') => void` | `undefined` | Callback function for scroll loading log. |
| on-reach-top | `() => void` | `undefined` | Scroll to the top callback function. |
| on-reach-bottom | `() => void` | `undefined` | Scroll to the bottom callback function. |
| font-size | `number` | `14` | |
| hljs | `Object` | `undefined` | |
| language | `string` | `undefined` | |
| line-height | `number` | `1.25` | |
| lines | `Array<string>` | `undefined` | |
| loading | `boolean` | `false` | |
| log | `string` | `undefined` | |
| rows | `number` | `15` | |
| trim | `boolean` | `false` | |
| on-require-more | `(from: 'top' \| 'bottom') => void` | `undefined` | |
| on-reach-top | `() => void` | `undefined` | |
| on-reach-bottom | `() => void` | `undefined` | |
## Methods
| Name | Parameters | Description |
| --- | --- | --- |
| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | Callback function for scroll event. |
| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | |

View File

@ -51,23 +51,23 @@ loading
## Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| font-size | `number` | `14` | 文字大小 |
| hljs | `Object` | `undefined` | 如果你想局部设定 `hljs` ,可以通过这个属性传给组件 |
| language | `string` | `undefined` | 日志在 `highlightjs` 中的语言 |
| line-height | `number` | `1.25` | 行高 |
| lines | `Array<string>` | `undefined` | 按行显示日志内容,在同时存在 `log` 参数时,该参数无效 |
| loading | `boolean` | `false` | 是否显示加载中 |
| log | `string` | `undefined` | 日志的内容 |
| rows | `number` | `15` | 日志的尺寸 |
| trim | `boolean` | `false` | 是否显示 `trim` 后的日志 |
| on-require-more | `(from: 'top' \| 'bottom') => void` | `undefined` | 滚动加载日志的回调函数 |
| on-reach-top | `() => void` | `undefined` | 滚动到顶部的回调函数 |
| on-reach-bottom | `() => void` | `undefined` | 滚动到底部的回调函数 |
| 名称 | 类型 | 默认值 | 说明 |
| --------------- | ----------------------------------- | ----------- | ---- |
| font-size | `number` | `14` | |
| hljs | `Object` | `undefined` | |
| language | `string` | `undefined` | |
| line-height | `number` | `1.25` | |
| lines | `Array<string>` | `undefined` | |
| loading | `boolean` | `false` | |
| log | `string` | `undefined` | |
| rows | `number` | `15` | |
| trim | `boolean` | `false` | |
| on-require-more | `(from: 'top' \| 'bottom') => void` | `undefined` | |
| on-reach-top | `() => void` | `undefined` | |
| on-reach-bottom | `() => void` | `undefined` | |
## Methods
| 名称 | 参数 | 说明 |
| --- | --- | --- |
| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | 滚动事件的回调函数 |
| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | |

View File

@ -1,15 +1,11 @@
# Basic Usage
If `label` is a callback function, input matching will be performed according to `value`.
```html
<n-mention :options="options" default-value="@" />
```
```js
import { defineComponent, h } from 'vue'
import { NIcon } from 'naive-ui'
import { HomeOutline as HomeIcon } from '@vicons/ionicons5'
import { defineComponent } from 'vue'
export default defineComponent({
setup () {
@ -28,15 +24,7 @@ export default defineComponent({
value: 'Guandong-Road'
},
{
label: (option) =>
h('span', null, [
h(
NIcon,
{ style: 'margin-right: 5px' },
{ default: () => h(HomeIcon) }
),
option.value
]),
label: 'No.5-Yiheyuan-Road',
value: 'No.5-Yiheyuan-Road'
}
]

View File

@ -43,7 +43,7 @@ Mention is provided after `v2.2.0`.
| --- | --- | --- |
| class | `string` | Option class name. |
| disabled | `boolean` | Option disabled status. |
| label | `string \| (option: MentionOption) => VNodeChild` | Option label. |
| label | `string` | Option label. |
| render | `(option: MentionOption) => VNodeChild` | Support custom options via `render` rendering function. |
| style | `string` | Option style. |
| value | `string` | Should be unique. |

View File

@ -1,15 +1,11 @@
# 基本用法
如果 `label` 是回调函数,输入匹配则会根据 `value` 进行匹配
```html
<n-mention :options="options" default-value="@" />
```
```js
import { defineComponent, h } from 'vue'
import { NIcon } from 'naive-ui'
import { HomeOutline as HomeIcon } from '@vicons/ionicons5'
import { defineComponent } from 'vue'
export default defineComponent({
setup () {
@ -28,15 +24,7 @@ export default defineComponent({
value: '广东路'
},
{
label: (option) =>
h('span', null, [
h(
NIcon,
{ style: 'margin-right: 5px' },
{ default: () => h(HomeIcon) }
),
option.value
]),
label: '颐和园路5号',
value: '颐和园路5号'
}
]

View File

@ -43,7 +43,7 @@ Mention 在 `v2.2.0` 及以后可用。
| --- | --- | --- |
| class | `string` | 选项的自定义类名 |
| disabled | `boolean` | 选项是否禁用 |
| label | `string \| (option: MentionOption) => VNodeChild` | 选项的标签 |
| label | `string` | 选项的标签 |
| render | `(option: MentionOption) => VNodeChild` | 支持通过 `render` 渲染函数自定义选项 |
| style | `string` | 选项的样式 |
| value | `string` | 在选项中应该是唯一的 |

View File

@ -126,10 +126,7 @@ export default defineComponent({
const { value: pattern } = partialPatternRef
return props.options.filter((option) => {
if (!pattern) return true
if (typeof option.label === 'string') {
return option.label.startsWith(pattern)
}
return option.value.startsWith(pattern)
return option.label.startsWith(pattern)
})
})
const treeMateRef = computed(() => {

View File

@ -1,3 +1,3 @@
import type { SelectBaseOption } from '../../select/src/interface'
export type MentionOption = SelectBaseOption<string>
export type MentionOption = SelectBaseOption<string, string>

View File

@ -36,7 +36,6 @@ long-label
| inverted | `boolean` | `false` | Use inverted style. |
| options | `Array<MenuOption \| MenuOptionGroup>` | `[]` | Items data of menu. |
| mode | `'vertical' \| 'horizontal'` | `'vertical'` | Menu layout. |
| render-icon | `(option: MenuOption) => VNodeChild` | `undefined` | Render function that renders all icons. |
| render-label | `(option: MenuOption \| MenuGroupOption) => VNodeChild` | `undefined` | Render function that renders all labels. |
| root-indent | `number` | `undefined` | The indent of menu's first level children. If not set, menu will use `indent` in place of it. |
| value | `string \| null` | `undefined` | The selected name of menu. |

View File

@ -1,6 +1,6 @@
# Batch Customizing Menu Options
# Render Label
The `render-label`, `render-icon` can be used to batch render menu options.
The `render-label` can be used to batch render menu options.
```html
<n-space vertical>
@ -22,7 +22,6 @@ The `render-label`, `render-icon` can be used to batch render menu options.
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
/>
</n-layout-sider>
<n-layout>
@ -35,17 +34,27 @@ The `render-label`, `render-icon` can be used to batch render menu options.
```js
import { h, ref, defineComponent } from 'vue'
import { NIcon } from 'naive-ui'
import { BookmarkOutline } from '@vicons/ionicons5'
import {
BookOutline as BookIcon,
PersonOutline as PersonIcon,
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
return () => h(NIcon, null, { default: () => h(icon) })
}
const menuOptions = [
{
label: 'Hear the Wind Sing',
key: 'hear-the-wind-sing',
icon: renderIcon(BookIcon),
href: 'https://en.wikipedia.org/wiki/Hear_the_Wind_Sing'
},
{
label: 'Pinball 1973',
key: 'pinball-1973',
icon: renderIcon(BookIcon),
disabled: true,
children: [
{
@ -57,11 +66,13 @@ const menuOptions = [
{
label: 'A Wild Sheep Chase',
key: 'a-wild-sheep-chase',
disabled: true
disabled: true,
icon: renderIcon(BookIcon)
},
{
label: 'Dance Dance Dance',
key: 'Dance Dance Dance',
icon: renderIcon(BookIcon),
children: [
{
type: 'group',
@ -70,17 +81,20 @@ const menuOptions = [
children: [
{
label: 'Narrator',
key: 'narrator'
key: 'narrator',
icon: renderIcon(PersonIcon)
},
{
label: 'Sheep Man',
key: 'sheep-man'
key: 'sheep-man',
icon: renderIcon(PersonIcon)
}
]
},
{
label: 'Beverage',
key: 'beverage',
icon: renderIcon(WineIcon),
children: [
{
label: 'Whisky',
@ -117,9 +131,6 @@ export default defineComponent({
return h('a', { href: option.href, target: '_blank' }, option.label)
}
return option.label
},
renderMenuIcon () {
return h(NIcon, null, { default: () => h(BookmarkOutline) })
}
}
}

View File

@ -1,6 +1,6 @@
# 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.
Use `@update:value` to listen to the select action of the menu. The firt 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.

View File

@ -36,8 +36,7 @@ long-label
| inverted | `boolean` | `false` | 使用反转样式 |
| options | `Array<MenuOption \| MenuOptionGroup>` | `[]` | 菜单的数据 |
| mode | `'vertical' \| 'horizontal'` | `'vertical'` | 菜单的布局方式 |
| render-icon | `(option: MenuOption) => VNodeChild` | `undefined` | 批量处理菜单图标渲染 |
| render-label | `(option: MenuOption \| MenuGroupOption) => VNodeChild` | `undefined` | 批量处理菜单标签渲染 |
| render-label | `(option: MenuOption \| MenuGroupOption) => VNodeChild` | `undefined` | 批量处理菜单渲染 |
| root-indent | `number` | `32` | 菜单第一级的缩进,如果没有设定,使用 `indent` 代替 |
| value | `string \| null` | `undefined` | 菜单当前的选中值 |
| on-update:expanded-keys | `(keys: string[]) => void` | `undefined` | `keys` 是展开菜单项的 `key` 的数组 |

View File

@ -1,6 +1,6 @@
# 批量处理菜单渲染
使用 `render-label`、`render-icon` 可以批量控制菜单的选项渲染。
使用 `render-label` 可以批量控制菜单的选项渲染。
```html
<n-space vertical>
@ -22,7 +22,6 @@
:collapsed-icon-size="22"
:options="menuOptions"
:render-label="renderMenuLabel"
:render-icon="renderMenuIcon"
/>
</n-layout-sider>
<n-layout>
@ -35,17 +34,27 @@
```js
import { h, ref, defineComponent } from 'vue'
import { NIcon } from 'naive-ui'
import { BookmarkOutline } from '@vicons/ionicons5'
import {
BookOutline as BookIcon,
PersonOutline as PersonIcon,
WineOutline as WineIcon
} from '@vicons/ionicons5'
function renderIcon (icon) {
return () => h(NIcon, null, { default: () => h(icon) })
}
const menuOptions = [
{
label: '且听风吟',
key: 'hear-the-wind-sing',
icon: renderIcon(BookIcon),
href: 'https://baike.baidu.com/item/%E4%B8%94%E5%90%AC%E9%A3%8E%E5%90%9F/3199'
},
{
label: '1973年的弹珠玩具',
key: 'pinball-1973',
icon: renderIcon(BookIcon),
disabled: true,
children: [
{
@ -57,11 +66,13 @@ const menuOptions = [
{
label: '寻羊冒险记',
key: 'a-wild-sheep-chase',
disabled: true
disabled: true,
icon: renderIcon(BookIcon)
},
{
label: '舞,舞,舞',
key: 'dance-dance-dance',
icon: renderIcon(BookIcon),
children: [
{
type: 'group',
@ -70,17 +81,20 @@ const menuOptions = [
children: [
{
label: '叙事者',
key: 'narrator'
key: 'narrator',
icon: renderIcon(PersonIcon)
},
{
label: '羊男',
key: 'sheep-man'
key: 'sheep-man',
icon: renderIcon(PersonIcon)
}
]
},
{
label: '饮品',
key: 'beverage',
icon: renderIcon(WineIcon),
children: [
{
label: '威士忌',
@ -117,9 +131,6 @@ export default defineComponent({
return h('a', { href: option.href, target: '_blank' }, option.label)
}
return option.label
},
renderMenuIcon () {
return h(NIcon, null, { default: () => h(BookmarkOutline) })
}
}
}

View File

@ -149,7 +149,6 @@ const menuProps = {
},
default: undefined
},
renderIcon: Function as PropType<(option: MenuOption) => VNodeChild>,
renderLabel: Function as PropType<
(option: MenuOption | MenuGroupOption) => VNodeChild
>,

View File

@ -63,7 +63,7 @@ export default defineComponent({
const {
clsPrefix,
tmNode,
menuProps: { renderIcon, renderLabel }
menuProps: { renderLabel }
} = this
return (
<div
@ -80,13 +80,13 @@ export default defineComponent({
]}
style={this.style}
>
{renderIcon || this.icon ? (
{this.icon ? (
<div
class={`${clsPrefix}-menu-item-content__icon`}
style={this.iconStyle}
role="none"
>
{renderIcon ? renderIcon(tmNode.rawNode) : render(this.icon)}
{render(this.icon)}
</div>
) : null}
<div class={`${clsPrefix}-menu-item-content-header`} role="none">

View File

@ -116,7 +116,7 @@ export default defineComponent({
render () {
const {
mergedClsPrefix,
menuProps: { renderIcon, renderLabel }
menuProps: { renderLabel }
} = this
const createSubmenuItem = (): VNode => {
const {
@ -184,7 +184,6 @@ export default defineComponent({
options={this.rawNodes}
onSelect={this.doSelect}
inverted={this.inverted}
renderIcon={renderIcon}
renderLabel={renderLabel}
>
{{

View File

@ -1,9 +1,7 @@
import { mount } from '@vue/test-utils'
import { HappyOutline } from '@vicons/ionicons5'
import { h } from 'vue'
import { sleep } from 'seemly'
import { NMenu } from '../index'
import { NIcon } from '../../icon'
describe('n-menu', () => {
it('should work with import on demand', () => {
@ -135,50 +133,4 @@ describe('n-menu', () => {
expect(document.querySelectorAll('a').length).toEqual(3)
expect(document.querySelectorAll('a.fantasy').length).toEqual(1)
})
it('should dropdown work with `render-icon` props', async () => {
const options = [
{
label: 'jj',
key: 'jj'
},
{
label: 'jay',
key: 'jay',
children: [
{
type: 'group',
label: 'song-group',
key: 'group',
children: [
{
label: 'fantasy',
key: 'fantasy'
},
{
label: 'mojito',
key: 'mojito'
}
]
}
]
}
]
function renderMenuIcon (): any {
return h(NIcon, null, { default: () => h(HappyOutline) })
}
const wrapper = mount(NMenu, {
props: {
options: options,
collapsed: true,
renderIcon: renderMenuIcon
}
})
expect(wrapper.find('.n-submenu').exists()).toBe(true)
await wrapper.find('.n-submenu').trigger('mouseenter')
// Popover has delay, so we need to wait
await sleep(150)
expect(document.body.querySelector('.n-dropdown')).not.toEqual(null)
expect(document.querySelectorAll('.n-icon').length).toEqual(2)
})
})

View File

@ -66,7 +66,6 @@ const modalProps = {
onClose: Function as PropType<() => Promise<boolean> | boolean | any>,
onPositiveClick: Function as PropType<() => Promise<boolean> | boolean | any>,
onNegativeClick: Function as PropType<() => Promise<boolean> | boolean | any>,
onMaskClick: Function as PropType<(e: MouseEvent) => void>,
// deprecated
overlayStyle: {
type: [String, Object] as PropType<string | CSSProperties | undefined>,
@ -193,10 +192,6 @@ export default defineComponent({
if (onAfterHide) onAfterHide()
}
function handleClickoutside (e: MouseEvent): void {
const { onMaskClick } = props
if (onMaskClick) {
onMaskClick(e)
}
if (props.maskClosable) {
if (containerRef.value?.contains(e.target as Node)) {
doUpdateShow(false)

View File

@ -157,7 +157,7 @@ export default defineComponent({
return (mergedPageRef.value - 1) * mergedPageSizeRef.value
})
const endIndexRef = computed(() => {
const endIndex = mergedPageRef.value * mergedPageSizeRef.value - 1
const endIndex = mergedPageRef.value * mergedPageSizeRef.value
const { itemCount } = props
if (itemCount !== undefined) {
return endIndex > itemCount ? itemCount : endIndex

View File

@ -1,9 +0,0 @@
# Format Tooltip
```html
<n-slider
v-model:value="value"
:step="10"
:format-tooltip="value => `${value}%`"
/>
```

View File

@ -9,7 +9,6 @@ basic
range
mark
disable-tooltip
format
```
## API

View File

@ -1,9 +0,0 @@
# 格式化弹出提示
```html
<n-slider
v-model:value="value"
:step="10"
:format-tooltip="value => `${value}%`"
/>
```

View File

@ -9,7 +9,6 @@ basic
range
mark
disable-tooltip
format
```
## API

View File

@ -10,10 +10,10 @@ basic
## Props
| Name | Type | Default | Description |
| ----- | -------- | ----------- | ------------------------ |
| label | `string` | `undefined` | Label of the statistics. |
| value | `string` | `undefined` | Statistics value. |
| Name | Type | Default | Description |
| ----- | -------- | ----------- | ----------- |
| label | `string` | `undefined` | |
| value | `string` | `undefined` | |
## Slots
@ -22,4 +22,4 @@ basic
| default | `()` | Value slot. |
| label | `()` | Label slot. |
| prefix | `()` | Value prefix. |
| suffix | `()` | Value suffix. |
| suffix | `()` | Valut suffix. |

View File

@ -10,10 +10,10 @@ basic
## Props
| 名称 | 类型 | 默认值 | 说明 |
| ----- | -------- | ----------- | ------------------- |
| label | `string` | `undefined` | 展示的 `label` 信息 |
| value | `string` | `undefined` | 统计数据的值 |
| 名称 | 类型 | 默认值 | 说明 |
| ----- | -------- | ----------- | ---- |
| label | `string` | `undefined` | |
| value | `string` | `undefined` | |
## Slots

View File

@ -24,8 +24,8 @@ You can use `n-table`, `n-thead`, `n-tbody`, `n-tr`, `n-th` and `n-td`. At most
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| bottom-bordered | `boolean` | `true` | The bottom border of the table, this prop is invalid when `bordered` is `true`. |
| bordered | `boolean` | `true` | Whether to show table border. |
| single-column | `boolean` | `false` | Whether to display as a column (when `true`, each column has `border-right`). |
| single-line | `boolean` | `true` | Whether to display as a line (when `true`, each row has `border-bottom`). |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Table size. |
| buttom-bordered | `boolean` | `true` | |
| bordered | `boolean` | `true` | |
| single-column | `boolean` | `false` | |
| single-line | `boolean` | `true` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |

View File

@ -22,10 +22,10 @@ single-line
### Table Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| bottom-bordered | `boolean` | `true` | 表格底部是否有边框,在 `bordered``true` 时该参数无效 |
| bordered | `boolean` | `true` | 是否显示边框 |
| single-column | `boolean` | `false` | 是否展示为一列(`true` 时每一列都有 `border-right` |
| single-line | `boolean` | `true` | 是否展示为一行(`true` 时每一行都有 `border-bottom` |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 表格尺寸大小 |
| 名称 | 类型 | 默认值 | 说明 |
| --------------- | -------------------------------- | ---------- | ---- |
| buttom-bordered | `boolean` | `true` | |
| bordered | `boolean` | `true` | |
| single-column | `boolean` | `false` | |
| single-line | `boolean` | `true` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |

View File

@ -1 +1 @@
export default '2.15.6'
export default '2.15.5'