mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
refactor: remove checkbox mixin
This commit is contained in:
parent
fc50e26416
commit
f7397e399d
@ -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 (
|
||||
<div
|
||||
ref="icon"
|
||||
class={bem('icon', [
|
||||
this.shape,
|
||||
{ disabled: this.isDisabled, checked },
|
||||
])}
|
||||
style={{ fontSize: addUnit(iconSize) }}
|
||||
>
|
||||
{this.$slots.icon ? (
|
||||
this.$slots.icon({ checked })
|
||||
) : (
|
||||
<Icon name="success" style={this.iconStyle} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
genLabel() {
|
||||
if (this.$slots.default) {
|
||||
return (
|
||||
<span
|
||||
class={bem('label', [
|
||||
this.labelPosition,
|
||||
{ disabled: this.isDisabled },
|
||||
])}
|
||||
>
|
||||
{this.$slots.default()}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// @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 (
|
||||
<div
|
||||
role="checkbox"
|
||||
class={bem([
|
||||
{
|
||||
disabled: this.isDisabled,
|
||||
'label-disabled': this.labelDisabled,
|
||||
},
|
||||
this.direction,
|
||||
])}
|
||||
tabindex={this.tabindex}
|
||||
aria-checked={String(this.checked)}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
{Children}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@ -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 (
|
||||
<div
|
||||
ref="icon"
|
||||
class={bem('icon', [
|
||||
this.shape,
|
||||
{ disabled: this.isDisabled, checked },
|
||||
])}
|
||||
style={{ fontSize: addUnit(iconSize) }}
|
||||
>
|
||||
{this.$slots.icon ? (
|
||||
this.$slots.icon({ checked })
|
||||
) : (
|
||||
<Icon name="success" style={this.iconStyle} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
genLabel() {
|
||||
if (this.$slots.default) {
|
||||
return (
|
||||
<span
|
||||
class={bem('label', [
|
||||
this.labelPosition,
|
||||
{ disabled: this.isDisabled },
|
||||
])}
|
||||
>
|
||||
{this.$slots.default()}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const Children = [this.genIcon()];
|
||||
|
||||
if (this.labelPosition === 'left') {
|
||||
Children.unshift(this.genLabel());
|
||||
} else {
|
||||
Children.push(this.genLabel());
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role={role}
|
||||
class={bem([
|
||||
{
|
||||
disabled: this.isDisabled,
|
||||
'label-disabled': this.labelDisabled,
|
||||
},
|
||||
this.direction,
|
||||
])}
|
||||
tabindex={this.tabindex}
|
||||
aria-checked={String(this.checked)}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
{Children}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
@ -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 (
|
||||
<div
|
||||
ref="icon"
|
||||
class={bem('icon', [
|
||||
this.shape,
|
||||
{ disabled: this.isDisabled, checked },
|
||||
])}
|
||||
style={{ fontSize: addUnit(iconSize) }}
|
||||
>
|
||||
{this.$slots.icon ? (
|
||||
this.$slots.icon({ checked })
|
||||
) : (
|
||||
<Icon name="success" style={this.iconStyle} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
genLabel() {
|
||||
if (this.$slots.default) {
|
||||
return (
|
||||
<span
|
||||
class={bem('label', [
|
||||
this.labelPosition,
|
||||
{ disabled: this.isDisabled },
|
||||
])}
|
||||
>
|
||||
{this.$slots.default()}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const Children = [this.genIcon()];
|
||||
|
||||
if (this.labelPosition === 'left') {
|
||||
Children.unshift(this.genLabel());
|
||||
} else {
|
||||
Children.push(this.genLabel());
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="radio"
|
||||
class={bem([
|
||||
{
|
||||
disabled: this.isDisabled,
|
||||
'label-disabled': this.labelDisabled,
|
||||
},
|
||||
this.direction,
|
||||
])}
|
||||
tabindex={this.tabindex}
|
||||
aria-checked={String(this.checked)}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
{Children}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user