diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index abbbd9715..6acee645a 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,22 +1,30 @@ # CHANGELOG -## Pending +## 2.15.6 (2021-07-23) ### 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) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 2606c1641..1c983c20f 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -1,22 +1,30 @@ # CHANGELOG -## Pending +## 2.15.6 (2021-07-23) ### 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) diff --git a/jest.config.js b/jest.config.js index 07ee1ef79..98c207b1f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -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: [], + setupFilesAfterEnv: ['/src/jest-setup.ts'], // A list of paths to snapshot serializer modules Jest should use for snapshot testing // snapshotSerializers: [], diff --git a/package.json b/package.json index c08f35e89..39b52d0a6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "naive-ui", - "version": "2.15.5", + "version": "2.15.6", "description": "A Vue 3 Component Library. Fairly Complete, Customizable Themes, Uses TypeScript, Not Too Slow", "main": "lib/index.js", "module": "es/index.js", diff --git a/src/checkbox/demos/enUS/index.demo-entry.md b/src/checkbox/demos/enUS/index.demo-entry.md index 593d3416b..a753b019e 100644 --- a/src/checkbox/demos/enUS/index.demo-entry.md +++ b/src/checkbox/demos/enUS/index.demo-entry.md @@ -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 \| (() => VNodeChild)` | `undefined` | Checkbox label. | +| label | `string` | `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. | diff --git a/src/checkbox/demos/zhCN/index.demo-entry.md b/src/checkbox/demos/zhCN/index.demo-entry.md index 13fbebce5..799f196c3 100644 --- a/src/checkbox/demos/zhCN/index.demo-entry.md +++ b/src/checkbox/demos/zhCN/index.demo-entry.md @@ -24,7 +24,7 @@ event | disabled | `boolean` | `false` | 是否禁用 | | focusable | `boolean` | `true` | 是否可被 focus | | indeterminate | `boolean` | `false` | 是否部分选中 | -| label | `string \| (() => VNodeChild)` | `undefined` | Checkbox 的标签 | +| label | `string` | `undefined` | Checkbox 的标签 | | value | `string \| number` | `undefined` | Checkbox 在 checkbox group 中使用的值 | | on-update:checked | `(checked: boolean) => void` | `undefined` | 当 checked 改变时触发的回调函数 | diff --git a/src/color-picker/demos/enUS/index.demo-entry.md b/src/color-picker/demos/enUS/index.demo-entry.md index eaaa63b94..35687724f 100644 --- a/src/color-picker/demos/enUS/index.demo-entry.md +++ b/src/color-picker/demos/enUS/index.demo-entry.md @@ -27,3 +27,4 @@ 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 | diff --git a/src/color-picker/demos/zhCN/alpha.demo.md b/src/color-picker/demos/zhCN/alpha.demo.md index 1659960f4..77f4365b1 100644 --- a/src/color-picker/demos/zhCN/alpha.demo.md +++ b/src/color-picker/demos/zhCN/alpha.demo.md @@ -3,5 +3,5 @@ 用 `show-alpha` 设定是否可调节 alpha 通道。 ```html - + ``` diff --git a/src/color-picker/demos/zhCN/index.demo-entry.md b/src/color-picker/demos/zhCN/index.demo-entry.md index 2203fb2fa..5d6639681 100644 --- a/src/color-picker/demos/zhCN/index.demo-entry.md +++ b/src/color-picker/demos/zhCN/index.demo-entry.md @@ -27,3 +27,4 @@ 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` | 显示按钮 | diff --git a/src/color-picker/src/ColorPicker.tsx b/src/color-picker/src/ColorPicker.tsx index 673c327a0..e9a42e154 100644 --- a/src/color-picker/src/ColorPicker.tsx +++ b/src/color-picker/src/ColorPicker.tsx @@ -59,7 +59,7 @@ import Pallete from './Pallete' import ColorInput from './ColorInput' import ColorPickerTrigger from './ColorPickerTrigger' import { deriveDefaultValue, getModeFromValue } from './utils' -import type { ColorPickerMode } from './utils' +import type { ColorPickerMode, ActionType } from './utils' import style from './styles/index.cssr' import { OnUpdateValue, OnUpdateValueImpl } from './interface' import { NButton } from '../../button' @@ -86,6 +86,10 @@ export const colorPickerPanelProps = { type: Boolean, default: true }, + actions: { + type: Array as PropType, + default: null + }, internalActions: Array as PropType>, size: String as PropType<'small' | 'medium' | 'large'>, onComplete: Function as PropType, @@ -421,6 +425,11 @@ 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 @@ -481,7 +490,7 @@ export default defineComponent({ function renderPanel (): VNode { const { value: rgba } = rgbaRef const { value: displayedHue } = displayedHueRef - const { internalActions, modes } = props + const { internalActions, modes, actions } = props const { value: mergedTheme } = themeRef const { value: mergedClsPrefix } = mergedClsPrefixRef return ( @@ -527,6 +536,20 @@ export default defineComponent({ onUpdateValue={handleInputUpdateValue} /> + {actions?.length ? ( +
+ {actions.includes('confirm') && ( + + {{ default: () => localeRef.value.confirm }} + + )} +
+ ) : null} {slots.action ? (
{{ default: slots.action }} diff --git a/src/color-picker/src/utils.ts b/src/color-picker/src/utils.ts index 656a3a24e..603a2714e 100644 --- a/src/color-picker/src/utils.ts +++ b/src/color-picker/src/utils.ts @@ -2,6 +2,8 @@ import { warn } from '../../_utils' export type ColorPickerMode = 'rgb' | 'hsl' | 'hsv' | 'hex' +export type ActionType = 'confirm' + export function deriveDefaultValue ( modes: ColorPickerMode[], showAlpha: boolean diff --git a/src/color-picker/tests/ColorPicker.spec.tsx b/src/color-picker/tests/ColorPicker.spec.tsx index 8b0def3c1..edd2dcc7f 100644 --- a/src/color-picker/tests/ColorPicker.spec.tsx +++ b/src/color-picker/tests/ColorPicker.spec.tsx @@ -2,6 +2,7 @@ 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', () => { @@ -72,4 +73,24 @@ 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() + }) + }) }) diff --git a/src/data-table/demos/enUS/index.demo-entry.md b/src/data-table/demos/enUS/index.demo-entry.md index 042e0162c..d75760101 100644 --- a/src/data-table/demos/enUS/index.demo-entry.md +++ b/src/data-table/demos/enUS/index.demo-entry.md @@ -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-bottom). | +| 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. | | summary | `CreateSummary` | `undefined` | Data of table summary row. For types, see CreateSummary Type. | diff --git a/src/data-table/demos/zhCN/index.demo-entry.md b/src/data-table/demos/zhCN/index.demo-entry.md index f65393d4a..a7715a556 100644 --- a/src/data-table/demos/zhCN/index.demo-entry.md +++ b/src/data-table/demos/zhCN/index.demo-entry.md @@ -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-bottom) | +| single-column | `boolean` | `false` | 是否展示为一列(true 时每一列都有 border-right) | | single-line | `boolean` | `true` | 是否展示为一行(true 时每一行都有 border-bottom) | | size | `'small' \| 'medium' \| 'large'` | `'medium'` | 表格的尺寸 | | summary | `CreateSummary` | `undefined` | 表格总结栏的数据,类型见 CreateSummary Type | diff --git a/src/data-table/src/TableParts/Body.tsx b/src/data-table/src/TableParts/Body.tsx index cc28aad17..6690b2ae9 100644 --- a/src/data-table/src/TableParts/Body.tsx +++ b/src/data-table/src/TableParts/Body.tsx @@ -286,6 +286,7 @@ export default defineComponent({ setHeaderScrollLeft } = this const contentStyle = { + width: '100%', minWidth: formatLength(scrollX) } return ( @@ -540,6 +541,10 @@ export default defineComponent({ ) }) const props = rowProps ? rowProps(rowData, rowIndex) : undefined + const mergedRowClassName = + typeof rowClassName === 'string' + ? rowClassName + : createRowClassName(rowData, rowIndex, rowClassName) const row = ( { @@ -548,7 +553,7 @@ export default defineComponent({ key={rowKey} class={[ `${mergedClsPrefix}-data-table-tr`, - createRowClassName(rowData, rowIndex, rowClassName) + mergedRowClassName ]} {...props} > diff --git a/src/descriptions/src/Descriptions.tsx b/src/descriptions/src/Descriptions.tsx index d476ee14b..583aebf30 100644 --- a/src/descriptions/src/Descriptions.tsx +++ b/src/descriptions/src/Descriptions.tsx @@ -9,7 +9,13 @@ 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' @@ -82,14 +88,10 @@ 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 { diff --git a/src/dialog/demos/enUS/action.demo.md b/src/dialog/demos/enUS/action.demo.md new file mode 100644 index 000000000..c056e340b --- /dev/null +++ b/src/dialog/demos/enUS/action.demo.md @@ -0,0 +1,31 @@ +# Custom Action + +Sometimes you may want to customize `action` and `content` . + +```html + + Use Render Function + +``` + +```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' + }) + } + } + } +} +``` diff --git a/src/dialog/demos/enUS/index.demo-entry.md b/src/dialog/demos/enUS/index.demo-entry.md index c060888eb..7db96a540 100644 --- a/src/dialog/demos/enUS/index.demo-entry.md +++ b/src/dialog/demos/enUS/index.demo-entry.md @@ -36,6 +36,8 @@ export default { basic async use-component +mask +action ``` ## API @@ -55,6 +57,7 @@ use-component | 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. | @@ -70,6 +73,7 @@ use-component | onClose | `() => boolean \| Promise \| 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 \| 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 \| 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 diff --git a/src/dialog/demos/enUS/mask.demo.md b/src/dialog/demos/enUS/mask.demo.md new file mode 100644 index 000000000..b3789aeb4 --- /dev/null +++ b/src/dialog/demos/enUS/mask.demo.md @@ -0,0 +1,32 @@ +# 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 +Callback on Mask Clicked +``` + +```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') + } + }) + } + } + } +} +``` diff --git a/src/dialog/demos/zhCN/action.demo.md b/src/dialog/demos/zhCN/action.demo.md new file mode 100644 index 000000000..17d4aee59 --- /dev/null +++ b/src/dialog/demos/zhCN/action.demo.md @@ -0,0 +1,31 @@ +# 自定义 Action + +有的时候你想自定义 `action` 和 `content`。 + +```html + + 使用渲染函数 + +``` + +```js +import { useDialog, NTag } from 'naive-ui' + +export default { + components: { + NTag + }, + setup () { + const dialog = useDialog() + return { + handleButtonClick () { + dialog.warning({ + title: '使用渲染函数', + content: () => 'Content', + action: () => 'Action' + }) + } + } + } +} +``` diff --git a/src/dialog/demos/zhCN/index.demo-entry.md b/src/dialog/demos/zhCN/index.demo-entry.md index 3cd9c98f7..64ca7e49b 100644 --- a/src/dialog/demos/zhCN/index.demo-entry.md +++ b/src/dialog/demos/zhCN/index.demo-entry.md @@ -37,6 +37,8 @@ export default { basic async use-component +mask +action ``` ## API @@ -56,6 +58,7 @@ use-component | 名称 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | +| action | `() => VNodeChild` | `undefined` | 操作区域的内容,需要是 render 函数 | | bordered | `boolean` | `false` | 是否显示 border | | closable | `boolean` | `true` | 是否显示 close 图标 | | content | `string \| (() => VNodeChild)` | `undefined` | 对话框内容,可以是 render 函数 | @@ -71,6 +74,7 @@ use-component | onClose | `() => boolean \| Promise \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 | | onNegativeClick | `() => boolean \| Promise \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 | | onPositiveClick | `() => boolean \| Promise \| any` | `undefined` | 默认行为是关闭确认框。返回 `false` 或者 resolve `false` 或者 Promise 被 reject 会避免默认行为 | +| onMaskClick | `() => void` | `undefined` | 点击蒙层后执行的回调 | ### DialogReactive API diff --git a/src/dialog/demos/zhCN/mask.demo.md b/src/dialog/demos/zhCN/mask.demo.md new file mode 100644 index 000000000..873e72c3c --- /dev/null +++ b/src/dialog/demos/zhCN/mask.demo.md @@ -0,0 +1,32 @@ +# 点击遮罩 + +我觉得用户应该聪明到点遮罩没用的时候就去点确认了。 + +```html +点击遮罩的事件 +``` + +```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('不能关闭') + } + }) + } + } + } +} +``` diff --git a/src/dialog/src/Dialog.tsx b/src/dialog/src/Dialog.tsx index 294d5c5e2..113e0a4c6 100644 --- a/src/dialog/src/Dialog.tsx +++ b/src/dialog/src/Dialog.tsx @@ -50,6 +50,7 @@ const dialogProps = { negativeText: String, positiveText: String, content: [String, Function] as PropType VNodeChild)>, + action: Function as PropType<() => VNodeChild>, showIcon: { type: Boolean, default: true @@ -184,6 +185,7 @@ export default defineComponent({ showIcon, title, content, + action, negativeText, positiveText, handlePositiveClick, @@ -243,38 +245,45 @@ export default defineComponent({
{renderSlot($slots, 'default', undefined, () => [render(content)])}
- {$slots.action || (!$slots.action && (positiveText || negativeText)) ? ( + {$slots.action || positiveText || negativeText || action ? (
- {renderSlot($slots, 'action', undefined, () => [ - this.negativeText && ( - - {{ - default: () => render(this.negativeText) - }} - - ), - this.positiveText && ( - - {{ - default: () => render(this.positiveText) - }} - - ) - ])} + {renderSlot( + $slots, + 'action', + undefined, + action + ? () => [render(action)] + : () => [ + this.negativeText && ( + + {{ + default: () => render(this.negativeText) + }} + + ), + this.positiveText && ( + + {{ + default: () => render(this.positiveText) + }} + + ) + ] + )}
) : null}
diff --git a/src/dialog/src/DialogEnvironment.tsx b/src/dialog/src/DialogEnvironment.tsx index 6caaf4d36..1926e4f06 100644 --- a/src/dialog/src/DialogEnvironment.tsx +++ b/src/dialog/src/DialogEnvironment.tsx @@ -17,7 +17,8 @@ export const exposedDialogEnvProps = { onNegativeClick: Function as PropType< (e: MouseEvent) => Promise | boolean | unknown >, - onClose: Function as PropType<() => Promise | boolean | unknown> + onClose: Function as PropType<() => Promise | boolean | unknown>, + onMaskClick: Function as PropType<(e: MouseEvent) => void> } export default defineComponent({ @@ -73,6 +74,13 @@ 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 } @@ -86,7 +94,8 @@ export default defineComponent({ handleAfterLeave, handleCloseClick, handleNegativeClick, - handlePositiveClick + handlePositiveClick, + handleMaskClick } }, render () { @@ -96,6 +105,7 @@ export default defineComponent({ handleNegativeClick, handleCloseClick, handleAfterLeave, + handleMaskClick, to, maskClosable, show @@ -104,6 +114,7 @@ export default defineComponent({ { expect(wrapper.find('button').exists()).toEqual(false) }) - it('async', async () => { + it('loading', async () => { const Test = defineComponent({ setup () { const dialog = useDialog() dialog.success({ - title: 'Async', + title: 'Loading', content: 'Content', + positiveText: '确认', loading: true }) }, @@ -68,4 +69,51 @@ describe('n-dialog', () => { await mount(() => {{ default: () => }}) 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(() => {{ default: () => }}) + 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(() => {{ default: () => }}) + document.body.dispatchEvent(mousedownEvent) + document.body.dispatchEvent(mouseupEvent) + expect(onMaskClick).toHaveBeenCalled() + }) }) diff --git a/src/icon/demos/enUS/index.demo-entry.md b/src/icon/demos/enUS/index.demo-entry.md index 3332c1ceb..e4188a93b 100644 --- a/src/icon/demos/enUS/index.demo-entry.md +++ b/src/icon/demos/enUS/index.demo-entry.md @@ -20,6 +20,6 @@ depth ## Slots -| Name | Parameters | Description | -| ------- | ---------- | ----------- | -| default | `()` | | +| Name | Parameters | Description | +| ------- | ---------- | ------------------------ | +| default | `()` | The content of the icon. | diff --git a/src/icon/demos/zhCN/index.demo-entry.md b/src/icon/demos/zhCN/index.demo-entry.md index 004f2f84e..9a1329957 100644 --- a/src/icon/demos/zhCN/index.demo-entry.md +++ b/src/icon/demos/zhCN/index.demo-entry.md @@ -20,8 +20,8 @@ depth ## Slots -| 名称 | 参数 | 说明 | -| ------- | ---- | ---- | -| default | `()` | | +| 名称 | 参数 | 说明 | +| ------- | ---- | ---------- | +| default | `()` | 图标的内容 | diff --git a/src/jest-setup.ts b/src/jest-setup.ts new file mode 100644 index 000000000..a2376bc87 --- /dev/null +++ b/src/jest-setup.ts @@ -0,0 +1,2 @@ +// https://github.com/jsdom/jsdom/issues/1422 +HTMLDivElement.prototype.scrollTo = () => {} diff --git a/src/locales/common/enUS.ts b/src/locales/common/enUS.ts index 8fdb3e4d3..be27b541a 100644 --- a/src/locales/common/enUS.ts +++ b/src/locales/common/enUS.ts @@ -2,7 +2,8 @@ const enUS = { name: 'en-US', global: { undo: 'Undo', - redo: 'Redo' + redo: 'Redo', + confirm: 'Confirm' }, Popconfirm: { positiveText: 'Confirm', diff --git a/src/locales/common/zhCN.ts b/src/locales/common/zhCN.ts index 6b3e9f5c1..b451c3a1e 100644 --- a/src/locales/common/zhCN.ts +++ b/src/locales/common/zhCN.ts @@ -4,7 +4,8 @@ const zhCN: NLocale = { name: 'zh-CN', global: { undo: '撤销', - redo: '重做' + redo: '重做', + confirm: '确认' }, Popconfirm: { positiveText: '确认', diff --git a/src/log/demos/enUS/index.demo-entry.md b/src/log/demos/enUS/index.demo-entry.md index ba8ef98ec..847bac8a8 100644 --- a/src/log/demos/enUS/index.demo-entry.md +++ b/src/log/demos/enUS/index.demo-entry.md @@ -53,21 +53,21 @@ loading | Name | Type | Default | Description | | --- | --- | --- | --- | -| font-size | `number` | `14` | | -| hljs | `Object` | `undefined` | | -| language | `string` | `undefined` | | -| line-height | `number` | `1.25` | | -| lines | `Array` | `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` | | +| 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` | `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. | ## Methods | Name | Parameters | Description | | --- | --- | --- | -| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | | +| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | Callback function for scroll event. | diff --git a/src/log/demos/zhCN/index.demo-entry.md b/src/log/demos/zhCN/index.demo-entry.md index c23b4a408..b00a0da78 100644 --- a/src/log/demos/zhCN/index.demo-entry.md +++ b/src/log/demos/zhCN/index.demo-entry.md @@ -51,23 +51,23 @@ loading ## Props -| 名称 | 类型 | 默认值 | 说明 | -| --------------- | ----------------------------------- | ----------- | ---- | -| font-size | `number` | `14` | | -| hljs | `Object` | `undefined` | | -| language | `string` | `undefined` | | -| line-height | `number` | `1.25` | | -| lines | `Array` | `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` | | +| 名称 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| font-size | `number` | `14` | 文字大小 | +| hljs | `Object` | `undefined` | 如果你想局部设定 `hljs` ,可以通过这个属性传给组件 | +| language | `string` | `undefined` | 日志在 `highlightjs` 中的语言 | +| line-height | `number` | `1.25` | 行高 | +| lines | `Array` | `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` | 滚动到底部的回调函数 | ## Methods | 名称 | 参数 | 说明 | | --- | --- | --- | -| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | | +| scrollTo | `(options: { top?: number, position?: 'top' \| 'bottom', slient?: boolean })` | 滚动事件的回调函数 | diff --git a/src/mention/demos/enUS/basic.demo.md b/src/mention/demos/enUS/basic.demo.md index 5a26124f1..84fb41a1a 100644 --- a/src/mention/demos/enUS/basic.demo.md +++ b/src/mention/demos/enUS/basic.demo.md @@ -1,11 +1,15 @@ # Basic Usage +If `label` is a callback function, input matching will be performed according to `value`. + ```html ``` ```js -import { defineComponent } from 'vue' +import { defineComponent, h } from 'vue' +import { NIcon } from 'naive-ui' +import { HomeOutline as HomeIcon } from '@vicons/ionicons5' export default defineComponent({ setup () { @@ -24,7 +28,15 @@ export default defineComponent({ value: 'Guandong-Road' }, { - label: 'No.5-Yiheyuan-Road', + label: (option) => + h('span', null, [ + h( + NIcon, + { style: 'margin-right: 5px' }, + { default: () => h(HomeIcon) } + ), + option.value + ]), value: 'No.5-Yiheyuan-Road' } ] diff --git a/src/mention/demos/enUS/index.demo-entry.md b/src/mention/demos/enUS/index.demo-entry.md index a07245f19..20c36d68b 100644 --- a/src/mention/demos/enUS/index.demo-entry.md +++ b/src/mention/demos/enUS/index.demo-entry.md @@ -43,7 +43,7 @@ Mention is provided after `v2.2.0`. | --- | --- | --- | | class | `string` | Option class name. | | disabled | `boolean` | Option disabled status. | -| label | `string` | Option label. | +| label | `string \| (option: MentionOption) => VNodeChild` | Option label. | | render | `(option: MentionOption) => VNodeChild` | Support custom options via `render` rendering function. | | style | `string` | Option style. | | value | `string` | Should be unique. | diff --git a/src/mention/demos/zhCN/basic.demo.md b/src/mention/demos/zhCN/basic.demo.md index d8fff811d..d1cb859e9 100644 --- a/src/mention/demos/zhCN/basic.demo.md +++ b/src/mention/demos/zhCN/basic.demo.md @@ -1,11 +1,15 @@ # 基本用法 +如果 `label` 是回调函数,输入匹配则会根据 `value` 进行匹配 + ```html ``` ```js -import { defineComponent } from 'vue' +import { defineComponent, h } from 'vue' +import { NIcon } from 'naive-ui' +import { HomeOutline as HomeIcon } from '@vicons/ionicons5' export default defineComponent({ setup () { @@ -24,7 +28,15 @@ export default defineComponent({ value: '广东路' }, { - label: '颐和园路5号', + label: (option) => + h('span', null, [ + h( + NIcon, + { style: 'margin-right: 5px' }, + { default: () => h(HomeIcon) } + ), + option.value + ]), value: '颐和园路5号' } ] diff --git a/src/mention/demos/zhCN/index.demo-entry.md b/src/mention/demos/zhCN/index.demo-entry.md index e35c01a70..90405d453 100644 --- a/src/mention/demos/zhCN/index.demo-entry.md +++ b/src/mention/demos/zhCN/index.demo-entry.md @@ -43,7 +43,7 @@ Mention 在 `v2.2.0` 及以后可用。 | --- | --- | --- | | class | `string` | 选项的自定义类名 | | disabled | `boolean` | 选项是否禁用 | -| label | `string` | 选项的标签 | +| label | `string \| (option: MentionOption) => VNodeChild` | 选项的标签 | | render | `(option: MentionOption) => VNodeChild` | 支持通过 `render` 渲染函数自定义选项 | | style | `string` | 选项的样式 | | value | `string` | 在选项中应该是唯一的 | diff --git a/src/mention/src/Mention.tsx b/src/mention/src/Mention.tsx index 92bfc25f6..4c16a82d3 100644 --- a/src/mention/src/Mention.tsx +++ b/src/mention/src/Mention.tsx @@ -126,7 +126,10 @@ export default defineComponent({ const { value: pattern } = partialPatternRef return props.options.filter((option) => { if (!pattern) return true - return option.label.startsWith(pattern) + if (typeof option.label === 'string') { + return option.label.startsWith(pattern) + } + return option.value.startsWith(pattern) }) }) const treeMateRef = computed(() => { diff --git a/src/mention/src/interface.ts b/src/mention/src/interface.ts index 18eeac890..b4cec2c23 100644 --- a/src/mention/src/interface.ts +++ b/src/mention/src/interface.ts @@ -1,3 +1,3 @@ import type { SelectBaseOption } from '../../select/src/interface' -export type MentionOption = SelectBaseOption +export type MentionOption = SelectBaseOption diff --git a/src/menu/demos/enUS/index.demo-entry.md b/src/menu/demos/enUS/index.demo-entry.md index f0e5b1b2f..926506aab 100644 --- a/src/menu/demos/enUS/index.demo-entry.md +++ b/src/menu/demos/enUS/index.demo-entry.md @@ -36,6 +36,7 @@ long-label | inverted | `boolean` | `false` | Use inverted style. | | options | `Array` | `[]` | 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. | diff --git a/src/menu/demos/enUS/render-label.demo.md b/src/menu/demos/enUS/render-label.demo.md index ac12e0a12..7c8782cdc 100644 --- a/src/menu/demos/enUS/render-label.demo.md +++ b/src/menu/demos/enUS/render-label.demo.md @@ -1,6 +1,6 @@ -# Render Label +# Batch Customizing Menu Options -The `render-label` can be used to batch render menu options. +The `render-label`, `render-icon` can be used to batch render menu options. ```html @@ -22,6 +22,7 @@ The `render-label` can be used to batch render menu options. :collapsed-icon-size="22" :options="menuOptions" :render-label="renderMenuLabel" + :render-icon="renderMenuIcon" /> @@ -34,27 +35,17 @@ The `render-label` can be used to batch render menu options. ```js import { h, ref, defineComponent } from 'vue' import { NIcon } from 'naive-ui' -import { - BookOutline as BookIcon, - PersonOutline as PersonIcon, - WineOutline as WineIcon -} from '@vicons/ionicons5' - -function renderIcon (icon) { - return () => h(NIcon, null, { default: () => h(icon) }) -} +import { BookmarkOutline } from '@vicons/ionicons5' 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: [ { @@ -66,13 +57,11 @@ const menuOptions = [ { label: 'A Wild Sheep Chase', key: 'a-wild-sheep-chase', - disabled: true, - icon: renderIcon(BookIcon) + disabled: true }, { label: 'Dance Dance Dance', key: 'Dance Dance Dance', - icon: renderIcon(BookIcon), children: [ { type: 'group', @@ -81,20 +70,17 @@ const menuOptions = [ children: [ { label: 'Narrator', - key: 'narrator', - icon: renderIcon(PersonIcon) + key: 'narrator' }, { label: 'Sheep Man', - key: 'sheep-man', - icon: renderIcon(PersonIcon) + key: 'sheep-man' } ] }, { label: 'Beverage', key: 'beverage', - icon: renderIcon(WineIcon), children: [ { label: 'Whisky', @@ -131,6 +117,9 @@ export default defineComponent({ return h('a', { href: option.href, target: '_blank' }, option.label) } return option.label + }, + renderMenuIcon () { + return h(NIcon, null, { default: () => h(BookmarkOutline) }) } } } diff --git a/src/menu/demos/enUS/select.demo.md b/src/menu/demos/enUS/select.demo.md index 23bc17a4d..ca78eba0e 100644 --- a/src/menu/demos/enUS/select.demo.md +++ b/src/menu/demos/enUS/select.demo.md @@ -1,6 +1,6 @@ # Select & Routing -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. +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 `` or `` to set route. diff --git a/src/menu/demos/zhCN/index.demo-entry.md b/src/menu/demos/zhCN/index.demo-entry.md index e9b12f4eb..1f5de9933 100644 --- a/src/menu/demos/zhCN/index.demo-entry.md +++ b/src/menu/demos/zhCN/index.demo-entry.md @@ -36,7 +36,8 @@ long-label | inverted | `boolean` | `false` | 使用反转样式 | | options | `Array` | `[]` | 菜单的数据 | | mode | `'vertical' \| 'horizontal'` | `'vertical'` | 菜单的布局方式 | -| render-label | `(option: MenuOption \| MenuGroupOption) => VNodeChild` | `undefined` | 批量处理菜单渲染 | +| render-icon | `(option: MenuOption) => 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` 的数组 | diff --git a/src/menu/demos/zhCN/render-label.demo.md b/src/menu/demos/zhCN/render-label.demo.md index e11f65803..14229de3f 100644 --- a/src/menu/demos/zhCN/render-label.demo.md +++ b/src/menu/demos/zhCN/render-label.demo.md @@ -1,6 +1,6 @@ # 批量处理菜单渲染 -使用 `render-label` 可以批量控制菜单的选项渲染。 +使用 `render-label`、`render-icon` 可以批量控制菜单的选项渲染。 ```html @@ -22,6 +22,7 @@ :collapsed-icon-size="22" :options="menuOptions" :render-label="renderMenuLabel" + :render-icon="renderMenuIcon" /> @@ -34,27 +35,17 @@ ```js import { h, ref, defineComponent } from 'vue' import { NIcon } from 'naive-ui' -import { - BookOutline as BookIcon, - PersonOutline as PersonIcon, - WineOutline as WineIcon -} from '@vicons/ionicons5' - -function renderIcon (icon) { - return () => h(NIcon, null, { default: () => h(icon) }) -} +import { BookmarkOutline } from '@vicons/ionicons5' 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: [ { @@ -66,13 +57,11 @@ const menuOptions = [ { label: '寻羊冒险记', key: 'a-wild-sheep-chase', - disabled: true, - icon: renderIcon(BookIcon) + disabled: true }, { label: '舞,舞,舞', key: 'dance-dance-dance', - icon: renderIcon(BookIcon), children: [ { type: 'group', @@ -81,20 +70,17 @@ const menuOptions = [ children: [ { label: '叙事者', - key: 'narrator', - icon: renderIcon(PersonIcon) + key: 'narrator' }, { label: '羊男', - key: 'sheep-man', - icon: renderIcon(PersonIcon) + key: 'sheep-man' } ] }, { label: '饮品', key: 'beverage', - icon: renderIcon(WineIcon), children: [ { label: '威士忌', @@ -131,6 +117,9 @@ export default defineComponent({ return h('a', { href: option.href, target: '_blank' }, option.label) } return option.label + }, + renderMenuIcon () { + return h(NIcon, null, { default: () => h(BookmarkOutline) }) } } } diff --git a/src/menu/src/Menu.tsx b/src/menu/src/Menu.tsx index 8f8d8bcc6..c937ec73e 100644 --- a/src/menu/src/Menu.tsx +++ b/src/menu/src/Menu.tsx @@ -149,6 +149,7 @@ const menuProps = { }, default: undefined }, + renderIcon: Function as PropType<(option: MenuOption) => VNodeChild>, renderLabel: Function as PropType< (option: MenuOption | MenuGroupOption) => VNodeChild >, diff --git a/src/menu/src/MenuOptionContent.tsx b/src/menu/src/MenuOptionContent.tsx index b5afd19c4..45234e8ef 100644 --- a/src/menu/src/MenuOptionContent.tsx +++ b/src/menu/src/MenuOptionContent.tsx @@ -63,7 +63,7 @@ export default defineComponent({ const { clsPrefix, tmNode, - menuProps: { renderLabel } + menuProps: { renderIcon, renderLabel } } = this return (
- {this.icon ? ( + {renderIcon || this.icon ? (
- {render(this.icon)} + {renderIcon ? renderIcon(tmNode.rawNode) : render(this.icon)}
) : null}
diff --git a/src/menu/src/Submenu.tsx b/src/menu/src/Submenu.tsx index 93cce4ab7..6fb0b2679 100644 --- a/src/menu/src/Submenu.tsx +++ b/src/menu/src/Submenu.tsx @@ -116,7 +116,7 @@ export default defineComponent({ render () { const { mergedClsPrefix, - menuProps: { renderLabel } + menuProps: { renderIcon, renderLabel } } = this const createSubmenuItem = (): VNode => { const { @@ -184,6 +184,7 @@ export default defineComponent({ options={this.rawNodes} onSelect={this.doSelect} inverted={this.inverted} + renderIcon={renderIcon} renderLabel={renderLabel} > {{ diff --git a/src/menu/tests/Menu.spec.ts b/src/menu/tests/Menu.spec.ts index c5ae16e88..6e6425c59 100644 --- a/src/menu/tests/Menu.spec.ts +++ b/src/menu/tests/Menu.spec.ts @@ -1,7 +1,9 @@ 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', () => { @@ -133,4 +135,50 @@ 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) + }) }) diff --git a/src/modal/src/Modal.tsx b/src/modal/src/Modal.tsx index 4857bc802..3d5860b3c 100644 --- a/src/modal/src/Modal.tsx +++ b/src/modal/src/Modal.tsx @@ -66,6 +66,7 @@ const modalProps = { onClose: Function as PropType<() => Promise | boolean | any>, onPositiveClick: Function as PropType<() => Promise | boolean | any>, onNegativeClick: Function as PropType<() => Promise | boolean | any>, + onMaskClick: Function as PropType<(e: MouseEvent) => void>, // deprecated overlayStyle: { type: [String, Object] as PropType, @@ -192,6 +193,10 @@ 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) diff --git a/src/pagination/src/Pagination.tsx b/src/pagination/src/Pagination.tsx index 87e1a9dbb..4e1ff7e47 100644 --- a/src/pagination/src/Pagination.tsx +++ b/src/pagination/src/Pagination.tsx @@ -157,7 +157,7 @@ export default defineComponent({ return (mergedPageRef.value - 1) * mergedPageSizeRef.value }) const endIndexRef = computed(() => { - const endIndex = mergedPageRef.value * mergedPageSizeRef.value + const endIndex = mergedPageRef.value * mergedPageSizeRef.value - 1 const { itemCount } = props if (itemCount !== undefined) { return endIndex > itemCount ? itemCount : endIndex diff --git a/src/slider/demos/enUS/format.demo.md b/src/slider/demos/enUS/format.demo.md new file mode 100644 index 000000000..8384e811e --- /dev/null +++ b/src/slider/demos/enUS/format.demo.md @@ -0,0 +1,9 @@ +# Format Tooltip + +```html + +``` diff --git a/src/slider/demos/enUS/index.demo-entry.md b/src/slider/demos/enUS/index.demo-entry.md index 89d486783..a29f32734 100644 --- a/src/slider/demos/enUS/index.demo-entry.md +++ b/src/slider/demos/enUS/index.demo-entry.md @@ -9,6 +9,7 @@ basic range mark disable-tooltip +format ``` ## API diff --git a/src/slider/demos/zhCN/format.demo.md b/src/slider/demos/zhCN/format.demo.md new file mode 100644 index 000000000..a749b6987 --- /dev/null +++ b/src/slider/demos/zhCN/format.demo.md @@ -0,0 +1,9 @@ +# 格式化弹出提示 + +```html + +``` diff --git a/src/slider/demos/zhCN/index.demo-entry.md b/src/slider/demos/zhCN/index.demo-entry.md index 10b7347ef..23ca635b7 100644 --- a/src/slider/demos/zhCN/index.demo-entry.md +++ b/src/slider/demos/zhCN/index.demo-entry.md @@ -9,6 +9,7 @@ basic range mark disable-tooltip +format ``` ## API diff --git a/src/statistic/demos/enUS/index.demo-entry.md b/src/statistic/demos/enUS/index.demo-entry.md index bcff08c50..5b8073f74 100644 --- a/src/statistic/demos/enUS/index.demo-entry.md +++ b/src/statistic/demos/enUS/index.demo-entry.md @@ -10,10 +10,10 @@ basic ## Props -| Name | Type | Default | Description | -| ----- | -------- | ----------- | ----------- | -| label | `string` | `undefined` | | -| value | `string` | `undefined` | | +| Name | Type | Default | Description | +| ----- | -------- | ----------- | ------------------------ | +| label | `string` | `undefined` | Label of the statistics. | +| value | `string` | `undefined` | Statistics value. | ## Slots @@ -22,4 +22,4 @@ basic | default | `()` | Value slot. | | label | `()` | Label slot. | | prefix | `()` | Value prefix. | -| suffix | `()` | Valut suffix. | +| suffix | `()` | Value suffix. | diff --git a/src/statistic/demos/zhCN/index.demo-entry.md b/src/statistic/demos/zhCN/index.demo-entry.md index c6a3a4733..7c222ba4e 100644 --- a/src/statistic/demos/zhCN/index.demo-entry.md +++ b/src/statistic/demos/zhCN/index.demo-entry.md @@ -10,10 +10,10 @@ basic ## Props -| 名称 | 类型 | 默认值 | 说明 | -| ----- | -------- | ----------- | ---- | -| label | `string` | `undefined` | | -| value | `string` | `undefined` | | +| 名称 | 类型 | 默认值 | 说明 | +| ----- | -------- | ----------- | ------------------- | +| label | `string` | `undefined` | 展示的 `label` 信息 | +| value | `string` | `undefined` | 统计数据的值 | ## Slots diff --git a/src/table/demos/enUS/index.demo-entry.md b/src/table/demos/enUS/index.demo-entry.md index 583fcd5f6..ddcf94d29 100644 --- a/src/table/demos/enUS/index.demo-entry.md +++ b/src/table/demos/enUS/index.demo-entry.md @@ -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 | | --- | --- | --- | --- | -| buttom-bordered | `boolean` | `true` | | -| bordered | `boolean` | `true` | | -| single-column | `boolean` | `false` | | -| single-line | `boolean` | `true` | | -| size | `'small' \| 'medium' \| 'large'` | `'medium'` | | +| 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. | diff --git a/src/table/demos/zhCN/index.demo-entry.md b/src/table/demos/zhCN/index.demo-entry.md index c11bff86f..3a58ea20f 100644 --- a/src/table/demos/zhCN/index.demo-entry.md +++ b/src/table/demos/zhCN/index.demo-entry.md @@ -22,10 +22,10 @@ single-line ### Table Props -| 名称 | 类型 | 默认值 | 说明 | -| --------------- | -------------------------------- | ---------- | ---- | -| buttom-bordered | `boolean` | `true` | | -| bordered | `boolean` | `true` | | -| single-column | `boolean` | `false` | | -| single-line | `boolean` | `true` | | -| size | `'small' \| 'medium' \| 'large'` | `'medium'` | | +| 名称 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| 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'` | 表格尺寸大小 | diff --git a/src/version.ts b/src/version.ts index 96d4c2cf4..1b300c64b 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export default '2.15.5' +export default '2.15.6'