feat(checkbox): update checkbox (#2376)

* feat(checkbox): update checkbox

* feat(checkbox): code review

* feat(checkbox): code review

* feat(checkbox): fix lint
pull/2468/head
逆寒 2020-06-20 22:22:00 +08:00 committed by GitHub
parent 0413bcf58a
commit c2a59f7f8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 77 additions and 85 deletions

View File

@ -82,8 +82,7 @@ export const withDefault = function(type) {
return this; return this;
} }
this.default = this.default =
isArray(def) || isArray(def) || isPlainObject(def)
isPlainObject(def)
? function() { ? function() {
return def; return def;
} }

View File

@ -1,18 +1,15 @@
import { inject } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import classNames from 'classnames'; import classNames from 'classnames';
import VcCheckbox from '../vc-checkbox'; import VcCheckbox from '../vc-checkbox';
import hasProp, { getOptionProps, getAttrs, getListeners } from '../_util/props-util'; import hasProp, { getOptionProps } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning'; import warning from '../_util/warning';
function noop() {}
export default { export default {
name: 'ACheckbox', name: 'ACheckbox',
inheritAttrs: false, inheritAttrs: false,
__ANT_CHECKBOX: true, __ANT_CHECKBOX: true,
model: {
prop: 'checked',
},
props: { props: {
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
defaultChecked: PropTypes.bool, defaultChecked: PropTypes.bool,
@ -26,10 +23,14 @@ export default {
type: PropTypes.string.def('checkbox'), type: PropTypes.string.def('checkbox'),
autoFocus: PropTypes.bool, autoFocus: PropTypes.bool,
}, },
inject: {
configProvider: { default: () => ConfigConsumerProps }, setup() {
checkboxGroupContext: { default: () => undefined }, return {
configProvider: inject('configProvider', ConfigConsumerProps),
checkboxGroupContext: inject('checkboxGroupContext', undefined),
};
}, },
watch: { watch: {
value(value, prevValue) { value(value, prevValue) {
this.$nextTick(() => { this.$nextTick(() => {
@ -41,6 +42,7 @@ export default {
}); });
}, },
}, },
mounted() { mounted() {
const { value, checkboxGroupContext: checkboxGroup = {} } = this; const { value, checkboxGroupContext: checkboxGroup = {} } = this;
if (checkboxGroup.registerValue) { if (checkboxGroup.registerValue) {
@ -74,41 +76,48 @@ export default {
}, },
render() { render() {
const { checkboxGroupContext: checkboxGroup, $slots } = this;
const props = getOptionProps(this); const props = getOptionProps(this);
const children = $slots.default; const { checkboxGroupContext: checkboxGroup, $slots, $attrs } = this;
const { mouseenter = noop, mouseleave = noop, input, ...restListeners } = getListeners(this); const children = $slots.default && $slots.default();
const { prefixCls: customizePrefixCls, indeterminate, ...restProps } = props; const { indeterminate, prefixCls: customizePrefixCls, ...restProps } = props;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('checkbox', customizePrefixCls); const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
const { onMouseenter, onMouseleave, onInput, class: className, style, ...restAttrs } = $attrs;
const checkboxProps = { const checkboxProps = {
props: { ...restProps, prefixCls }, ...restProps,
on: restListeners, prefixCls,
attrs: getAttrs(this), ...restAttrs,
}; };
if (checkboxGroup) { if (checkboxGroup) {
checkboxProps.on.change = (...args) => { checkboxProps.onChange = (...args) => {
this.$emit('change', ...args); this.$emit('change', ...args);
checkboxGroup.toggleOption({ label: children, value: props.value }); checkboxGroup.toggleOption({ label: children, value: props.value });
}; };
checkboxProps.props.name = checkboxGroup.name; checkboxProps.name = checkboxGroup.name;
checkboxProps.props.checked = checkboxGroup.sValue.indexOf(props.value) !== -1; checkboxProps.checked = checkboxGroup.sValue.indexOf(props.value) !== -1;
checkboxProps.props.disabled = props.disabled || checkboxGroup.disabled; checkboxProps.disabled = props.disabled || checkboxGroup.disabled;
checkboxProps.props.indeterminate = indeterminate; checkboxProps.indeterminate = indeterminate;
} else { } else {
checkboxProps.on.change = this.handleChange; checkboxProps.onChange = this.handleChange;
} }
const classString = classNames({ const classString = classNames(
[`${prefixCls}-wrapper`]: true, {
[`${prefixCls}-wrapper-checked`]: checkboxProps.props.checked, [`${prefixCls}-wrapper`]: true,
[`${prefixCls}-wrapper-disabled`]: checkboxProps.props.disabled, [`${prefixCls}-wrapper-checked`]: checkboxProps.checked,
}); [`${prefixCls}-wrapper-disabled`]: checkboxProps.disabled,
},
className,
);
const checkboxClass = classNames({ const checkboxClass = classNames({
[`${prefixCls}-indeterminate`]: indeterminate, [`${prefixCls}-indeterminate`]: indeterminate,
}); });
return ( return (
<label class={classString} onMouseenter={mouseenter} onMouseleave={mouseleave}> <label
class={classString}
style={style}
onMouseenter={onMouseenter}
onMouseenter={onMouseleave}
>
<VcCheckbox {...checkboxProps} class={checkboxClass} ref="vcCheckbox" /> <VcCheckbox {...checkboxProps} class={checkboxClass} ref="vcCheckbox" />
{children !== undefined && <span>{children}</span>} {children !== undefined && <span>{children}</span>}
</label> </label>

View File

@ -1,3 +1,4 @@
import { inject, provide } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import Checkbox from './Checkbox'; import Checkbox from './Checkbox';
import hasProp from '../_util/props-util'; import hasProp from '../_util/props-util';
@ -17,14 +18,7 @@ export default {
options: PropTypes.array.def([]), options: PropTypes.array.def([]),
disabled: PropTypes.bool, disabled: PropTypes.bool,
}, },
provide() {
return {
checkboxGroupContext: this,
};
},
inject: {
configProvider: { default: () => ConfigConsumerProps },
},
data() { data() {
const { value, defaultValue } = this; const { value, defaultValue } = this;
return { return {
@ -37,9 +31,13 @@ export default {
this.sValue = val || []; this.sValue = val || [];
}, },
}, },
created() {
(this.configProvider = inject('configProvider', ConfigConsumerProps)),
provide('checkboxGroupContext', this);
},
methods: { methods: {
getOptions() { getOptions() {
const { options, $scopedSlots } = this; const { options, $slots } = this;
return options.map(option => { return options.map(option => {
if (typeof option === 'string') { if (typeof option === 'string') {
return { return {
@ -48,8 +46,8 @@ export default {
}; };
} }
let label = option.label; let label = option.label;
if (label === undefined && $scopedSlots.label) { if (label === undefined && $slots.label) {
label = $scopedSlots.label(option); label = $slots.label(option);
} }
return { ...option, label }; return { ...option, label };
}); });
@ -90,7 +88,6 @@ export default {
const { prefixCls: customizePrefixCls, options } = props; const { prefixCls: customizePrefixCls, options } = props;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('checkbox', customizePrefixCls); const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
let children = $slots.default; let children = $slots.default;
const groupPrefixCls = `${prefixCls}-group`; const groupPrefixCls = `${prefixCls}-group`;
if (options && options.length > 0) { if (options && options.length > 0) {

View File

@ -1,14 +1,12 @@
import Checkbox from './Checkbox'; import Checkbox from './Checkbox';
import CheckboxGroup from './Group'; import CheckboxGroup from './Group';
import Base from '../base';
Checkbox.Group = CheckboxGroup; Checkbox.Group = CheckboxGroup;
/* istanbul ignore next */ /* istanbul ignore next */
Checkbox.install = function(Vue) { Checkbox.install = function(app) {
Vue.use(Base); app.component(Checkbox.name, Checkbox);
Vue.component(Checkbox.name, Checkbox); app.component(CheckboxGroup.name, CheckboxGroup);
Vue.component(CheckboxGroup.name, CheckboxGroup);
}; };
export default Checkbox; export default Checkbox;

View File

@ -82,13 +82,9 @@ export default {
const prefixCls = getPrefixCls('radio', customizePrefixCls); const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`; const groupPrefixCls = `${prefixCls}-group`;
const classString = classNames( const classString = classNames(groupPrefixCls, `${groupPrefixCls}-${buttonStyle}`, {
groupPrefixCls, [`${groupPrefixCls}-${props.size}`]: props.size,
`${groupPrefixCls}-${buttonStyle}`, });
{
[`${groupPrefixCls}-${props.size}`]: props.size,
},
);
let children = filterEmpty(getSlot(this)); let children = filterEmpty(getSlot(this));
@ -122,12 +118,6 @@ export default {
}); });
} }
return ( return <div class={classString}>{children}</div>;
<div
class={classString}
>
{children}
</div>
);
}, },
}; };

View File

@ -69,16 +69,14 @@ export default {
} else { } else {
radioProps.onChange = this.handleChange; radioProps.onChange = this.handleChange;
} }
const wrapperClassString = classNames( { const wrapperClassString = classNames({
[`${prefixCls}-wrapper`]: true, [`${prefixCls}-wrapper`]: true,
[`${prefixCls}-wrapper-checked`]: radioProps.checked, [`${prefixCls}-wrapper-checked`]: radioProps.checked,
[`${prefixCls}-wrapper-disabled`]: radioProps.disabled, [`${prefixCls}-wrapper-disabled`]: radioProps.disabled,
}); });
return ( return (
<label <label class={wrapperClassString}>
class={wrapperClassString}
>
<VcCheckbox {...radioProps} ref="vcCheckbox" /> <VcCheckbox {...radioProps} ref="vcCheckbox" />
{$slots.default && <span>{$slots.default()}</span>} {$slots.default && <span>{$slots.default()}</span>}
</label> </label>

View File

@ -158,7 +158,7 @@ export default {
sPagination: this.getDefaultPagination(this.$props), sPagination: this.getDefaultPagination(this.$props),
pivot: undefined, pivot: undefined,
sComponents: createComponents(this.components), sComponents: createComponents(this.components),
filterDataCnt: 0 filterDataCnt: 0,
}; };
}, },
watch: { watch: {

View File

@ -108,6 +108,7 @@ export default {
value, value,
...others ...others
} = getOptionProps(this); } = getOptionProps(this);
const { class: className } = this.$attrs;
const globalProps = Object.keys({ ...others, ...this.$attrs }).reduce((prev, key) => { const globalProps = Object.keys({ ...others, ...this.$attrs }).reduce((prev, key) => {
if (key.substr(0, 5) === 'aria-' || key.substr(0, 5) === 'data-' || key === 'role') { if (key.substr(0, 5) === 'aria-' || key.substr(0, 5) === 'data-' || key === 'role') {
prev[key] = others[key]; prev[key] = others[key];
@ -116,31 +117,29 @@ export default {
}, {}); }, {});
const { sChecked } = this; const { sChecked } = this;
const classString = classNames(prefixCls, { const classString = classNames(prefixCls, className, {
[`${prefixCls}-checked`]: sChecked, [`${prefixCls}-checked`]: sChecked,
[`${prefixCls}-disabled`]: disabled, [`${prefixCls}-disabled`]: disabled,
}); });
const inputProps = {
name,
id,
type,
readOnly,
disabled,
tabIndex,
class: `${prefixCls}-input`,
checked: !!sChecked,
autoFocus,
value,
...globalProps,
onChange: this.handleChange,
onClick: this.onClick,
};
return ( return (
<span class={classString}> <span class={classString}>
<input <input ref="input" {...inputProps} />
name={name}
id={id}
type={type}
readOnly={readOnly}
disabled={disabled}
tabIndex={tabIndex}
class={`${prefixCls}-input`}
checked={!!sChecked}
autoFocus={autoFocus}
ref="input"
value={value}
onChange={this.handleChange}
onClick={this.onClick}
onFocus={onFocus}
onBlur={onBlur}
{...globalProps}
/>
<span class={`${prefixCls}-inner`} /> <span class={`${prefixCls}-inner`} />
</span> </span>
); );

View File

@ -18,6 +18,7 @@ import PageHeader from 'ant-design-vue/page-header';
import Skeleton from 'ant-design-vue/skeleton'; import Skeleton from 'ant-design-vue/skeleton';
import Empty from 'ant-design-vue/empty'; import Empty from 'ant-design-vue/empty';
import Timeline from 'ant-design-vue/timeline'; import Timeline from 'ant-design-vue/timeline';
import Checkbox from 'ant-design-vue/checkbox';
import Col from 'ant-design-vue/col'; import Col from 'ant-design-vue/col';
import Row from 'ant-design-vue/row'; import Row from 'ant-design-vue/row';
import Tooltip from 'ant-design-vue/tooltip'; import Tooltip from 'ant-design-vue/tooltip';
@ -63,6 +64,7 @@ app
.use(Skeleton) .use(Skeleton)
.use(Spin) .use(Spin)
.use(Empty) .use(Empty)
.use(Checkbox)
.use(Timeline) .use(Timeline)
.use(Col) .use(Col)
.use(Row) .use(Row)