diff --git a/src/checkbox/index.js b/src/checkbox/index.js index 880e1e286..b74f94a6b 100644 --- a/src/checkbox/index.js +++ b/src/checkbox/index.js @@ -1,22 +1,66 @@ -import { createNamespace } from '../utils'; +import { addUnit, createNamespace } from '../utils'; import { FieldMixin } from '../mixins/field'; -import { CheckboxMixin } from '../mixins/checkbox'; +import { ChildrenMixin } from '../mixins/relation'; +import Icon from '../icon'; const [createComponent, bem] = createNamespace('checkbox'); export default createComponent({ - mixins: [ - FieldMixin, - CheckboxMixin({ - bem, - role: 'checkbox', - parent: 'vanCheckbox', - }), - ], + 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, + }, + }, emits: ['click', '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) { @@ -42,6 +86,61 @@ 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, @@ -78,4 +177,32 @@ export default createComponent({ } }, }, + + render() { + const Children = [this.genIcon()]; + + if (this.labelPosition === 'left') { + Children.unshift(this.genLabel()); + } else { + Children.push(this.genLabel()); + } + + return ( + + ); + }, }); diff --git a/src/mixins/checkbox.js b/src/mixins/checkbox.js deleted file mode 100644 index 1729cbf91..000000000 --- a/src/mixins/checkbox.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Common part of Checkbox & Radio - */ -import Icon from '../icon'; -import { ChildrenMixin } from './relation'; -import { addUnit } from '../utils'; - -export const CheckboxMixin = ({ parent, bem, role }) => ({ - mixins: [ChildrenMixin(parent)], - - 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, - }, - }, - - 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 || (role === 'radio' && !this.checked)) { - return -1; - } - - return 0; - }, - }, - - 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()} - - ); - } - }, - }, - - render() { - const Children = [this.genIcon()]; - - if (this.labelPosition === 'left') { - Children.unshift(this.genLabel()); - } else { - Children.push(this.genLabel()); - } - - return ( -
- {Children} -
- ); - }, -}); diff --git a/src/radio/index.js b/src/radio/index.js index ae06f3565..1ceba1582 100644 --- a/src/radio/index.js +++ b/src/radio/index.js @@ -1,20 +1,57 @@ -import { createNamespace } from '../utils'; -import { CheckboxMixin } from '../mixins/checkbox'; +import { addUnit, createNamespace } from '../utils'; +import { ChildrenMixin } from '../mixins/relation'; +import Icon from '../icon'; const [createComponent, bem] = createNamespace('radio'); export default createComponent({ - mixins: [ - CheckboxMixin({ - bem, - role: 'radio', - parent: 'vanRadio', - }), - ], + mixins: [ChildrenMixin('vanRadio')], + + props: { + name: null, + disabled: Boolean, + iconSize: [Number, String], + modelValue: null, + checkedColor: String, + labelPosition: String, + labelDisabled: Boolean, + shape: { + type: String, + default: 'round', + }, + }, emits: ['click', '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; @@ -34,5 +71,88 @@ 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 ( + + ); }, });