From d5fdab55ccf158e56d86522229dfe528cfa003e4 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 11 Dec 2021 11:45:19 +0800 Subject: [PATCH 01/94] fix(DatetimePicker): should update value after calling picker methods (#10029) --- .../vant/src/datetime-picker/DatePicker.tsx | 4 +- .../vant/src/datetime-picker/TimePicker.tsx | 10 +++- .../datetime-picker.spec.tsx.snap | 34 +++++------ .../test/datetime-picker.spec.tsx | 58 ++++++++++++++++--- packages/vant/src/datetime-picker/utils.ts | 25 ++++++++ 5 files changed, 102 insertions(+), 29 deletions(-) diff --git a/packages/vant/src/datetime-picker/DatePicker.tsx b/packages/vant/src/datetime-picker/DatePicker.tsx index 621cec848..3bebf8809 100644 --- a/packages/vant/src/datetime-picker/DatePicker.tsx +++ b/packages/vant/src/datetime-picker/DatePicker.tsx @@ -23,6 +23,7 @@ import { getTrueValue, getMonthEndDay, pickerInheritKeys, + proxyPickerMethods, } from './utils'; // Composables @@ -316,7 +317,8 @@ export default defineComponent({ ); useExpose({ - getPicker: () => picker.value, + getPicker: () => + picker.value && proxyPickerMethods(picker.value, updateInnerValue), }); return () => ( diff --git a/packages/vant/src/datetime-picker/TimePicker.tsx b/packages/vant/src/datetime-picker/TimePicker.tsx index d3ecf692c..aac16aec1 100644 --- a/packages/vant/src/datetime-picker/TimePicker.tsx +++ b/packages/vant/src/datetime-picker/TimePicker.tsx @@ -16,7 +16,12 @@ import { createNamespace, makeNumericProp, } from '../utils'; -import { times, sharedProps, pickerInheritKeys } from './utils'; +import { + times, + sharedProps, + pickerInheritKeys, + proxyPickerMethods, +} from './utils'; // Composables import { useExpose } from '../composables/use-expose'; @@ -160,7 +165,8 @@ export default defineComponent({ ); useExpose({ - getPicker: () => picker.value, + getPicker: () => + picker.value && proxyPickerMethods(picker.value, updateInnerValue), }); return () => ( diff --git a/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap b/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap index 3b614dcc8..c69cff11f 100644 --- a/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap +++ b/packages/vant/src/datetime-picker/test/__snapshots__/datetime-picker.spec.tsx.snap @@ -1,22 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render title slot correctly 1`] = ` -
- - Custom title - -
-`; - -exports[`time type 1`] = ` +exports[`should render time type correctly 1`] = `
`; + +exports[`should render title slot correctly 1`] = ` +
+ + Custom title + +
+`; diff --git a/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx b/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx index 929b4931c..76c0978b5 100644 --- a/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx +++ b/packages/vant/src/datetime-picker/test/datetime-picker.spec.tsx @@ -3,25 +3,29 @@ import { mount, later } from '../../../test'; import { reactive } from 'vue'; import { useExpose } from '../../composables/use-expose'; -test('confirm & cancel event', () => { +test('should emit confirm event after clicking the confirm button', () => { const onConfirm = jest.fn(); - const onCancel = jest.fn(); - const wrapper = mount(DatetimePicker, { props: { onConfirm, + }, + }); + wrapper.find('.van-picker__confirm').trigger('click'); + expect(onConfirm).toHaveBeenCalledTimes(1); +}); + +test('should emit cancel event after clicking the confirm button', () => { + const onCancel = jest.fn(); + const wrapper = mount(DatetimePicker, { + props: { onCancel, }, }); - - wrapper.find('.van-picker__confirm').trigger('click'); - expect(onConfirm).toHaveBeenCalledTimes(1); - wrapper.find('.van-picker__cancel').trigger('click'); expect(onCancel).toHaveBeenCalledTimes(1); }); -test('time type', () => { +test('should render time type correctly', () => { const wrapper = mount(DatetimePicker, { props: { type: 'time', @@ -33,7 +37,7 @@ test('time type', () => { expect(wrapper.html()).toMatchSnapshot(); }); -test('getPicker method', () => { +test('should allow to call getPicker method', () => { const wrapper = mount(DatetimePicker); expect(wrapper.vm.getPicker()).toBeTruthy(); @@ -86,3 +90,39 @@ test('should emit value correctly when dynamic change min-date', async () => { wrapper.find('.van-picker__confirm').trigger('click'); expect(wrapper.emitted<[Date]>('confirm')![0][0]).toEqual(defaultValue); }); + +test('should update value correctly after calling setColumnIndex method', async () => { + const onConfirm = jest.fn(); + const defaultDate = new Date(2020, 0, 1); + const wrapper = mount(DatetimePicker, { + props: { + type: 'date', + minDate: defaultDate, + maxDate: new Date(2020, 0, 30), + modelValue: defaultDate, + onConfirm, + }, + }); + + wrapper.vm.getPicker().setColumnIndex(2, 14); + await wrapper.find('.van-picker__confirm').trigger('click'); + expect(onConfirm.mock.calls[0]).toEqual([new Date(2020, 0, 15)]); +}); + +test('should update value correctly after calling setColumnValue method', async () => { + const onConfirm = jest.fn(); + const defaultDate = new Date(2020, 0, 1); + const wrapper = mount(DatetimePicker, { + props: { + type: 'date', + minDate: defaultDate, + maxDate: new Date(2020, 0, 30), + modelValue: defaultDate, + onConfirm, + }, + }); + + wrapper.vm.getPicker().setColumnValue(2, '15'); + await wrapper.find('.van-picker__confirm').trigger('click'); + expect(onConfirm.mock.calls[0]).toEqual([new Date(2020, 0, 15)]); +}); diff --git a/packages/vant/src/datetime-picker/utils.ts b/packages/vant/src/datetime-picker/utils.ts index ee09f1387..f78e90d06 100644 --- a/packages/vant/src/datetime-picker/utils.ts +++ b/packages/vant/src/datetime-picker/utils.ts @@ -1,6 +1,7 @@ import { PropType } from 'vue'; import { extend } from '../utils'; import { pickerSharedProps } from '../picker/Picker'; +import type { PickerInstance } from '../picker'; import type { DatetimePickerColumnType } from './types'; export const sharedProps = extend({}, pickerSharedProps, { @@ -45,3 +46,27 @@ export function getTrueValue(value: string | undefined): number { export const getMonthEndDay = (year: number, month: number): number => 32 - new Date(year, month - 1, 32).getDate(); + +// https://github.com/youzan/vant/issues/10013 +export const proxyPickerMethods = ( + picker: PickerInstance, + callback: () => void +) => { + const methods = [ + 'setValues', + 'setIndexes', + 'setColumnIndex', + 'setColumnValue', + ]; + return new Proxy(picker, { + get: (target, prop: keyof PickerInstance) => { + if (methods.includes(prop)) { + return (...args: unknown[]) => { + target[prop](...args); + callback(); + }; + } + return target[prop]; + }, + }); +}; From b893f911a9fc232ecac99706c60ba2e6292dddfb Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 12 Dec 2021 20:29:10 +0800 Subject: [PATCH 02/94] fix(Field): fix the length of emoji (#10033) --- packages/vant/src/field/Field.tsx | 10 ++++--- .../test/__snapshots__/index.spec.js.snap | 29 +++++++++---------- packages/vant/src/field/test/index.spec.js | 25 +++++++++++++++- packages/vant/src/field/utils.ts | 11 +++++++ 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/packages/vant/src/field/Field.tsx b/packages/vant/src/field/Field.tsx index 41aa3166a..03957c292 100644 --- a/packages/vant/src/field/Field.tsx +++ b/packages/vant/src/field/Field.tsx @@ -27,12 +27,14 @@ import { createNamespace, } from '../utils'; import { + cutString, runSyncRule, endComposing, mapInputType, startComposing, getRuleMessage, resizeTextarea, + getStringLength, runRuleValidator, } from './utils'; import { cellSharedProps } from '../cell/Cell'; @@ -255,12 +257,12 @@ export default defineComponent({ // see: https://github.com/youzan/vant/issues/5033 const limitValueLength = (value: string) => { const { maxlength } = props; - if (isDef(maxlength) && value.length > maxlength) { + if (isDef(maxlength) && getStringLength(value) > maxlength) { const modelValue = getModelValue(); - if (modelValue && modelValue.length === +maxlength) { + if (modelValue && getStringLength(modelValue) === +maxlength) { return modelValue; } - return value.slice(0, +maxlength); + return cutString(value, +maxlength); } return value; }; @@ -462,7 +464,7 @@ export default defineComponent({ const renderWordLimit = () => { if (props.showWordLimit && props.maxlength) { - const count = getModelValue().length; + const count = getStringLength(getModelValue()); return (
{count}/{props.maxlength} diff --git a/packages/vant/src/field/test/__snapshots__/index.spec.js.snap b/packages/vant/src/field/test/__snapshots__/index.spec.js.snap index 700d799ac..3d851b865 100644 --- a/packages/vant/src/field/test/__snapshots__/index.spec.js.snap +++ b/packages/vant/src/field/test/__snapshots__/index.spec.js.snap @@ -62,21 +62,11 @@ exports[`should render textarea when type is textarea 1`] = ` `; exports[`should render word limit correctly 1`] = ` -
-
-
- -
-
- - 3 - - /3 -
-
+
+ + 3 + + /3
`; @@ -117,3 +107,12 @@ exports[`should render word limit correctly when modelValue is undefined 1`] = `
`; + +exports[`should render word limit with emoji correctly 1`] = ` +
+ + 2 + + /3 +
+`; diff --git a/packages/vant/src/field/test/index.spec.js b/packages/vant/src/field/test/index.spec.js index 676f8c3ae..8a9258124 100644 --- a/packages/vant/src/field/test/index.spec.js +++ b/packages/vant/src/field/test/index.spec.js @@ -343,7 +343,7 @@ test('should render word limit correctly', () => { showWordLimit: true, }, }); - expect(wrapper.html()).toMatchSnapshot(); + expect(wrapper.find('.van-field__word-limit').html()).toMatchSnapshot(); }); test('should render word limit correctly when modelValue is undefined', () => { @@ -475,3 +475,26 @@ test('should render error-message slot correctly', async () => { expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot(); }); + +test('should limit maxlength with emoji correctly', async () => { + const wrapper = mount(Field, { + props: { + maxlength: 3, + modelValue: '😀😀😀😀', + }, + }); + + const input = wrapper.find('input'); + expect(input.element.value).toEqual('😀😀😀'); +}); + +test('should render word limit with emoji correctly', () => { + const wrapper = mount(Field, { + props: { + modelValue: '😀😀', + maxlength: 3, + showWordLimit: true, + }, + }); + expect(wrapper.find('.van-field__word-limit').html()).toMatchSnapshot(); +}); diff --git a/packages/vant/src/field/utils.ts b/packages/vant/src/field/utils.ts index d55f97f81..9c9c3c6a0 100644 --- a/packages/vant/src/field/utils.ts +++ b/packages/vant/src/field/utils.ts @@ -107,3 +107,14 @@ export function mapInputType(type: FieldType): { return { type }; } + +// get correct length of emoji +// https://github.com/youzan/vant/issues/10032 +export function getStringLength(str: string) { + return [...str].length; +} + +// cut string with emoji +export function cutString(str: string, maxlength: number) { + return [...str].slice(0, maxlength).join(''); +} From 2b1df7d443bd3952c63deb6c829c364b3db4156c Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 12 Dec 2021 21:04:08 +0800 Subject: [PATCH 03/94] fix: tree shaking is broken (#10034) --- packages/vant/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vant/package.json b/packages/vant/package.json index 490010481..6e7211840 100644 --- a/packages/vant/package.json +++ b/packages/vant/package.json @@ -3,7 +3,7 @@ "version": "3.3.6", "description": "Mobile UI Components built on Vue", "main": "lib/vant.cjs.js", - "module": "lib/vant.es.js", + "module": "es/index.js", "style": "lib/index.css", "typings": "lib/index.d.ts", "unpkg": "lib/vant.min.js", @@ -14,11 +14,11 @@ "import": "./lib/ssr.mjs", "require": "./lib/ssr.js" }, - "import": "./lib/vant.es.js", + "import": "./es/index.js", "require": "./lib/vant.cjs.js", "types": "./lib/index.d.ts" }, - "./es": "./lib/vant.es.js", + "./es": "./es/index.js", "./lib": "./lib/vant.cjs.js", "./es/": "./es/", "./lib/": "./lib/", From 217326e3a0addfb8a5a79091a6af8e0f2b90bbbe Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Sun, 12 Dec 2021 21:16:49 +0800 Subject: [PATCH 04/94] release: 3.3.7 --- packages/vant/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vant/package.json b/packages/vant/package.json index 6e7211840..3be915795 100644 --- a/packages/vant/package.json +++ b/packages/vant/package.json @@ -1,6 +1,6 @@ { "name": "vant", - "version": "3.3.6", + "version": "3.3.7", "description": "Mobile UI Components built on Vue", "main": "lib/vant.cjs.js", "module": "es/index.js", From f240a32e8e2bcffbfc601599278f4e46a3f8f667 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Sun, 12 Dec 2021 21:19:03 +0800 Subject: [PATCH 05/94] docs(changelog): 3.3.7 --- packages/vant/docs/markdown/changelog.en-US.md | 15 +++++++++++++++ packages/vant/docs/markdown/changelog.zh-CN.md | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/vant/docs/markdown/changelog.en-US.md b/packages/vant/docs/markdown/changelog.en-US.md index 9e498fa91..f471c9b89 100644 --- a/packages/vant/docs/markdown/changelog.en-US.md +++ b/packages/vant/docs/markdown/changelog.en-US.md @@ -16,6 +16,21 @@ Vant follows [Semantic Versioning 2.0.0](https://semver.org/lang/zh-CN/). ## Details +### [v3.3.7](https://github.com/compare/v3.3.6...v3.3.7) + +`2021-12-12` + +**Feature** + +- Badge: add position prop [#10024](https://github.com/issues/10024) + +**Bug Fixes** + +- DatetimePicker: should update value after calling picker methods [#10029](https://github.com/issues/10029) +- Field: fix the length of emoji [#10033](https://github.com/issues/10033) +- Pagination: change event not work [#10018](https://github.com/issues/10018) +- fix tree shaking is broken [#10034](https://github.com/issues/10034) + ### [v3.3.6](https://github.com/compare/v3.3.5...v3.3.6) `2021-12-05` diff --git a/packages/vant/docs/markdown/changelog.zh-CN.md b/packages/vant/docs/markdown/changelog.zh-CN.md index fb66a7644..c7eb9089c 100644 --- a/packages/vant/docs/markdown/changelog.zh-CN.md +++ b/packages/vant/docs/markdown/changelog.zh-CN.md @@ -16,6 +16,21 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。 ## 更新内容 +### [v3.3.7](https://github.com/compare/v3.3.6...v3.3.7) + +`2021-12-12` + +**Feature** + +- Badge: 新增 position 属性 [#10024](https://github.com/issues/10024) + +**Bug Fixes** + +- DatetimePicker: 修复调用 Picker 实例方法后日期未正确更新的问题 [#10029](https://github.com/issues/10029) +- Field: 修复输入内容包含 emoji 时,长度计算错误的问题 [#10033](https://github.com/issues/10033) +- Pagination: 修复 change 事件不触发的问题 [#10018](https://github.com/issues/10018) +- 修复 tree shaking 不生效的问题 [#10034](https://github.com/issues/10034) + ### [v3.3.6](https://github.com/compare/v3.3.5...v3.3.6) `2021-12-05` From 03fa2d43893240bd286949e02a8198e1595b2ad2 Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 14 Dec 2021 09:54:27 +0800 Subject: [PATCH 06/94] fix(areaData): fix incorrect area code (#10041) --- packages/vant-area-data/package.json | 2 +- packages/vant-area-data/src/index.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vant-area-data/package.json b/packages/vant-area-data/package.json index 54d7a255a..6881d2ed7 100644 --- a/packages/vant-area-data/package.json +++ b/packages/vant-area-data/package.json @@ -1,6 +1,6 @@ { "name": "@vant/area-data", - "version": "1.1.3", + "version": "1.1.5", "description": "Vant 省市区数据", "main": "./lib/index.js", "typings": "./lib/index.d.ts", diff --git a/packages/vant-area-data/src/index.ts b/packages/vant-area-data/src/index.ts index c332cb7ac..863a21e5b 100644 --- a/packages/vant-area-data/src/index.ts +++ b/packages/vant-area-data/src/index.ts @@ -1290,8 +1290,8 @@ export const areaList = { 330110: '余杭区', 330111: '富阳区', 330112: '临安区', - 330113: '钱塘区', - 330114: '临平区', + 330113: '临平区', + 330114: '钱塘区', 330122: '桐庐县', 330127: '淳安县', 330182: '建德市', From 0cdc99cdcac4c68a0da96f1907998b3b6aa5d607 Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 14 Dec 2021 10:32:06 +0800 Subject: [PATCH 07/94] types(Field): type prop allow all native types (#10042) --- packages/vant/src/field/README.md | 16 ++++++++-------- packages/vant/src/field/README.zh-CN.md | 16 ++++++++-------- packages/vant/src/field/types.ts | 19 ++++++++++++++++++- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/vant/src/field/README.md b/packages/vant/src/field/README.md index b9c014bdf..3aa306c53 100644 --- a/packages/vant/src/field/README.md +++ b/packages/vant/src/field/README.md @@ -251,7 +251,7 @@ Use `input-align` prop to align the input value. | label | Left side label | _string_ | - | | name | As the identifier when submitting the form | _string_ | - | | id `v3.2.2` | Input id, the for attribute of the label also will be set | _string_ | `van-field-n-input` | -| type | Input type, can be set to `tel` `digit`
`number` `textarea` `password` | _string_ | `text` | +| type | Input type, support all [native types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types) and `digit` type | _FieldType_ | `text` | | size | Size,can be set to `large` | _string_ | - | | maxlength | Max length of value | _number \| string_ | - | | placeholder | Input placeholder | _string_ | - | @@ -263,26 +263,26 @@ Use `input-align` prop to align the input value. | center | Whether to center content vertically | _boolean_ | `true` | | clearable | Whether to be clearable | _boolean_ | `false` | | clear-icon `v3.0.12` | Clear icon name | _string_ | `clear` | -| clear-trigger | When to display the clear icon, `always` means to display the icon when value is not empty, `focus` means to display the icon when input is focused | _string_ | `focus` | +| clear-trigger | When to display the clear icon, `always` means to display the icon when value is not empty, `focus` means to display the icon when input is focused | _FieldClearTrigger_ | `focus` | | clickable | Whether to show click feedback when clicked | _boolean_ | `false` | | is-link | Whether to show link icon | _boolean_ | `false` | | autofocus | Whether to auto focus, unsupported in iOS | _boolean_ | `false` | | show-word-limit | Whether to show word limit, need to set the `maxlength` prop | _boolean_ | `false` | | error | Whether to mark the input content in red | _boolean_ | `false` | | error-message | Error message | _string_ | - | -| error-message-align | Error message align, can be set to `center` `right` | _string_ | `left` | +| error-message-align | Error message align, can be set to `center` `right` | _FieldTextAlign_ | `left` | | formatter | Input value formatter | _(val: string) => string_ | - | -| format-trigger | When to format value,can be set to `onBlur` | _string_ | `onChange` | +| format-trigger | When to format value,can be set to `onBlur` | _FieldFormatTrigger_ | `onChange` | | arrow-direction | Can be set to `left` `up` `down` | _string_ | `right` | | label-class | Label className | _string \| Array \| object_ | - | | label-width | Label width | _number \| string_ | `6.2em` | -| label-align | Label align, can be set to `center` `right` | _string_ | `left` | -| input-align | Input align, can be set to `center` `right` | _string_ | `left` | -| autosize | Textarea auto resize,can accept an object,
e.g. { maxHeight: 100, minHeight: 50 } | _boolean \| object_ | `false` | +| label-align | Label align, can be set to `center` `right` | _FieldTextAlign_ | `left` | +| input-align | Input align, can be set to `center` `right` | _FieldTextAlign_ | `left` | +| autosize | Textarea auto resize,can accept an object,
e.g. { maxHeight: 100, minHeight: 50 } | _boolean \| FieldAutosizeConfig_ | `false` | | left-icon | Left side icon name | _string_ | - | | right-icon | Right side icon name | _string_ | - | | icon-prefix | Icon className prefix | _string_ | `van-icon` | -| rules | Form validation rules | _Rule[]_ | - | +| rules | Form validation rules | _FieldRule[]_ | - | | autocomplete `v3.0.3` | [autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) attribute of native input element | _string_ | - | ### Events diff --git a/packages/vant/src/field/README.zh-CN.md b/packages/vant/src/field/README.zh-CN.md index 16f5a4966..814a54ff6 100644 --- a/packages/vant/src/field/README.zh-CN.md +++ b/packages/vant/src/field/README.zh-CN.md @@ -270,7 +270,7 @@ export default { | label | 输入框左侧文本 | _string_ | - | | name | 名称,作为提交表单时的标识符 | _string_ | - | | id `v3.2.2` | 输入框 id,同时会设置 label 的 for 属性 | _string_ | `van-field-n-input` | -| type | 输入框类型, 可选值为 `tel` `digit`
`number` `textarea` `password` 等 | _string_ | `text` | +| type | 输入框类型, 支持原生 input 标签的所有 [type 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input#%3Cinput%3E_types),额外支持了 `digit` 类型 | _FieldType_ | `text` | | size | 大小,可选值为 `large` | _string_ | - | | maxlength | 输入的最大字符数 | _number \| string_ | - | | placeholder | 输入框占位提示文字 | _string_ | - | @@ -282,26 +282,26 @@ export default { | center | 是否使内容垂直居中 | _boolean_ | `false` | | clearable | 是否启用清除图标,点击清除图标后会清空输入框 | _boolean_ | `false` | | clear-icon `v3.0.12` | 清除[图标名称](#/zh-CN/icon)或图片链接 | _string_ | `clear` | -| clear-trigger | 显示清除图标的时机,`always` 表示输入框不为空时展示,
`focus` 表示输入框聚焦且不为空时展示 | _string_ | `focus` | +| clear-trigger | 显示清除图标的时机,`always` 表示输入框不为空时展示,
`focus` 表示输入框聚焦且不为空时展示 | _FieldClearTrigger_ | `focus` | | clickable | 是否开启点击反馈 | _boolean_ | `false` | | is-link | 是否展示右侧箭头并开启点击反馈 | _boolean_ | `false` | | autofocus | 是否自动聚焦,iOS 系统不支持该属性 | _boolean_ | `false` | | show-word-limit | 是否显示字数统计,需要设置 `maxlength` 属性 | _boolean_ | `false` | | error | 是否将输入内容标红 | _boolean_ | `false` | | error-message | 底部错误提示文案,为空时不展示 | _string_ | - | -| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | _string_ | `left` | +| error-message-align | 错误提示文案对齐方式,可选值为 `center` `right` | _FieldTextAlign_ | `left` | | formatter | 输入内容格式化函数 | _(val: string) => string_ | - | -| format-trigger | 格式化函数触发的时机,可选值为 `onBlur` | _string_ | `onChange` | +| format-trigger | 格式化函数触发的时机,可选值为 `onBlur` | _FieldFormatTrigger_ | `onChange` | | arrow-direction | 箭头方向,可选值为 `left` `up` `down` | _string_ | `right` | | label-class | 左侧文本额外类名 | _string \| Array \| object_ | - | | label-width | 左侧文本宽度,默认单位为 `px` | _number \| string_ | `6.2em` | -| label-align | 左侧文本对齐方式,可选值为 `center` `right` | _string_ | `left` | -| input-align | 输入框对齐方式,可选值为 `center` `right` | _string_ | `left` | -| autosize | 是否自适应内容高度,只对 textarea 有效,
可传入对象,如 { maxHeight: 100, minHeight: 50 },
单位为`px` | _boolean \| object_ | `false` | +| label-align | 左侧文本对齐方式,可选值为 `center` `right` | _FieldTextAlign_ | `left` | +| input-align | 输入框对齐方式,可选值为 `center` `right` | _FieldTextAlign_ | `left` | +| autosize | 是否自适应内容高度,只对 textarea 有效,
可传入对象,如 { maxHeight: 100, minHeight: 50 },
单位为`px` | _boolean \| FieldAutosizeConfig_ | `false` | | left-icon | 左侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - | | right-icon | 右侧[图标名称](#/zh-CN/icon)或图片链接 | _string_ | - | | icon-prefix | 图标类名前缀,等同于 Icon 组件的 [class-prefix 属性](#/zh-CN/icon#props) | _string_ | `van-icon` | -| rules | 表单校验规则,详见 [Form 组件](#/zh-CN/form#rule-shu-ju-jie-gou) | _Rule[]_ | - | +| rules | 表单校验规则,详见 [Form 组件](#/zh-CN/form#rule-shu-ju-jie-gou) | _FieldRule[]_ | - | | autocomplete `v3.0.3` | input 标签原生的[自动完成属性](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) | _string_ | - | ### Events diff --git a/packages/vant/src/field/types.ts b/packages/vant/src/field/types.ts index 95cd23e0b..730de9b8f 100644 --- a/packages/vant/src/field/types.ts +++ b/packages/vant/src/field/types.ts @@ -4,12 +4,29 @@ import type { FieldProps } from './Field'; export type FieldType = | 'tel' + | 'url' + | 'date' + | 'file' | 'text' + | 'time' + | 'week' + | 'color' | 'digit' + | 'email' + | 'image' + | 'month' + | 'radio' + | 'range' + | 'reset' + | 'button' + | 'hidden' | 'number' | 'search' + | 'submit' + | 'checkbox' | 'password' - | 'textarea'; + | 'textarea' + | 'datetime-local'; export type FieldTextAlign = 'left' | 'center' | 'right'; From db5b7918aff28f0b0358978c3711f77b3dd85ca4 Mon Sep 17 00:00:00 2001 From: neverland Date: Wed, 15 Dec 2021 11:30:13 +0800 Subject: [PATCH 08/94] feat(ImagePreview): add overlayClass option (#10044) * feat(ImagePreview): add overlayClass option * chore: update --- packages/vant/src/image-preview/ImagePreview.tsx | 3 ++- packages/vant/src/image-preview/README.md | 4 +++- packages/vant/src/image-preview/README.zh-CN.md | 4 +++- packages/vant/src/image-preview/function-call.tsx | 1 + packages/vant/src/image-preview/types.ts | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/vant/src/image-preview/ImagePreview.tsx b/packages/vant/src/image-preview/ImagePreview.tsx index 6a38b505c..7257a8b37 100644 --- a/packages/vant/src/image-preview/ImagePreview.tsx +++ b/packages/vant/src/image-preview/ImagePreview.tsx @@ -61,6 +61,7 @@ const imagePreviewProps = { closeIcon: makeStringProp('clear'), transition: String, beforeClose: Function as PropType, + overlayClass: unknownProp, overlayStyle: Object as PropType, swipeDuration: makeNumericProp(300), startPosition: makeNumericProp(0), @@ -215,7 +216,7 @@ export default defineComponent({ return () => ( `bottom-left` `bottom-right` | _string_ | `top-right` | | transition `v3.0.8` | 动画类名,等价于 [transition](https://v3.cn.vuejs.org/api/built-in-components.html#transition) 的 `name` 属性 | _string_ | `van-fade` | -| overlay-style `v3.0.8` | 自定义遮罩层样式 | _object_ | - | +| overlayClass `v3.2.8` | 自定义遮罩层类名 | _string \| Array \| object_ | - | +| overlayStyle `v3.0.8` | 自定义遮罩层样式 | _object_ | - | | teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://v3.cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | - | ### Props @@ -213,6 +214,7 @@ export default { | close-icon | 关闭图标名称或图片链接 | _string_ | `clear` | | close-icon-position | 关闭图标位置,可选值为 `top-left`
`bottom-left` `bottom-right` | _string_ | `top-right` | | transition `v3.0.8` | 动画类名,等价于 [transition](https://v3.cn.vuejs.org/api/built-in-components.html#transition) 的 `name` 属性 | _string_ | `van-fade` | +| overlay-class `v3.2.8` | 自定义遮罩层类名 | _string \| Array \| object_ | - | | overlay-style `v3.0.8` | 自定义遮罩层样式 | _object_ | - | | teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://v3.cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | - | diff --git a/packages/vant/src/image-preview/function-call.tsx b/packages/vant/src/image-preview/function-call.tsx index 04ebe8e06..b33fb1d86 100644 --- a/packages/vant/src/image-preview/function-call.tsx +++ b/packages/vant/src/image-preview/function-call.tsx @@ -22,6 +22,7 @@ const defaultConfig: ImagePreviewOptions = { transition: undefined, beforeClose: undefined, overlayStyle: undefined, + overlayClass: undefined, startPosition: 0, swipeDuration: 300, showIndicators: false, diff --git a/packages/vant/src/image-preview/types.ts b/packages/vant/src/image-preview/types.ts index eb4c574f1..5f196bdc8 100644 --- a/packages/vant/src/image-preview/types.ts +++ b/packages/vant/src/image-preview/types.ts @@ -21,6 +21,7 @@ export type ImagePreviewOptions = { transition?: string; beforeClose?: Interceptor; overlayStyle?: CSSProperties; + overlayClass?: unknown; swipeDuration?: number; startPosition?: number; showIndicators?: boolean; From e9f84b68aa4bb91534ff3a0c5e5e7230f1651e32 Mon Sep 17 00:00:00 2001 From: windole <1322670109@qq.com> Date: Thu, 16 Dec 2021 11:03:15 +0800 Subject: [PATCH 09/94] fix(Step): fix inactive title style (#10049) Co-authored-by: pengjin --- packages/vant/src/step/Step.tsx | 2 +- .../vant/src/steps/test/__snapshots__/index.spec.tsx.snap | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vant/src/step/Step.tsx b/packages/vant/src/step/Step.tsx index 7725fb945..5e54a173c 100644 --- a/packages/vant/src/step/Step.tsx +++ b/packages/vant/src/step/Step.tsx @@ -48,7 +48,7 @@ export default defineComponent({ if (isActive()) { return { color: parentProps.activeColor }; } - if (!getStatus()) { + if (getStatus() === 'waiting') { return { color: parentProps.inactiveColor }; } }); diff --git a/packages/vant/src/steps/test/__snapshots__/index.spec.tsx.snap b/packages/vant/src/steps/test/__snapshots__/index.spec.tsx.snap index e91fb7c4e..ee2077539 100644 --- a/packages/vant/src/steps/test/__snapshots__/index.spec.tsx.snap +++ b/packages/vant/src/steps/test/__snapshots__/index.spec.tsx.snap @@ -31,7 +31,9 @@ exports[`should change inactive color when using inactive-color prop 1`] = `
-
+
B
From 7b82ce6573972840e21ab281964a48362a513d6d Mon Sep 17 00:00:00 2001 From: neverland Date: Thu, 16 Dec 2021 11:06:19 +0800 Subject: [PATCH 10/94] test: prefer using toHaveLength (#10050) --- packages/vant/src/action-sheet/test/index.spec.ts | 6 +++--- packages/vant/src/area/test/index.spec.js | 4 ++-- packages/vant/src/button/test/index.spec.ts | 2 +- packages/vant/src/card/test/index.spec.ts | 2 +- packages/vant/src/contact-card/test/index.spec.ts | 2 +- packages/vant/src/contact-list/test/index.spec.ts | 6 +++--- packages/vant/src/form/test/methods.spec.tsx | 8 ++++---- packages/vant/src/image/test/index.spec.ts | 4 ++-- packages/vant/src/number-keyboard/test/index.spec.ts | 2 +- packages/vant/src/password-input/test/index.spec.ts | 2 +- packages/vant/src/picker/test/index.spec.tsx | 8 ++++---- packages/vant/src/popover/test/index.spec.tsx | 2 +- packages/vant/src/popup/test/index.spec.js | 4 ++-- packages/vant/src/rate/test/index.spec.ts | 8 ++++---- packages/vant/src/search/test/index.spec.ts | 4 ++-- packages/vant/src/slider/test/index.spec.ts | 4 ++-- packages/vant/src/submit-bar/test/index.spec.ts | 2 +- packages/vant/src/swipe-cell/test/index.spec.js | 4 ++-- packages/vant/src/switch/test/index.spec.ts | 8 ++++---- packages/vant/src/tab/test/index.spec.tsx | 2 +- packages/vant/src/tag/test/index.spec.ts | 2 +- 21 files changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/vant/src/action-sheet/test/index.spec.ts b/packages/vant/src/action-sheet/test/index.spec.ts index 469de0b92..355084856 100644 --- a/packages/vant/src/action-sheet/test/index.spec.ts +++ b/packages/vant/src/action-sheet/test/index.spec.ts @@ -13,7 +13,7 @@ test('should emit select event after clicking option', async () => { wrapper.find('.van-action-sheet__item').trigger('click'); await nextTick(); - expect(wrapper.emitted('select')!.length).toEqual(1); + expect(wrapper.emitted('select')).toHaveLength(1); expect(wrapper.emitted('select')![0]).toEqual([ { name: 'Option', @@ -71,7 +71,7 @@ test('should emit cancel event after clicking cancel button', () => { }); wrapper.find('.van-action-sheet__cancel').trigger('click'); - expect(wrapper.emitted('cancel')!.length).toEqual(1); + expect(wrapper.emitted('cancel')).toHaveLength(1); }); test('should render subname correctly', () => { @@ -225,7 +225,7 @@ test('should close after clicking option if close-on-click-action prop is true', const option = wrapper.find('.van-action-sheet__item'); option.trigger('click'); - expect(wrapper.emitted('update:show')!.length).toEqual(1); + expect(wrapper.emitted('update:show')).toHaveLength(1); expect(wrapper.emitted('update:show')![0]).toEqual([false]); }); diff --git a/packages/vant/src/area/test/index.spec.js b/packages/vant/src/area/test/index.spec.js index 44b510316..55ed0cc27 100644 --- a/packages/vant/src/area/test/index.spec.js +++ b/packages/vant/src/area/test/index.spec.js @@ -116,10 +116,10 @@ test('should render two columns when columns-num prop is two', async () => { }, }); - expect(wrapper.findAll('.van-picker-column').length).toEqual(3); + expect(wrapper.findAll('.van-picker-column')).toHaveLength(3); await wrapper.setProps({ columnsNum: 2 }); - expect(wrapper.findAll('.van-picker-column').length).toEqual(2); + expect(wrapper.findAll('.van-picker-column')).toHaveLength(2); expect(wrapper.html()).toMatchSnapshot(); }); diff --git a/packages/vant/src/button/test/index.spec.ts b/packages/vant/src/button/test/index.spec.ts index e75e26aec..82493a380 100644 --- a/packages/vant/src/button/test/index.spec.ts +++ b/packages/vant/src/button/test/index.spec.ts @@ -5,7 +5,7 @@ test('should emit click event', () => { const wrapper = mount(Button); wrapper.trigger('click'); - expect(wrapper.emitted('click')!.length).toEqual(1); + expect(wrapper.emitted('click')).toHaveLength(1); }); test('should not emit click event when disabled', () => { diff --git a/packages/vant/src/card/test/index.spec.ts b/packages/vant/src/card/test/index.spec.ts index 31d55d844..9a56ff6f3 100644 --- a/packages/vant/src/card/test/index.spec.ts +++ b/packages/vant/src/card/test/index.spec.ts @@ -20,7 +20,7 @@ test('should emit click-thumb event after clicking thumb', () => { }); wrapper.find('.van-card__thumb').trigger('click'); - expect(wrapper.emitted('click-thumb')!.length).toEqual(1); + expect(wrapper.emitted('click-thumb')!).toHaveLength(1); }); test('should render price and num slot correctly', () => { diff --git a/packages/vant/src/contact-card/test/index.spec.ts b/packages/vant/src/contact-card/test/index.spec.ts index adfb153bd..e78e16564 100644 --- a/packages/vant/src/contact-card/test/index.spec.ts +++ b/packages/vant/src/contact-card/test/index.spec.ts @@ -4,7 +4,7 @@ import { mount } from '../../../test'; test('should emit click event when clicked', () => { const wrapper = mount(ContactCard); wrapper.trigger('click'); - expect(wrapper.emitted('click')!.length).toEqual(1); + expect(wrapper.emitted('click')).toHaveLength(1); }); test('should not emit click event when editable is false and clicked ', () => { diff --git a/packages/vant/src/contact-list/test/index.spec.ts b/packages/vant/src/contact-list/test/index.spec.ts index 4ad67d4e9..a9e3cfb6b 100644 --- a/packages/vant/src/contact-list/test/index.spec.ts +++ b/packages/vant/src/contact-list/test/index.spec.ts @@ -20,7 +20,7 @@ test('should render ContactList correctly', () => { test('should emit add event when add button is clicked', () => { const wrapper = mount(ContactList); wrapper.find('.van-contact-list__add').trigger('click'); - expect(wrapper.emitted('add')!.length).toEqual(1); + expect(wrapper.emitted('add')).toHaveLength(1); }); test('should emit select event when radio is clicked', () => { @@ -32,7 +32,7 @@ test('should emit select event when radio is clicked', () => { wrapper.find('.van-radio__icon').trigger('click'); - expect(wrapper.emitted('select')!.length).toEqual(1); + expect(wrapper.emitted('select')).toHaveLength(1); expect(wrapper.emitted('select')![0]).toEqual([contactInfo, 0]); }); @@ -45,6 +45,6 @@ test('should emit edit event when edit icon is clicked', () => { wrapper.find('.van-contact-list__edit').trigger('click'); - expect(wrapper.emitted('edit')!.length).toEqual(1); + expect(wrapper.emitted('edit')).toHaveLength(1); expect(wrapper.emitted('edit')![0]).toEqual([contactInfo, 0]); }); diff --git a/packages/vant/src/form/test/methods.spec.tsx b/packages/vant/src/form/test/methods.spec.tsx index 7066bab86..5a3b4d9ec 100644 --- a/packages/vant/src/form/test/methods.spec.tsx +++ b/packages/vant/src/form/test/methods.spec.tsx @@ -94,7 +94,7 @@ test('resetValidation method - reset all fields', async () => { formRef.value?.resetValidation(); await later(); const errors = form.findAll('.van-field__error-message'); - expect(errors.length).toEqual(0); + expect(errors).toHaveLength(0); } }); @@ -107,7 +107,7 @@ test('resetValidation method - reset two fields', async () => { formRef.value?.resetValidation(['A', 'B']); await later(); const errors = form.findAll('.van-field__error-message'); - expect(errors.length).toEqual(0); + expect(errors).toHaveLength(0); } }); @@ -119,11 +119,11 @@ test('resetValidation method - reset one field', async () => { } catch (err) { formRef.value?.resetValidation('A'); await later(); - expect(form.findAll('.van-field__error-message').length).toEqual(1); + expect(form.findAll('.van-field__error-message')).toHaveLength(1); formRef.value?.resetValidation('B'); await later(); - expect(form.findAll('.van-field__error-message').length).toEqual(0); + expect(form.findAll('.van-field__error-message')).toHaveLength(0); } }); diff --git a/packages/vant/src/image/test/index.spec.ts b/packages/vant/src/image/test/index.spec.ts index 96ceacf0d..18aa006f6 100644 --- a/packages/vant/src/image/test/index.spec.ts +++ b/packages/vant/src/image/test/index.spec.ts @@ -190,7 +190,7 @@ test('should render default slot correctly', () => { // setTimeout(() => { // hanlder({ el: null }); // hanlder({ el: wrapper.find('img').element }); -// expect(wrapper.emitted('load').length).toEqual(1); +// expect(wrapper.emitted('load')).toHaveLength(1); // expect(wrapper.html()).toMatchSnapshot(); // wrapper.unmount(); // }); @@ -217,7 +217,7 @@ test('should render default slot correctly', () => { // setTimeout(() => { // hanlder({ el: null }); // hanlder({ el: wrapper.find('img').element }); -// expect(wrapper.emitted('error').length).toEqual(1); +// expect(wrapper.emitted('error')).toHaveLength(1); // expect(wrapper.html()).toMatchSnapshot(); // wrapper.unmount(); // }); diff --git a/packages/vant/src/number-keyboard/test/index.spec.ts b/packages/vant/src/number-keyboard/test/index.spec.ts index 443fc3b6f..128496256 100644 --- a/packages/vant/src/number-keyboard/test/index.spec.ts +++ b/packages/vant/src/number-keyboard/test/index.spec.ts @@ -187,7 +187,7 @@ test('should limit max length of modelValue when using maxlength prop', async () clickKey(keys[1]); expect(onInput).toHaveBeenCalledTimes(1); - expect(wrapper.emitted('update:modelValue')!.length).toEqual(1); + expect(wrapper.emitted('update:modelValue')).toHaveLength(1); }); test('should not render delete key when show-delete-key prop is false', async () => { diff --git a/packages/vant/src/password-input/test/index.spec.ts b/packages/vant/src/password-input/test/index.spec.ts index 1fbcfea3d..ba637f5ab 100644 --- a/packages/vant/src/password-input/test/index.spec.ts +++ b/packages/vant/src/password-input/test/index.spec.ts @@ -4,7 +4,7 @@ import { PasswordInput } from '..'; test('should emit focus event when security is touched', () => { const wrapper = mount(PasswordInput); wrapper.find('.van-password-input__security').trigger('touchstart'); - expect(wrapper.emitted('focus')!.length).toEqual(1); + expect(wrapper.emitted('focus')).toHaveLength(1); }); test('should render error info correctly', () => { diff --git a/packages/vant/src/picker/test/index.spec.tsx b/packages/vant/src/picker/test/index.spec.tsx index 593a6b55a..b05018513 100644 --- a/packages/vant/src/picker/test/index.spec.tsx +++ b/packages/vant/src/picker/test/index.spec.tsx @@ -58,7 +58,7 @@ test('set picker values', () => { const vm = wrapper.vm as Record; expect(vm.getColumnValues(-1)).toEqual(undefined); - expect(vm.getColumnValues(1).length).toEqual(6); + expect(vm.getColumnValues(1)).toHaveLength(6); expect(vm.getColumnValue(1)).toEqual('1990'); vm.setColumnValue(0, 'normal'); @@ -71,11 +71,11 @@ test('set picker values', () => { expect(vm.getColumnValue(1)).toEqual('1991'); vm.setColumnValues(0, ['vip', 'normal', 'other']); - expect(vm.getColumnValues(0).length).toEqual(3); - expect(vm.getValues().length).toEqual(2); + expect(vm.getColumnValues(0)).toHaveLength(3); + expect(vm.getValues()).toHaveLength(2); vm.setColumnValues(-1, []); - expect(vm.getValues().length).toEqual(2); + expect(vm.getValues()).toHaveLength(2); vm.setValues(['vip', '1992']); expect(vm.getColumnIndex(1)).toEqual(2); diff --git a/packages/vant/src/popover/test/index.spec.tsx b/packages/vant/src/popover/test/index.spec.tsx index 2a41f1b54..0950dc69e 100644 --- a/packages/vant/src/popover/test/index.spec.tsx +++ b/packages/vant/src/popover/test/index.spec.tsx @@ -67,7 +67,7 @@ test('should close popover when clicking the action', async () => { await wrapper.setProps({ closeOnClickAction: false }); await wrapper.find('.van-popover__action').trigger('click'); - expect(wrapper.emitted('update:show')!.length).toEqual(1); + expect(wrapper.emitted('update:show')).toHaveLength(1); }); test('should allow to custom the className of action', () => { diff --git a/packages/vant/src/popup/test/index.spec.js b/packages/vant/src/popup/test/index.spec.js index 955bbc930..13047ded1 100644 --- a/packages/vant/src/popup/test/index.spec.js +++ b/packages/vant/src/popup/test/index.spec.js @@ -101,7 +101,7 @@ test('should emit click-overlay event when overlay is clicked', async () => { }); const overlay = wrapper.find('.van-overlay'); overlay.trigger('click'); - expect(wrapper.emitted('click-overlay').length).toEqual(1); + expect(wrapper.emitted('click-overlay')).toHaveLength(1); }); test('should emit open event when show prop is set to true', async () => { @@ -175,7 +175,7 @@ test('should emit click-close-icon event when close icon is clicked', () => { }); wrapper.find('.van-popup__close-icon').trigger('click'); - expect(wrapper.emitted('click-close-icon').length).toEqual(1); + expect(wrapper.emitted('click-close-icon')).toHaveLength(1); }); test('should render correct close icon when using close-icon prop', () => { diff --git a/packages/vant/src/rate/test/index.spec.ts b/packages/vant/src/rate/test/index.spec.ts index a1ecabc08..6a89bd36d 100644 --- a/packages/vant/src/rate/test/index.spec.ts +++ b/packages/vant/src/rate/test/index.spec.ts @@ -18,15 +18,15 @@ test('should emit change and update:modelValue event when rate icon is clicked', const item4 = wrapper.findAll('.van-rate__icon')[3]; item4.trigger('click'); - expect(wrapper.emitted('change')!.length).toEqual(1); + expect(wrapper.emitted('change')).toHaveLength(1); expect(wrapper.emitted('change')![0]).toEqual([4]); - expect(wrapper.emitted('update:modelValue')!.length).toEqual(1); + expect(wrapper.emitted('update:modelValue')).toHaveLength(1); expect(wrapper.emitted('update:modelValue')![0]).toEqual([4]); await wrapper.setProps({ modelValue: 4 }); item4.trigger('click'); - expect(wrapper.emitted('change')!.length).toEqual(1); - expect(wrapper.emitted('update:modelValue')!.length).toEqual(1); + expect(wrapper.emitted('change')).toHaveLength(1); + expect(wrapper.emitted('update:modelValue')).toHaveLength(1); }); test('should not emit change and update:modelValue event when rate is not changed', () => { diff --git a/packages/vant/src/search/test/index.spec.ts b/packages/vant/src/search/test/index.spec.ts index 825a33695..f8c5d9474 100644 --- a/packages/vant/src/search/test/index.spec.ts +++ b/packages/vant/src/search/test/index.spec.ts @@ -29,7 +29,7 @@ test('should emit cancel event when cancel button click is clicked', () => { const cancel = wrapper.find('.van-search__action'); cancel.trigger('click'); - expect(wrapper.emitted('cancel')!.length).toEqual(1); + expect(wrapper.emitted('cancel')).toHaveLength(1); expect(wrapper.emitted('update:modelValue')![0]).toEqual(['']); }); @@ -57,7 +57,7 @@ test('should emit search event when enter key is pressed', () => { input.trigger('keypress.enter'); input.trigger('keypress.a'); - expect(wrapper.emitted('search')!.length).toEqual(1); + expect(wrapper.emitted('search')).toHaveLength(1); }); test('should render label slot correctly', () => { diff --git a/packages/vant/src/slider/test/index.spec.ts b/packages/vant/src/slider/test/index.spec.ts index 29d5d7eb1..a51a36ed7 100644 --- a/packages/vant/src/slider/test/index.spec.ts +++ b/packages/vant/src/slider/test/index.spec.ts @@ -191,13 +191,13 @@ test('should not emit change event when value not changed', async () => { const button = wrapper.find('.van-slider__button'); trigger(button, 'touchstart'); trigger(wrapper, 'click', 100, 0); - expect(wrapper.emitted('change')!.length).toEqual(1); + expect(wrapper.emitted('change')).toHaveLength(1); await wrapper.setProps({ modelValue: 100 }); trigger(button, 'touchstart'); trigger(wrapper, 'click', 100, 0); - expect(wrapper.emitted('change')!.length).toEqual(1); + expect(wrapper.emitted('change')).toHaveLength(1); }); // https://github.com/youzan/vant/issues/8889 diff --git a/packages/vant/src/submit-bar/test/index.spec.ts b/packages/vant/src/submit-bar/test/index.spec.ts index 24ff45b74..9d3742a71 100644 --- a/packages/vant/src/submit-bar/test/index.spec.ts +++ b/packages/vant/src/submit-bar/test/index.spec.ts @@ -5,7 +5,7 @@ test('should emit submit event when submit button is clicked', () => { const wrapper = mount(SubmitBar); const button = wrapper.find('.van-submit-bar__button'); button.trigger('click'); - expect(wrapper.emitted('submit')!.length).toEqual(1); + expect(wrapper.emitted('submit')).toHaveLength(1); }); test('should render disabled submit button correctly', () => { diff --git a/packages/vant/src/swipe-cell/test/index.spec.js b/packages/vant/src/swipe-cell/test/index.spec.js index 034dec6aa..4e6c77889 100644 --- a/packages/vant/src/swipe-cell/test/index.spec.js +++ b/packages/vant/src/swipe-cell/test/index.spec.js @@ -188,8 +188,8 @@ test('should not trigger close event again if already closed', () => { wrapper.vm.open('left'); wrapper.vm.close(); - expect(wrapper.emitted('close').length).toEqual(1); + expect(wrapper.emitted('close')).toHaveLength(1); wrapper.vm.close(); - expect(wrapper.emitted('close').length).toEqual(1); + expect(wrapper.emitted('close')).toHaveLength(1); }); diff --git a/packages/vant/src/switch/test/index.spec.ts b/packages/vant/src/switch/test/index.spec.ts index 17d20bfd9..df3e97e92 100644 --- a/packages/vant/src/switch/test/index.spec.ts +++ b/packages/vant/src/switch/test/index.spec.ts @@ -5,12 +5,12 @@ test('should emit update:modelValue event when click the switch button', async ( const wrapper = mount(Switch); wrapper.trigger('click'); - expect(wrapper.emitted('update:modelValue')!.length).toEqual(1); + expect(wrapper.emitted('update:modelValue')).toHaveLength(1); expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]); await wrapper.setProps({ modelValue: true }); wrapper.trigger('click'); - expect(wrapper.emitted('update:modelValue')!.length).toEqual(2); + expect(wrapper.emitted('update:modelValue')).toHaveLength(2); expect(wrapper.emitted('update:modelValue')![1]).toEqual([false]); }); @@ -18,12 +18,12 @@ test('should emit change event when click the switch button', async () => { const wrapper = mount(Switch); wrapper.trigger('click'); - expect(wrapper.emitted('change')!.length).toEqual(1); + expect(wrapper.emitted('change')).toHaveLength(1); expect(wrapper.emitted('change')![0]).toEqual([true]); await wrapper.setProps({ modelValue: true }); wrapper.trigger('click'); - expect(wrapper.emitted('change')!.length).toEqual(2); + expect(wrapper.emitted('change')).toHaveLength(2); expect(wrapper.emitted('change')![1]).toEqual([false]); }); diff --git a/packages/vant/src/tab/test/index.spec.tsx b/packages/vant/src/tab/test/index.spec.tsx index b6ace3fd9..6dc31c618 100644 --- a/packages/vant/src/tab/test/index.spec.tsx +++ b/packages/vant/src/tab/test/index.spec.tsx @@ -44,7 +44,7 @@ test('should not render zero badge when show-zero-badge prop is false', async () }, }); await later(); - expect(wrapper.findAll('.van-badge').length).toEqual(1); + expect(wrapper.findAll('.van-badge')).toHaveLength(1); }); test('should switch tab after click the tab title', async () => { diff --git a/packages/vant/src/tag/test/index.spec.ts b/packages/vant/src/tag/test/index.spec.ts index 20205bb33..ae73a441c 100644 --- a/packages/vant/src/tag/test/index.spec.ts +++ b/packages/vant/src/tag/test/index.spec.ts @@ -9,7 +9,7 @@ test('should emit close event when clicking the close icon', () => { }); wrapper.find('.van-tag__close').trigger('click'); - expect(wrapper.emitted('close')!.length).toEqual(1); + expect(wrapper.emitted('close')).toHaveLength(1); }); test('should hide tag when the show prop is false', () => { From a06f2666a1ecb7be99a6cd9ce4cfdc34caf0dd6c Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 17 Dec 2021 17:52:13 +0800 Subject: [PATCH 11/94] feat(Notify): add position prop (#10056) * feat(Notify): add position prop * chore: update --- packages/vant/src/notify/Notify.tsx | 5 +++-- packages/vant/src/notify/README.md | 13 ++++++++++++- packages/vant/src/notify/README.zh-CN.md | 15 +++++++++++++-- packages/vant/src/notify/demo/index.vue | 14 ++++++++++++++ packages/vant/src/notify/function-call.tsx | 1 + .../notify/test/__snapshots__/demo.spec.ts.snap | 12 ++++++++++++ .../{index.spec.js.snap => index.spec.ts.snap} | 0 .../test/{index.spec.js => index.spec.ts} | 17 ++++++++++++++--- packages/vant/src/notify/types.ts | 3 +++ 9 files changed, 72 insertions(+), 8 deletions(-) rename packages/vant/src/notify/test/__snapshots__/{index.spec.js.snap => index.spec.ts.snap} (100%) rename packages/vant/src/notify/test/{index.spec.js => index.spec.ts} (78%) diff --git a/packages/vant/src/notify/Notify.tsx b/packages/vant/src/notify/Notify.tsx index 90900d385..9207dbd2e 100644 --- a/packages/vant/src/notify/Notify.tsx +++ b/packages/vant/src/notify/Notify.tsx @@ -8,7 +8,7 @@ import { } from '../utils'; import { Popup } from '../popup'; import { popupSharedProps } from '../popup/shared'; -import type { NotifyType } from './types'; +import type { NotifyType, NotifyPosition } from './types'; const [name, bem] = createNamespace('notify'); @@ -16,6 +16,7 @@ const notifyProps = extend({}, popupSharedProps, { type: makeStringProp('danger'), color: String, message: numericProp, + position: makeStringProp('top'), className: unknownProp, background: String, lockScroll: Boolean, @@ -42,7 +43,7 @@ export default defineComponent({ background: props.background, }} overlay={false} - position="top" + position={props.position} duration={0.2} lockScroll={props.lockScroll} onUpdate:show={updateShow} diff --git a/packages/vant/src/notify/README.md b/packages/vant/src/notify/README.md index b0bbc6e25..cddcf6cb7 100644 --- a/packages/vant/src/notify/README.md +++ b/packages/vant/src/notify/README.md @@ -42,6 +42,11 @@ Notify({ background: '#ffe1e1', }); +Notify({ + message: 'Custom Position', + position: 'bottom', +}); + Notify({ message: 'Custom Duration', duration: 1000, @@ -110,6 +115,7 @@ export default { | type | Can be set to `primary` `success` `warning` | _NotifyType_ | `danger` | | message | Message | _string_ | - | | duration | Duration(ms), won't disappear if value is 0 | _number \| string_ | `3000` | +| position `v3.3.8` | Position, can be set to `bottom` | _NotifyPosition_ | `top` | | color | Message color | _string_ | `white` | | background | Background color | _string_ | - | | className | Custom className | _string \| Array \| object_ | - | @@ -123,7 +129,12 @@ export default { The component exports the following type definitions: ```ts -import type { NotifyType, NotifyProps, NotifyOptions } from 'vant'; +import type { + NotifyType, + NotifyProps, + NotifyOptions, + NotifyPosition, +} from 'vant'; ``` ## Theming diff --git a/packages/vant/src/notify/README.zh-CN.md b/packages/vant/src/notify/README.zh-CN.md index 28e2ac85e..b6b182d2b 100644 --- a/packages/vant/src/notify/README.zh-CN.md +++ b/packages/vant/src/notify/README.zh-CN.md @@ -77,7 +77,7 @@ Notify({ type: 'warning', message: '通知内容' }); ### 自定义通知 -自定义消息通知的颜色和展示时长。 +自定义消息通知的颜色、位置和展示时长。 ```js Notify({ @@ -86,6 +86,11 @@ Notify({ background: '#ffe1e1', }); +Notify({ + message: '自定义位置', + position: 'bottom', +}); + Notify({ message: '自定义时长', duration: 1000, @@ -158,6 +163,7 @@ export default { | type | 类型,可选值为 `primary` `success` `warning` | _NotifyType_ | `danger` | | message | 展示文案,支持通过`\n`换行 | _string_ | - | | duration | 展示时长(ms),值为 0 时,notify 不会消失 | _number \| string_ | `3000` | +| position `v3.3.8` | 弹出位置,可选值为 `bottom` | _NotifyPosition_ | `top` | | color | 字体颜色 | _string_ | `white` | | background | 背景颜色 | _string_ | - | | className | 自定义类名 | _string \| Array \| object_ | - | @@ -171,7 +177,12 @@ export default { 组件导出以下类型定义: ```ts -import type { NotifyType, NotifyProps, NotifyOptions } from 'vant'; +import type { + NotifyType, + NotifyProps, + NotifyOptions, + NotifyPosition, +} from 'vant'; ``` ## 主题定制 diff --git a/packages/vant/src/notify/demo/index.vue b/packages/vant/src/notify/demo/index.vue index 2600ed712..f49ee4cb4 100644 --- a/packages/vant/src/notify/demo/index.vue +++ b/packages/vant/src/notify/demo/index.vue @@ -20,6 +20,7 @@ const t = useTranslate({ customNotify: '自定义配置', componentCall: '组件调用', customDuration: '自定义时长', + customPosition: '自定义位置', }, 'en-US': { primary: 'Primary', @@ -32,6 +33,7 @@ const t = useTranslate({ customNotify: 'Custom Notify', componentCall: 'Component Call', customDuration: 'Custom Duration', + customPosition: 'Custom Position', }, }); @@ -56,6 +58,13 @@ const showCustomDuration = () => { }); }; +const showCustomPosition = () => { + Notify({ + message: t('customPosition'), + position: 'bottom', + }); +}; + const showType = (type: NotifyType) => { Notify({ message: t('content'), @@ -85,6 +94,11 @@ const showComponentCall = () => { + ({ onClick: undefined, onOpened: undefined, duration: 3000, + position: undefined, className: '', lockScroll: false, background: undefined, diff --git a/packages/vant/src/notify/test/__snapshots__/demo.spec.ts.snap b/packages/vant/src/notify/test/__snapshots__/demo.spec.ts.snap index f9b023818..0ff23424a 100644 --- a/packages/vant/src/notify/test/__snapshots__/demo.spec.ts.snap +++ b/packages/vant/src/notify/test/__snapshots__/demo.spec.ts.snap @@ -78,6 +78,18 @@ exports[`should render demo and match snapshot 1`] = `
+
+
+ + Custom Position + +
+ + +
}); await later(); - const notify = document.querySelector('.van-notify'); + const notify = document.querySelector('.van-notify') as HTMLElement; expect(notify.classList.contains('van-notify--success')).toBeTruthy(); }); test('should register component to app', () => { - const app = createApp(); + const app = createApp({}); app.use(Notify); expect(app.component(NotifyComponent.name)).toBeTruthy(); }); @@ -63,7 +63,18 @@ test('should call onClick option when clicked', async () => { }); await later(); - const notify = document.querySelector('.van-notify'); + const notify = document.querySelector('.van-notify') as HTMLElement; notify.click(); expect(onClick).toHaveBeenCalledTimes(1); }); + +test('should align to bottom when position option is bottom', async () => { + Notify({ + message: 'test', + position: 'bottom', + }); + + await later(); + const notify = document.querySelector('.van-notify') as HTMLElement; + expect(notify.classList.contains('van-popup--bottom')).toBeTruthy(); +}); diff --git a/packages/vant/src/notify/types.ts b/packages/vant/src/notify/types.ts index 661c2ddd1..08bec392f 100644 --- a/packages/vant/src/notify/types.ts +++ b/packages/vant/src/notify/types.ts @@ -4,11 +4,14 @@ export type NotifyMessage = string | number; export type NotifyType = 'primary' | 'success' | 'danger' | 'warning'; +export type NotifyPosition = 'top' | 'bottom'; + export type NotifyOptions = { type?: NotifyType; color?: string; message?: NotifyMessage; duration?: number; + position?: NotifyPosition; className?: unknown; background?: string; lockScroll?: boolean; From 0e0339ef6b224e0ba3525a736785b4f42fd5a19c Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 17 Dec 2021 20:48:16 +0800 Subject: [PATCH 12/94] docs: add vant use install guide (#10058) --- .../vant/docs/markdown/vant-use-intro.en-US.md | 15 +++++++++++++++ .../vant/docs/markdown/vant-use-intro.zh-CN.md | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/vant/docs/markdown/vant-use-intro.en-US.md b/packages/vant/docs/markdown/vant-use-intro.en-US.md index 5797982c7..647195f23 100644 --- a/packages/vant/docs/markdown/vant-use-intro.en-US.md +++ b/packages/vant/docs/markdown/vant-use-intro.en-US.md @@ -4,6 +4,21 @@ Vant provide some built-in composition APIs, you can directly use these APIs for development. +### Install + +Although `@vant/use` is already included in Vant's dependencies, it is still recommended to install this package explicitly: + +```shell +# with npm +npm i @vant/use + +# with yarn +yarn add @vant/use + +# with pnpm +pnpm add @vant/use +``` + ### Demo ```js diff --git a/packages/vant/docs/markdown/vant-use-intro.zh-CN.md b/packages/vant/docs/markdown/vant-use-intro.zh-CN.md index 03a548a50..2b3df5a35 100644 --- a/packages/vant/docs/markdown/vant-use-intro.zh-CN.md +++ b/packages/vant/docs/markdown/vant-use-intro.zh-CN.md @@ -2,7 +2,22 @@ ### 介绍 -Vant 内置了一系列的组合式 API,对于安装了 `vant` 的项目,可以直接使用这些 API 进行开发。 +Vant 底层依赖了 `@vant/use` 包,其中内置了一系列的组合式 API。对于使用了 Vant 的项目,可以复用这些 API 进行开发。 + +### 安装 + +虽然 Vant 的依赖中已经包含了 `@vant/use`,但我们仍然推荐显式地安装它: + +```shell +# with npm +npm i @vant/use + +# with yarn +yarn add @vant/use + +# with pnpm +pnpm add @vant/use +``` ### 示例 From be7a08bd207647a38d26791b9da3eceff98784d0 Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 17 Dec 2021 20:59:48 +0800 Subject: [PATCH 13/94] fix(SwipeCell): should not trigger open event when opened (#10059) --- packages/vant/src/swipe-cell/SwipeCell.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/vant/src/swipe-cell/SwipeCell.tsx b/packages/vant/src/swipe-cell/SwipeCell.tsx index 84d3b5ce9..61174a534 100644 --- a/packages/vant/src/swipe-cell/SwipeCell.tsx +++ b/packages/vant/src/swipe-cell/SwipeCell.tsx @@ -80,13 +80,15 @@ export default defineComponent({ ); const open = (side: SwipeCellSide) => { - opened = true; state.offset = side === 'left' ? leftWidth.value : -rightWidth.value; - emit('open', { - name: props.name, - position: side, - }); + if (!opened) { + opened = true; + emit('open', { + name: props.name, + position: side, + }); + } }; const close = (position: SwipeCellPosition) => { From 92fb70d6e891e893ae4c2772b8d12958e1b84e13 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 18 Dec 2021 08:32:57 +0800 Subject: [PATCH 14/94] feat(Swipe): indicator slot add total param (#10060) * feat(Swipe): indicator slot add total param * test: indicator slot --- packages/vant/src/swipe/README.md | 8 +++---- packages/vant/src/swipe/README.zh-CN.md | 8 +++---- packages/vant/src/swipe/Swipe.tsx | 1 + .../test/__snapshots__/index.spec.js.snap | 22 +++++++++++++++++++ packages/vant/src/swipe/test/index.spec.js | 22 +++++++++++++++++++ 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/packages/vant/src/swipe/README.md b/packages/vant/src/swipe/README.md index 4b93268af..54076e953 100644 --- a/packages/vant/src/swipe/README.md +++ b/packages/vant/src/swipe/README.md @@ -206,10 +206,10 @@ swipeRef.value?.next(); ### Swipe Slots -| Name | Description | SlotProps | -| ------------------- | ---------------- | -------------------- | -| default | Content | - | -| indicator `v3.0.16` | Custom indicator | _{ active: number }_ | +| Name | Description | SlotProps | +| ------------------ | ---------------- | ----------------------------------- | +| default | Content | - | +| indicator `v3.3.8` | Custom indicator | _{ active: number, total: number }_ | ## Theming diff --git a/packages/vant/src/swipe/README.zh-CN.md b/packages/vant/src/swipe/README.zh-CN.md index 43abd9e4c..98636d516 100644 --- a/packages/vant/src/swipe/README.zh-CN.md +++ b/packages/vant/src/swipe/README.zh-CN.md @@ -214,10 +214,10 @@ swipeRef.value?.next(); ### Swipe Slots -| 名称 | 说明 | 参数 | -| ------------------- | ------------ | -------------------- | -| default | 轮播内容 | - | -| indicator `v3.0.16` | 自定义指示器 | _{ active: number }_ | +| 名称 | 说明 | 参数 | +| ------------------ | ------------ | ----------------------------------- | +| default | 轮播内容 | - | +| indicator `v3.3.8` | 自定义指示器 | _{ active: number, total: number }_ | ## 主题定制 diff --git a/packages/vant/src/swipe/Swipe.tsx b/packages/vant/src/swipe/Swipe.tsx index 3fd156f9d..564fd277a 100644 --- a/packages/vant/src/swipe/Swipe.tsx +++ b/packages/vant/src/swipe/Swipe.tsx @@ -384,6 +384,7 @@ export default defineComponent({ if (slots.indicator) { return slots.indicator({ active: activeIndicator.value, + total: count.value, }); } if (props.showIndicators && count.value > 1) { diff --git a/packages/vant/src/swipe/test/__snapshots__/index.spec.js.snap b/packages/vant/src/swipe/test/__snapshots__/index.spec.js.snap index 729711266..e09105ee3 100644 --- a/packages/vant/src/swipe/test/__snapshots__/index.spec.js.snap +++ b/packages/vant/src/swipe/test/__snapshots__/index.spec.js.snap @@ -76,6 +76,28 @@ exports[`should render dynamic SwipeItem correctly 2`] = `
`; +exports[`should render indicator slot correctly 1`] = ` +
+
+
+ 1 +
+
+ 2 +
+
+ active: 0, total: 2 +
+`; + exports[`should render initial swipe correctly 1`] = `
{ await later(); expect(wrapper.html()).toMatchSnapshot(); }); + +test('should render indicator slot correctly', async () => { + const wrapper = mount({ + render() { + return ( + + `active: ${active}, total: ${total}`, + }} + style={swipeStyle} + > + 1 + 2 + + ); + }, + }); + + await later(); + expect(wrapper.html()).toMatchSnapshot(); +}); From 0002f1b1afeacff04e58c0ea3c8fbdb52798029e Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 18 Dec 2021 10:46:29 +0800 Subject: [PATCH 15/94] docs(Swipe): update demo (#10061) --- packages/vant/src/swipe/README.md | 4 ++-- packages/vant/src/swipe/README.zh-CN.md | 4 ++-- packages/vant/src/swipe/demo/index.vue | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vant/src/swipe/README.md b/packages/vant/src/swipe/README.md index 54076e953..f10856c2c 100644 --- a/packages/vant/src/swipe/README.md +++ b/packages/vant/src/swipe/README.md @@ -120,8 +120,8 @@ export default { 2 3 4 -