From 31f713bf1bb75a6b6065d23de1a8dc8a5cdc19dd Mon Sep 17 00:00:00 2001 From: Hefty Date: Tue, 11 Oct 2022 10:21:19 +0800 Subject: [PATCH] feat(components): [rate] add clearable attribute (#10031) feat(components): [rate] add clearable attribute --- docs/en-US/component/rate.md | 9 ++++++++ docs/examples/rate/clearable.vue | 9 ++++++++ .../components/rate/__tests__/rate.test.tsx | 23 +++++++++++++++++++ packages/components/rate/src/rate.ts | 4 ++++ packages/components/rate/src/rate.vue | 22 +++++++++++------- 5 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 docs/examples/rate/clearable.vue diff --git a/docs/en-US/component/rate.md b/docs/en-US/component/rate.md index 9bedab804c..a051515a9c 100644 --- a/docs/en-US/component/rate.md +++ b/docs/en-US/component/rate.md @@ -41,6 +41,14 @@ rate/text ::: +## Clearable + +:::demo You can reset the value to `0` when you click at the same value again. + +rate/clearable + +::: + ## More icons You can use different icons to distinguish different rate components. @@ -97,6 +105,7 @@ Use `css/scss` language to change the global or local color. We set some global | text-color | color of texts | string | — | #1F2D3D | | texts | text array | array | — | ['Extremely bad', 'Disappointed', 'Fair', 'Satisfied', 'Surprise'] | | score-template | score template | string | — | {value} | +| clearable | whether value can be reset to `0` | boolean | — | false | ## Events diff --git a/docs/examples/rate/clearable.vue b/docs/examples/rate/clearable.vue new file mode 100644 index 0000000000..08129bf3a1 --- /dev/null +++ b/docs/examples/rate/clearable.vue @@ -0,0 +1,9 @@ + + + diff --git a/packages/components/rate/__tests__/rate.test.tsx b/packages/components/rate/__tests__/rate.test.tsx index b9aeb0ce45..8d04ac75a6 100644 --- a/packages/components/rate/__tests__/rate.test.tsx +++ b/packages/components/rate/__tests__/rate.test.tsx @@ -113,6 +113,29 @@ describe('Rate.vue', () => { expect(changeCount.value).toEqual(1) }) + it('clearable', () => { + const value = ref(4) + const changeCount = ref(0) + const handleChange = () => { + changeCount.value++ + } + const wrapper = mount(() => ( + + )) + + const fourthStar = wrapper.findAll('.el-rate__item')[3] + .element as HTMLElement + fourthStar.click() + + expect(value.value).toEqual(0) + expect(changeCount.value).toEqual(1) + const fifthStar = wrapper.findAll('.el-rate__item')[4] + .element as HTMLElement + fifthStar.click() + expect(value.value).toEqual(5) + expect(changeCount.value).toEqual(2) + }) + describe('form item accessibility integration', () => { it('automatic id attachment', async () => { const wrapper = mount(() => ( diff --git a/packages/components/rate/src/rate.ts b/packages/components/rate/src/rate.ts index b2d9da8e5d..e010ce08e2 100644 --- a/packages/components/rate/src/rate.ts +++ b/packages/components/rate/src/rate.ts @@ -98,6 +98,10 @@ export const rateProps = buildProps({ type: String, default: undefined, }, + clearable: { + type: Boolean, + default: false, + }, } as const) export type RateProps = ExtractPropTypes diff --git a/packages/components/rate/src/rate.vue b/packages/components/rate/src/rate.vue index 52dc14a12c..2bea9b2d69 100644 --- a/packages/components/rate/src/rate.vue +++ b/packages/components/rate/src/rate.vue @@ -195,20 +195,26 @@ function showDecimalIcon(item: number) { return showWhenDisabled || showWhenAllowHalf } +function emitValue(value: number) { + // if allow clear, and selected value is same as modelValue, reset value to 0 + if (props.clearable && value === props.modelValue) { + value = 0 + } + + emit(UPDATE_MODEL_EVENT, value) + if (props.modelValue !== value) { + emit('change', value) + } +} + function selectValue(value: number) { if (rateDisabled.value) { return } if (props.allowHalf && pointerAtLeftHalf.value) { - emit(UPDATE_MODEL_EVENT, currentValue.value) - if (props.modelValue !== currentValue.value) { - emit('change', currentValue.value) - } + emitValue(currentValue.value) } else { - emit(UPDATE_MODEL_EVENT, value) - if (props.modelValue !== value) { - emit('change', value) - } + emitValue(value) } }