diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..079ea4888 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +chenjiahan@buaa.edu.cn diff --git a/src/badge/README.md b/src/badge/README.md index fc72752f5..c442a3cba 100644 --- a/src/badge/README.md +++ b/src/badge/README.md @@ -117,6 +117,7 @@ Use `content` slot to custom :content of badge. | color | Background color | _string_ | `#ee0a24` | | dot | Whether to show dot | _boolean_ | `false` | | max | Max value,show `{max}+` when exceed,only works when content is number | _number \| string_ | - | +| offset `v3.0.5` | Offset of badge dot | _[number, number]_ | - | ### Slots diff --git a/src/badge/README.zh-CN.md b/src/badge/README.zh-CN.md index 454bf8247..1b76865ac 100644 --- a/src/badge/README.zh-CN.md +++ b/src/badge/README.zh-CN.md @@ -129,6 +129,7 @@ app.use(Badge); | color | 徽标背景颜色 | _string_ | `#ee0a24` | | dot | 是否展示为小红点 | _boolean_ | `false` | | max | 最大值,超过最大值会显示 `{max}+`,仅当 content 为数字时有效 | _number \| string_ | - | +| offset `v3.0.5` | 设置徽标的偏移量,数组的两项分别对应水平和垂直方向的偏移量 | _[number, number]_ | - | ### Slots diff --git a/src/badge/demo/index.vue b/src/badge/demo/index.vue index 8fb338850..8394dc342 100644 --- a/src/badge/demo/index.vue +++ b/src/badge/demo/index.vue @@ -3,6 +3,12 @@
+ +
+ + +
+
@@ -12,6 +18,9 @@
+ +
+
@@ -21,12 +30,37 @@
+ +
+
+ + +
+ + + +
+ + + +
+ + + + + @@ -76,6 +110,7 @@ export default { .badge-icon { display: block; + margin-left: 0; font-size: 10px; line-height: 16px; } diff --git a/src/badge/index.tsx b/src/badge/index.tsx index 596820199..7544f90cb 100644 --- a/src/badge/index.tsx +++ b/src/badge/index.tsx @@ -1,4 +1,4 @@ -import type { PropType } from 'vue'; +import type { PropType, CSSProperties } from 'vue'; import { isDef, createNamespace } from '../utils'; import { isNumeric } from '../utils/validate/number'; @@ -9,6 +9,7 @@ export default createComponent({ dot: Boolean, max: [Number, String], color: String, + offset: (Array as unknown) as PropType<[number, number]>, content: [Number, String], tag: { type: String as PropType, @@ -38,10 +39,25 @@ export default createComponent({ const renderBadge = () => { if (hasContent() || props.dot) { + const style: CSSProperties = { + background: props.color, + }; + + if (props.offset) { + const [x, y] = props.offset; + if (slots.default) { + style.top = `${y}px`; + style.right = `${-x}px`; + } else { + style.marginTop = `${y}px`; + style.marginLeft = `${x}px`; + } + } + return (
{renderContent()}
diff --git a/src/badge/test/__snapshots__/demo.spec.js.snap b/src/badge/test/__snapshots__/demo.spec.js.snap index 108c54e9b..b2109b53e 100644 --- a/src/badge/test/__snapshots__/demo.spec.js.snap +++ b/src/badge/test/__snapshots__/demo.spec.js.snap @@ -9,6 +9,20 @@ exports[`should render demo and match snapshot 1`] = ` 5
+
+
+
+
+ 10 +
+
+
+
+
+
+ Hot +
+
@@ -24,6 +38,13 @@ exports[`should render demo and match snapshot 1`] = ` 9+
+
+
+
+
+ 20+ +
+
@@ -42,6 +63,15 @@ exports[`should render demo and match snapshot 1`] = ` 5
+
+
+
+
+ 10 +
+
@@ -52,6 +82,37 @@ exports[`should render demo and match snapshot 1`] = `
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+
+ 20 +
diff --git a/src/badge/test/index.spec.js b/src/badge/test/index.spec.js index 86984be2d..af105d21b 100644 --- a/src/badge/test/index.spec.js +++ b/src/badge/test/index.spec.js @@ -40,3 +40,32 @@ test('should render content slot correctly', () => { expect(wrapper.html()).toMatchSnapshot(); }); + +test('should change dot position when using offset prop', () => { + const wrapper = mount(Badge, { + props: { + dot: true, + offset: [2, 4], + }, + slots: { + default: () => 'Child', + }, + }); + + const badge = wrapper.find('.van-badge').element; + expect(badge.style.top).toEqual('4px'); + expect(badge.style.right).toEqual('-2px'); +}); + +test('should change dot position when using offset prop without children', () => { + const wrapper = mount(Badge, { + props: { + dot: true, + offset: [2, 4], + }, + }); + + const badge = wrapper.find('.van-badge').element; + expect(badge.style.marginTop).toEqual('4px'); + expect(badge.style.marginLeft).toEqual('2px'); +}); diff --git a/src/calendar/README.md b/src/calendar/README.md index 15faa7689..6666f9039 100644 --- a/src/calendar/README.md +++ b/src/calendar/README.md @@ -336,7 +336,7 @@ Use [ref](https://v3.vuejs.org/guide/component-template-refs.html) to get Calend | Name | Description | Attribute | Return value | | --- | --- | --- | --- | -| reset | Reset selected date to default date | - | - | +| reset | Reset selected date, will reset to default date when no params passed | _date?: Date \| Date[]_ | - | | scrollToDate | Scroll to date | _date: Date_ | - | ### Less Variables diff --git a/src/calendar/README.zh-CN.md b/src/calendar/README.zh-CN.md index 5fb6e2437..d4710d487 100644 --- a/src/calendar/README.zh-CN.md +++ b/src/calendar/README.zh-CN.md @@ -340,10 +340,10 @@ export default { 通过 ref 可以获取到 Calendar 实例并调用实例方法,详见[组件实例方法](#/zh-CN/advanced-usage#zu-jian-shi-li-fang-fa)。 -| 方法名 | 说明 | 参数 | 返回值 | -| ------------ | ---------------------- | ------------ | ------ | -| reset | 重置选中的日期到默认值 | - | - | -| scrollToDate | 滚动到某个日期 | _date: Date_ | - | +| 方法名 | 说明 | 参数 | 返回值 | +| --- | --- | --- | --- | +| reset | 将选中的日期重置到指定日期,未传参时会重置到默认日期 | _date?: Date \| Date[]_ | - | +| scrollToDate | 滚动到某个日期 | _date: Date_ | - | ### 样式变量 diff --git a/src/calendar/index.js b/src/calendar/index.js index 1929690ac..88a621d17 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -311,8 +311,8 @@ export default createComponent({ }); }; - const reset = () => { - state.currentDate = getInitialDate(state.currentDate); + const reset = (date = getInitialDate()) => { + state.currentDate = date; scrollIntoView(); }; @@ -500,7 +500,9 @@ export default createComponent({ ); watch(() => props.show, init); - watch([() => props.type, () => props.minDate, () => props.maxDate], reset); + watch([() => props.type, () => props.minDate, () => props.maxDate], () => { + reset(getInitialDate(state.currentDate)); + }); watch( () => props.defaultDate, (value) => { diff --git a/src/calendar/test/index.legacy.js b/src/calendar/test/index.legacy.js index 2b3298129..eb496309e 100644 --- a/src/calendar/test/index.legacy.js +++ b/src/calendar/test/index.legacy.js @@ -196,31 +196,6 @@ test('default range date', async () => { ); }); -test('reset method', async () => { - const wrapper = mount(Calendar, { - props: { - minDate, - maxDate, - type: 'range', - poppable: false, - defaultDate: [minDate, getNextDay(minDate)], - }, - }); - - await later(); - - const days = wrapper.findAll('.van-calendar__day'); - days.at(15).trigger('click'); - days.at(18).trigger('click'); - - wrapper.vm.reset(); - - wrapper.find('.van-calendar__confirm').trigger('click'); - expect(formatRange(wrapper.emitted('confirm')[0][0])).toEqual( - '2010/1/10-2010/1/11' - ); -}); - test('set show-confirm to false', async () => { const wrapper = mount(Calendar, { props: { diff --git a/src/calendar/test/index.spec.js b/src/calendar/test/index.spec.js new file mode 100644 index 000000000..4ee865418 --- /dev/null +++ b/src/calendar/test/index.spec.js @@ -0,0 +1,50 @@ +import Calendar from '..'; +import { mount } from '../../../test'; +import { getNextDay, getPrevDay } from '../utils'; +import { minDate, maxDate } from './utils'; + +test('should reset to default date when calling reset method', async () => { + const defaultDate = [minDate, getNextDay(minDate)]; + const wrapper = mount(Calendar, { + props: { + minDate, + maxDate, + type: 'range', + poppable: false, + lazyRender: false, + defaultDate, + }, + }); + + const days = wrapper.findAll('.van-calendar__day'); + await days[15].trigger('click'); + await days[18].trigger('click'); + + wrapper.vm.reset(); + + wrapper.find('.van-calendar__confirm').trigger('click'); + expect(wrapper.emitted('confirm')[0][0]).toEqual(defaultDate); +}); + +test('should reset to specific date when calling reset method with date', async () => { + const wrapper = mount(Calendar, { + props: { + minDate, + maxDate, + type: 'range', + poppable: false, + lazyRender: false, + defaultDate: [minDate, getNextDay(minDate)], + }, + }); + + const days = wrapper.findAll('.van-calendar__day'); + await days[15].trigger('click'); + await days[18].trigger('click'); + + const newDate = [getPrevDay(maxDate), maxDate]; + wrapper.vm.reset(newDate); + + wrapper.find('.van-calendar__confirm').trigger('click'); + expect(wrapper.emitted('confirm')[0][0]).toEqual(newDate); +}); diff --git a/src/dialog/Dialog.js b/src/dialog/Dialog.js index 95edeccf6..f59792fd8 100644 --- a/src/dialog/Dialog.js +++ b/src/dialog/Dialog.js @@ -120,7 +120,12 @@ export default createComponent({ if (message) { const hasTitle = title || slots.title; return ( -
+
{ - state.scale = range(scale, +props.minZoom, +props.maxZoom); - emit('scale', { - scale: state.scale, - index: state.active, - }); + scale = range(scale, +props.minZoom, +props.maxZoom); + + if (scale !== state.scale) { + state.scale = scale; + emit('scale', { + scale, + index: props.active, + }); + } }; const resetScale = () => { @@ -235,6 +239,7 @@ export default { state.imageRatio = naturalHeight / naturalWidth; }; + watch(() => props.active, resetScale); watch( () => props.show, (value) => { diff --git a/src/image-preview/README.md b/src/image-preview/README.md index baec912d5..d463479e7 100644 --- a/src/image-preview/README.md +++ b/src/image-preview/README.md @@ -127,7 +127,7 @@ export default { | showIndex | Whether to show index | _boolean_ | `true` | | showIndicators | Whether to show indicators | _boolean_ | `false` | | loop | Whether to enable loop | _boolean_ | `true` | -| swipeDuration | Animation duration (ms) | _number \| string_ | `500` | +| swipeDuration | Animation duration (ms) | _number \| string_ | `300` | | onClose | Emitted when ImagePreview is closed | _Function_ | - | | onChange | Emitted when current image changed | _Function_ | - | | onScale | Emitted when scaling current image | _Function_ | - | @@ -147,7 +147,7 @@ export default { | --- | --- | --- | --- | | images | Images URL list | _string[]_ | `[]` | | start-position | Start position | _number \| string_ | `0` | -| swipe-duration | Animation duration (ms) | _number \| string_ | `500` | +| swipe-duration | Animation duration (ms) | _number \| string_ | `300` | | show-index | Whether to show index | _boolean_ | `true` | | show-indicators | Whether to show indicators | _boolean_ | `false` | | loop | Whether to enable loop | _boolean_ | `true` | diff --git a/src/image-preview/README.zh-CN.md b/src/image-preview/README.zh-CN.md index 789a38114..1f9d5b688 100644 --- a/src/image-preview/README.zh-CN.md +++ b/src/image-preview/README.zh-CN.md @@ -161,7 +161,7 @@ export default { | --- | --- | --- | --- | | images | 需要预览的图片 URL 数组 | _string[]_ | `[]` | | startPosition | 图片预览起始位置索引 | _number \| string_ | `0` | -| swipeDuration | 动画时长,单位为`ms` | _number \| string_ | `500` | +| swipeDuration | 动画时长,单位为 `ms` | _number \| string_ | `300` | | showIndex | 是否显示页码 | _boolean_ | `true` | | showIndicators | 是否显示轮播指示器 | _boolean_ | `false` | | loop | 是否开启循环播放 | _boolean_ | `true` | @@ -175,7 +175,7 @@ export default { | minZoom | 手势缩放时,最小缩放比例 | _number \| string_ | `1/3` | | closeable | 是否显示关闭图标 | _boolean_ | `false` | | closeIcon | 关闭图标名称或图片链接 | _string_ | `clear` | -| closeIconPosition | 关闭图标位置,可选值为`top-left`
`bottom-left` `bottom-right` | _string_ | `top-right` | +| closeIconPosition | 关闭图标位置,可选值为 `top-left`
`bottom-left` `bottom-right` | _string_ | `top-right` | | teleport | 指定挂载的节点,[用法示例](#/zh-CN/popup#zhi-ding-gua-zai-wei-zhi) | _string \| Element_ | - | ### Props @@ -186,7 +186,7 @@ export default { | --- | --- | --- | --- | | images | 需要预览的图片 URL 数组 | _string[]_ | `[]` | | start-position | 图片预览起始位置索引 | _number \| string_ | `0` | -| swipe-duration | 动画时长,单位为 ms | _number \| string_ | `500` | +| swipe-duration | 动画时长,单位为 ms | _number \| string_ | `300` | | show-index | 是否显示页码 | _boolean_ | `true` | | show-indicators | 是否显示轮播指示器 | _boolean_ | `false` | | loop | 是否开启循环播放 | _boolean_ | `true` | diff --git a/src/image-preview/index.js b/src/image-preview/index.js index 4cd178fd8..b83aec2ce 100644 --- a/src/image-preview/index.js +++ b/src/image-preview/index.js @@ -19,7 +19,7 @@ const defaultConfig = { closeIcon: 'clear', beforeClose: null, startPosition: 0, - swipeDuration: 500, + swipeDuration: 300, showIndicators: false, closeOnPopstate: true, closeIconPosition: 'top-right', diff --git a/src/image-preview/test/__snapshots__/index.spec.js.snap b/src/image-preview/test/__snapshots__/index.spec.js.snap index b972b1098..d6f6ae45f 100644 --- a/src/image-preview/test/__snapshots__/index.spec.js.snap +++ b/src/image-preview/test/__snapshots__/index.spec.js.snap @@ -22,7 +22,7 @@ exports[`should render cover slot correctly 1`] = `
-
diff --git a/src/picker/README.zh-CN.md b/src/picker/README.zh-CN.md index 29af4b9f5..4fc5437b0 100644 --- a/src/picker/README.zh-CN.md +++ b/src/picker/README.zh-CN.md @@ -100,7 +100,7 @@ export default { ### 级联选择 -使用 `columns` 的 `children` 字段可以实现选项级联的效果。 +使用 `columns` 的 `children` 字段可以实现选项级联的效果。如果级联层级较多,推荐使用 [Cascader 级联选项组件](#/zh-CN/cascader)。 ```html @@ -143,7 +143,7 @@ export default { }; ``` -> 级联选择的数据嵌套深度需要保持一致,如果部分选项没有子选项,可以使用空字符串进行占位 +> 级联选择的数据嵌套深度需要保持一致,如果部分选项没有子选项,可以使用空字符串进行占位。 ### 禁用选项 diff --git a/types/calendar.d.ts b/types/calendar.d.ts index bc815f8d0..f516e2f06 100644 --- a/types/calendar.d.ts +++ b/types/calendar.d.ts @@ -1,7 +1,7 @@ import { VanComponent } from './component'; export class Calendar extends VanComponent { - reset(): void; + reset(date?: Date | Date[]): void; scrollToDate(date: Date): void; }