diff --git a/src/checkbox/Checker.js b/src/checkbox/Checker.js new file mode 100644 index 000000000..452009783 --- /dev/null +++ b/src/checkbox/Checker.js @@ -0,0 +1,147 @@ +import { addUnit } from '../utils'; +import Icon from '../icon'; + +export const checkerProps = { + name: null, + disabled: Boolean, + iconSize: [Number, String], + modelValue: null, + checkedColor: String, + labelPosition: String, + labelDisabled: Boolean, + shape: { + type: String, + default: 'round', + }, + bindGroup: { + type: Boolean, + default: true, + }, +}; + +export default { + props: { + ...checkerProps, + bem: Function, + role: String, + parent: Object, + checked: Boolean, + }, + + emits: ['click', 'toggle'], + + computed: { + isDisabled() { + return (this.parent && this.parent.disabled) || this.disabled; + }, + + direction() { + return (this.parent && this.parent.direction) || null; + }, + + iconStyle() { + const checkedColor = + this.checkedColor || (this.parent && this.parent.checkedColor); + + if (checkedColor && this.checked && !this.isDisabled) { + return { + borderColor: checkedColor, + backgroundColor: checkedColor, + }; + } + }, + + tabindex() { + return this.isDisabled ? -1 : 0; + }, + + disableBindRelation() { + return !this.bindGroup; + }, + }, + + methods: { + onClick(event) { + const { target } = event; + const { icon } = this.$refs; + const iconClicked = icon === target || icon.contains(target); + + if (!this.isDisabled && (iconClicked || !this.labelDisabled)) { + this.$emit('toggle'); + + // wait for toggle method to complete + // so we can get the changed value in the click event listener + setTimeout(() => { + this.$emit('click', event); + }); + } else { + this.$emit('click', event); + } + }, + + genIcon() { + const { checked } = this; + const iconSize = this.iconSize || (this.parent && this.parent.iconSize); + + return ( +
+ {this.$slots.icon ? ( + this.$slots.icon({ checked }) + ) : ( + + )} +
+ ); + }, + + genLabel() { + if (this.$slots.default) { + return ( + + {this.$slots.default()} + + ); + } + }, + }, + + render() { + const Children = [this.genIcon()]; + + if (this.labelPosition === 'left') { + Children.unshift(this.genLabel()); + } else { + Children.push(this.genLabel()); + } + + return ( +
+ {Children} +
+ ); + }, +}; diff --git a/src/checkbox/index.js b/src/checkbox/index.js index b74f94a6b..7ff588965 100644 --- a/src/checkbox/index.js +++ b/src/checkbox/index.js @@ -1,66 +1,18 @@ -import { addUnit, createNamespace } from '../utils'; +import { createNamespace, pick } from '../utils'; import { FieldMixin } from '../mixins/field'; import { ChildrenMixin } from '../mixins/relation'; -import Icon from '../icon'; +import Checker, { checkerProps } from './Checker'; const [createComponent, bem] = createNamespace('checkbox'); export default createComponent({ mixins: [FieldMixin, ChildrenMixin('vanCheckbox')], - props: { - name: null, - disabled: Boolean, - iconSize: [Number, String], - modelValue: null, - checkedColor: String, - labelPosition: String, - labelDisabled: Boolean, - shape: { - type: String, - default: 'round', - }, - bindGroup: { - type: Boolean, - default: true, - }, - }, + props: checkerProps, - emits: ['click', 'change', 'update:modelValue'], + emits: ['change', 'update:modelValue'], computed: { - disableBindRelation() { - return !this.bindGroup; - }, - - isDisabled() { - return (this.parent && this.parent.disabled) || this.disabled; - }, - - direction() { - return (this.parent && this.parent.direction) || null; - }, - - iconStyle() { - const checkedColor = - this.checkedColor || (this.parent && this.parent.checkedColor); - - if (checkedColor && this.checked && !this.isDisabled) { - return { - borderColor: checkedColor, - backgroundColor: checkedColor, - }; - } - }, - - tabindex() { - if (this.isDisabled) { - return -1; - } - - return 0; - }, - checked: { get() { if (this.parent) { @@ -86,61 +38,6 @@ export default createComponent({ }, methods: { - onClick(event) { - const { target } = event; - const { icon } = this.$refs; - const iconClicked = icon === target || icon.contains(target); - - if (!this.isDisabled && (iconClicked || !this.labelDisabled)) { - this.toggle(); - - // wait for toggle method to complete - // so we can get the changed value in the click event listener - setTimeout(() => { - this.$emit('click', event); - }); - } else { - this.$emit('click', event); - } - }, - - genIcon() { - const { checked } = this; - const iconSize = this.iconSize || (this.parent && this.parent.iconSize); - - return ( -
- {this.$slots.icon ? ( - this.$slots.icon({ checked }) - ) : ( - - )} -
- ); - }, - - genLabel() { - if (this.$slots.default) { - return ( - - {this.$slots.default()} - - ); - } - }, - // @exposed-api toggle(checked = !this.checked) { // When toggle method is called multiple times at the same time, @@ -179,30 +76,16 @@ export default createComponent({ }, render() { - const Children = [this.genIcon()]; - - if (this.labelPosition === 'left') { - Children.unshift(this.genLabel()); - } else { - Children.push(this.genLabel()); - } - return ( - + parent={this.parent} + checked={this.checked} + onToggle={this.toggle} + {...this.$props} + /> ); }, }); diff --git a/src/radio/index.js b/src/radio/index.js index 1ceba1582..543f79326 100644 --- a/src/radio/index.js +++ b/src/radio/index.js @@ -1,57 +1,17 @@ -import { addUnit, createNamespace } from '../utils'; +import { pick, createNamespace } from '../utils'; import { ChildrenMixin } from '../mixins/relation'; -import Icon from '../icon'; +import Checker, { checkerProps } from '../checkbox/Checker'; const [createComponent, bem] = createNamespace('radio'); export default createComponent({ mixins: [ChildrenMixin('vanRadio')], - props: { - name: null, - disabled: Boolean, - iconSize: [Number, String], - modelValue: null, - checkedColor: String, - labelPosition: String, - labelDisabled: Boolean, - shape: { - type: String, - default: 'round', - }, - }, + props: checkerProps, - emits: ['click', 'update:modelValue'], + emits: ['update:modelValue'], computed: { - isDisabled() { - return (this.parent && this.parent.disabled) || this.disabled; - }, - - direction() { - return (this.parent && this.parent.direction) || null; - }, - - iconStyle() { - const checkedColor = - this.checkedColor || (this.parent && this.parent.checkedColor); - - if (checkedColor && this.checked && !this.isDisabled) { - return { - borderColor: checkedColor, - backgroundColor: checkedColor, - }; - } - }, - - tabindex() { - if (this.isDisabled || !this.checked) { - return -1; - } - - return 0; - }, - currentValue: { get() { return this.parent ? this.parent.modelValue : this.modelValue; @@ -71,88 +31,19 @@ export default createComponent({ toggle() { this.currentValue = this.name; }, - - onClick(event) { - const { target } = event; - const { icon } = this.$refs; - const iconClicked = icon === target || icon.contains(target); - - if (!this.isDisabled && (iconClicked || !this.labelDisabled)) { - this.toggle(); - - // wait for toggle method to complete - // so we can get the changed value in the click event listener - setTimeout(() => { - this.$emit('click', event); - }); - } else { - this.$emit('click', event); - } - }, - - genIcon() { - const { checked } = this; - const iconSize = this.iconSize || (this.parent && this.parent.iconSize); - - return ( -
- {this.$slots.icon ? ( - this.$slots.icon({ checked }) - ) : ( - - )} -
- ); - }, - - genLabel() { - if (this.$slots.default) { - return ( - - {this.$slots.default()} - - ); - } - }, }, render() { - const Children = [this.genIcon()]; - - if (this.labelPosition === 'left') { - Children.unshift(this.genLabel()); - } else { - Children.push(this.genLabel()); - } - return ( - + parent={this.parent} + checked={this.checked} + onToggle={this.toggle} + {...this.$props} + /> ); }, });