diff --git a/src/checkbox/Checker.js b/src/checkbox/Checker.js
deleted file mode 100644
index 452009783..000000000
--- a/src/checkbox/Checker.js
+++ /dev/null
@@ -1,147 +0,0 @@
-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/Checker.tsx b/src/checkbox/Checker.tsx
new file mode 100644
index 000000000..cf47bc48e
--- /dev/null
+++ b/src/checkbox/Checker.tsx
@@ -0,0 +1,136 @@
+import { ref, computed, defineComponent } from 'vue';
+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',
+ },
+};
+
+export default defineComponent({
+ props: {
+ ...checkerProps,
+ role: String,
+ parent: Object,
+ checked: Boolean,
+ bem: {
+ type: Function,
+ required: true,
+ },
+ },
+
+ emits: ['click', 'toggle'],
+
+ setup(props, { emit, slots }) {
+ const iconRef = ref();
+
+ const disabled = computed(
+ () => (props.parent && props.parent.disabled) || props.disabled
+ );
+
+ const direction = computed(
+ () => (props.parent && props.parent.direction) || null
+ );
+
+ const iconStyle = computed(() => {
+ const checkedColor =
+ props.checkedColor || (props.parent && props.parent.checkedColor);
+
+ if (checkedColor && props.checked && !disabled.value) {
+ return {
+ borderColor: checkedColor,
+ backgroundColor: checkedColor,
+ };
+ }
+ });
+
+ const onClick = (event: MouseEvent) => {
+ const { target } = event;
+ const icon = iconRef.value;
+ const iconClicked = icon === target || icon.contains(target);
+
+ if (!disabled.value && (iconClicked || !props.labelDisabled)) {
+ emit('toggle');
+
+ // wait for toggle method to complete
+ // so we can get the changed value in the click event listener
+ setTimeout(() => {
+ emit('click', event);
+ });
+ } else {
+ emit('click', event);
+ }
+ };
+
+ const renderIcon = () => {
+ const { bem, shape, parent, checked } = props;
+ const iconSize = props.iconSize || (parent && parent.iconSize);
+
+ return (
+
+ {slots.icon ? (
+ slots.icon({ checked })
+ ) : (
+
+ )}
+
+ );
+ };
+
+ const renderLabel = () => {
+ if (slots.default) {
+ return (
+
+ {slots.default()}
+
+ );
+ }
+ };
+
+ return () => {
+ const nodes: (JSX.Element | undefined)[] = [renderIcon()];
+
+ if (props.labelPosition === 'left') {
+ nodes.unshift(renderLabel());
+ } else {
+ nodes.push(renderLabel());
+ }
+
+ return (
+
+ {nodes}
+
+ );
+ };
+ },
+});
diff --git a/src/checkbox/index.js b/src/checkbox/index.js
index 7ff588965..9b6c96659 100644
--- a/src/checkbox/index.js
+++ b/src/checkbox/index.js
@@ -8,7 +8,13 @@ const [createComponent, bem] = createNamespace('checkbox');
export default createComponent({
mixins: [FieldMixin, ChildrenMixin('vanCheckbox')],
- props: checkerProps,
+ props: {
+ ...checkerProps,
+ bindGroup: {
+ type: Boolean,
+ default: true,
+ },
+ },
emits: ['change', 'update:modelValue'],