feat: update checkbox

pull/1790/head
tangjinzhou 2020-02-11 15:21:29 +08:00
parent 81e6391707
commit c0b92c6c50
11 changed files with 132 additions and 60 deletions

View File

@ -1,5 +1,5 @@
module.exports = {
dev: {
componentName: 'carousel', // dev components
componentName: 'checkbox', // dev components
},
};

View File

@ -1,13 +1,15 @@
import PropTypes from '../_util/vue-types';
import classNames from 'classnames';
import VcCheckbox from '../vc-checkbox';
import { getOptionProps, getAttrs, getListeners } from '../_util/props-util';
import hasProp, { getOptionProps, getAttrs, getListeners } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
function noop() {}
export default {
name: 'ACheckbox',
inheritAttrs: false,
__ANT_CHECKBOX: true,
model: {
prop: 'checked',
},
@ -26,7 +28,36 @@ export default {
},
inject: {
configProvider: { default: () => ConfigConsumerProps },
checkboxGroupContext: { default: () => null },
checkboxGroupContext: { default: () => undefined },
},
watch: {
value(value, prevValue) {
this.$nextTick(() => {
const { checkboxGroupContext: checkboxGroup = {} } = this;
if (checkboxGroup.registerValue && checkboxGroup.cancelValue) {
checkboxGroup.cancelValue(prevValue);
checkboxGroup.registerValue(value);
}
});
},
},
mounted() {
const { value, checkboxGroupContext: checkboxGroup = {} } = this;
if (checkboxGroup.registerValue) {
checkboxGroup.registerValue(value);
}
warning(
hasProp(this, 'checked') || this.checkboxGroupContext || !hasProp(this, 'value'),
'Checkbox',
'`value` is not validate prop, do you mean `checked`?',
);
},
beforeDestroy() {
const { value, checkboxGroupContext: checkboxGroup = {} } = this;
if (checkboxGroup.cancelValue) {
checkboxGroup.cancelValue(value);
}
},
methods: {
handleChange(event) {
@ -61,6 +92,7 @@ export default {
this.$emit('change', ...args);
checkboxGroup.toggleOption({ label: children, value: props.value });
};
checkboxProps.props.name = checkboxGroup.name;
checkboxProps.props.checked = checkboxGroup.sValue.indexOf(props.value) !== -1;
checkboxProps.props.disabled = props.disabled || checkboxGroup.disabled;
} else {

View File

@ -10,6 +10,7 @@ export default {
prop: 'value',
},
props: {
name: PropTypes.string,
prefixCls: PropTypes.string,
defaultValue: PropTypes.array,
value: PropTypes.array,
@ -28,6 +29,7 @@ export default {
const { value, defaultValue } = this;
return {
sValue: value || defaultValue || [],
registeredValues: [],
};
},
watch: {
@ -52,7 +54,15 @@ export default {
return { ...option, label };
});
},
cancelValue(value) {
this.registeredValues = this.registeredValues.filter(val => val !== value);
},
registerValue(value) {
this.registeredValues = [...this.registeredValues, value];
},
toggleOption(option) {
const { registeredValues } = this;
const optionIndex = this.sValue.indexOf(option.value);
const value = [...this.sValue];
if (optionIndex === -1) {
@ -63,8 +73,16 @@ export default {
if (!hasProp(this, 'value')) {
this.sValue = value;
}
this.$emit('input', value);
this.$emit('change', value);
const options = this.getOptions();
const val = value
.filter(val => registeredValues.indexOf(val) !== -1)
.sort((a, b) => {
const indexA = options.findIndex(opt => opt.value === a);
const indexB = options.findIndex(opt => opt.value === b);
return indexA - indexB;
});
this.$emit('input', val);
this.$emit('change', val);
},
},
render() {

View File

@ -24,7 +24,7 @@ exports[`renders ./components/checkbox/demo/disabled.md correctly 1`] = `<div><l
exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `
<div>
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Apple"><span class="ant-checkbox-inner"></span></span><span>Apple</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Pear"><span class="ant-checkbox-inner"></span></span><span>Pear</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Orange"><span class="ant-checkbox-inner"></span></span><span>Orange</span></label></div> <br>
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input name="checkboxgroup" type="checkbox" class="ant-checkbox-input" value="Apple"><span class="ant-checkbox-inner"></span></span><span>Apple</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input name="checkboxgroup" type="checkbox" class="ant-checkbox-input" value="Pear"><span class="ant-checkbox-inner"></span></span><span>Pear</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input name="checkboxgroup" type="checkbox" class="ant-checkbox-input" value="Orange"><span class="ant-checkbox-inner"></span></span><span>Orange</span></label></div> <br>
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-group-item"><span class="ant-checkbox ant-checkbox-checked"><input type="checkbox" class="ant-checkbox-input" value="Apple"><span class="ant-checkbox-inner"></span></span><span>Apple</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Pear"><span class="ant-checkbox-inner"></span></span><span>Pear</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Orange"><span class="ant-checkbox-inner"></span></span><span>Orange</span></label></div> <br>
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Apple"><span class="ant-checkbox-inner"></span></span><span>Apple</span></label><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-group-item"><span class="ant-checkbox ant-checkbox-checked"><input type="checkbox" class="ant-checkbox-input" value="Pear"><span class="ant-checkbox-inner"></span></span><span>Pear</span></label><label class="ant-checkbox-wrapper ant-checkbox-group-item"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="Orange"><span class="ant-checkbox-inner"></span></span><span>Orange</span></label></div> <br>
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked ant-checkbox-wrapper-disabled ant-checkbox-group-item"><span class="ant-checkbox ant-checkbox-checked ant-checkbox-disabled"><input type="checkbox" disabled="disabled" class="ant-checkbox-input" value="Apple"><span class="ant-checkbox-inner"></span></span><span><span style="color: red;">Apple</span></span></label><label class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled ant-checkbox-group-item"><span class="ant-checkbox ant-checkbox-disabled"><input type="checkbox" disabled="disabled" class="ant-checkbox-input" value="Pear"><span class="ant-checkbox-inner"></span></span><span>Pear</span></label><label class="ant-checkbox-wrapper ant-checkbox-wrapper-disabled ant-checkbox-group-item"><span class="ant-checkbox ant-checkbox-disabled"><input type="checkbox" disabled="disabled" class="ant-checkbox-input" value="Orange"><span class="ant-checkbox-inner"></span></span><span>Orange</span></label></div>

View File

@ -1,9 +1,12 @@
import { mount } from '@vue/test-utils';
import Checkbox from '..';
import focusTest from '../../../tests/shared/focusTest';
import { resetWarned } from '../../_util/warning';
import mountTest from '../../../tests/shared/mountTest';
describe('Checkbox', () => {
focusTest(Checkbox);
mountTest(Checkbox);
it('responses hover events', () => {
const onMouseEnter = jest.fn();
const onMouseLeave = jest.fn();
@ -21,4 +24,18 @@ describe('Checkbox', () => {
wrapper.trigger('mouseleave');
expect(onMouseLeave).toHaveBeenCalled();
});
it('warning if set `value`', () => {
resetWarned();
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
mount(Checkbox, {
propsData: {
value: 'xxx',
},
});
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antdv: Checkbox] `value` is not validate prop, do you mean `checked`?',
);
errorSpy.mockRestore();
});
});

View File

@ -1,8 +1,10 @@
import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
import Checkbox from '../index';
import mountTest from '../../../tests/shared/mountTest';
describe('CheckboxGroup', () => {
mountTest(Checkbox.Group);
it('should work basically', () => {
const onChange = jest.fn();
const wrapper = mount(
@ -19,22 +21,22 @@ describe('CheckboxGroup', () => {
.findAll('.ant-checkbox-input')
.at(0)
.trigger('change');
expect(onChange).toBeCalledWith(['Apple']);
expect(onChange).toHaveBeenCalledWith(['Apple']);
wrapper
.findAll('.ant-checkbox-input')
.at(1)
.trigger('change');
expect(onChange).toBeCalledWith(['Apple', 'Pear']);
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear']);
wrapper
.findAll('.ant-checkbox-input')
.at(2)
.trigger('change');
expect(onChange).toBeCalledWith(['Apple', 'Pear', 'Orange']);
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear', 'Orange']);
wrapper
.findAll('.ant-checkbox-input')
.at(1)
.trigger('change');
expect(onChange).toBeCalledWith(['Apple', 'Orange']);
expect(onChange).toHaveBeenCalledWith(['Apple', 'Orange']);
});
it('does not trigger onChange callback of both Checkbox and CheckboxGroup when CheckboxGroup is disabled', () => {
@ -89,12 +91,12 @@ describe('CheckboxGroup', () => {
.findAll('.ant-checkbox-input')
.at(0)
.trigger('change');
expect(onChangeGroup).toBeCalledWith(['Apple']);
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
groupWrapper
.findAll('.ant-checkbox-input')
.at(1)
.trigger('change');
expect(onChangeGroup).toBeCalledWith(['Apple']);
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
});
it('passes prefixCls down to checkbox', () => {

View File

@ -11,7 +11,7 @@ Generate a group of checkboxes from an array
```tpl
<template>
<div>
<a-checkbox-group :options="plainOptions" v-model="value" @change="onChange" />
<a-checkbox-group name="checkboxgroup" :options="plainOptions" v-model="value" @change="onChange" />
<br />
<a-checkbox-group :options="plainOptions" :defaultValue="['Apple']" @change="onChange" />
<br />

View File

@ -4,40 +4,41 @@
#### Checkbox
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| autoFocus | get focus when component mounted | boolean | false |
| checked | Specifies whether the checkbox is selected. | boolean | false |
| defaultChecked | Specifies the initial state: whether or not the checkbox is selected. | boolean | false |
| disabled | Disable checkbox | boolean | false |
| indeterminate | indeterminate checked state of checkbox | boolean | false |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| autoFocus | get focus when component mounted | boolean | false | |
| checked | Specifies whether the checkbox is selected. | boolean | false | |
| defaultChecked | Specifies the initial state: whether or not the checkbox is selected. | boolean | false | |
| disabled | Disable checkbox | boolean | false | |
| indeterminate | indeterminate checked state of checkbox | boolean | false | |
#### events
| Events Name | Description | Arguments |
| --- | --- | --- |
| change | The callback function that is triggered when the state changes. | Function(e:Event) |
| Events Name | Description | Arguments | Version |
| --- | --- | --- | --- |
| change | The callback function that is triggered when the state changes. | Function(e:Event) | |
#### Checkbox Group
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| defaultValue | Default selected value | string\[] | \[] |
| disabled | Disable all checkboxes | boolean | false |
| options | Specifies options, you can customize `label` with slot = "label" slot-scope="option" | string\[] \| Array&lt;{ label: string value: string disabled?: boolean, onChange?: function }> | \[] |
| value | Used for setting the currently selected value. | string\[] | \[] |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | Default selected value | string\[] | \[] | |
| disabled | Disable all checkboxes | boolean | false | |
| name | The `name` property of all `input[type="checkbox"]` children | string | - | 1.5.0 |
| options | Specifies options, you can customize `label` with slot = "label" slot-scope="option" | string\[] \| Array&lt;{ label: string value: string disabled?: boolean, onChange?: function }> | \[] | |
| value | Used for setting the currently selected value. | string\[] | \[] | |
#### events
| Events Name | Description | Arguments |
| --- | --- | --- |
| change | The callback function that is triggered when the state changes. | Function(checkedValue) |
| Events Name | Description | Arguments | Version |
| --- | --- | --- | --- |
| change | The callback function that is triggered when the state changes. | Function(checkedValue) | |
### Methods
#### Checkbox
| Name | Description |
| ------- | ------------ |
| blur() | remove focus |
| focus() | get focus |
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | remove focus | |
| focus() | get focus | |

View File

@ -4,40 +4,41 @@
#### Checkbox
| 参数 | 说明 | 类型 | 默认值 |
| -------------- | --------------------------------------- | ------- | ------ |
| autoFocus | 自动获取焦点 | boolean | false |
| checked | 指定当前是否选中 | boolean | false |
| defaultChecked | 初始是否选中 | boolean | false |
| disabled | 失效状态 | boolean | false |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| -------------- | --------------------------------------- | ------- | ------ | ---- |
| autoFocus | 自动获取焦点 | boolean | false | |
| checked | 指定当前是否选中 | boolean | false | |
| defaultChecked | 初始是否选中 | boolean | false | |
| disabled | 失效状态 | boolean | false | |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | |
#### 事件
| 事件名称 | 说明 | 回调参数 |
| -------- | -------------- | ----------------- |
| change | 变化时回调函数 | Function(e:Event) | - |
| 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | -------------- | ----------------- | ---- |
| change | 变化时回调函数 | Function(e:Event) | - | |
#### Checkbox Group
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| defaultValue | 默认选中的选项 | string\[] | \[] |
| disabled | 整组失效 | boolean | false |
| options | 指定可选项,可以通过 slot="label" slot-scope="option" 定制`label` | string\[] \| Array&lt;{ label: string value: string disabled?: boolean, onChange?: function }> | \[] |
| value | 指定选中的选项 | string\[] | \[] |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认选中的选项 | string\[] | \[] | |
| disabled | 整组失效 | boolean | false | |
| name | CheckboxGroup 下所有 `input[type="checkbox"]``name` 属性 | string | - | 1.5.0 |
| options | 指定可选项,可以通过 slot="label" slot-scope="option" 定制`label` | string\[] \| Array&lt;{ label: string value: string disabled?: boolean, onChange?: function }> | \[] | |
| value | 指定选中的选项 | string\[] | \[] | |
#### 事件
| 事件名称 | 说明 | 回调参数 |
| -------- | -------------- | ---------------------- |
| change | 变化时回调函数 | Function(checkedValue) | - |
| 事件名称 | 说明 | 回调参数 | 版本 |
| -------- | -------------- | ---------------------- | ---- |
| change | 变化时回调函数 | Function(checkedValue) | - | |
### 方法
#### Checkbox
| 名称 | 描述 |
| ------- | -------- |
| blur() | 移除焦点 |
| focus() | 获取焦点 |
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |

View File

@ -193,7 +193,7 @@ const Descriptions = {
});
});
},
beforeDestory() {
beforeDestroy() {
ResponsiveObserve.unsubscribe(this.token);
},
render() {

View File

@ -31,4 +31,5 @@ export declare class CheckboxGroup extends AntdComponent {
* @type string[]
*/
value: string[];
name?: string;
}