From 4f3823eeda2df94a8b8cb5f3607a263636c5449e Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Mon, 27 Dec 2021 21:53:31 +0800 Subject: [PATCH] refactor: vc-checkbox --- components/checkbox/Checkbox.tsx | 2 +- components/checkbox/demo/disabled.vue | 2 +- components/radio/Radio.tsx | 2 +- components/vc-checkbox/Checkbox.tsx | 157 +++++++++++++++++++++++ components/vc-checkbox/assets/index.less | 155 ---------------------- components/vc-checkbox/index.js | 2 - components/vc-checkbox/src/Checkbox.jsx | 143 --------------------- components/vc-checkbox/src/index.js | 3 - 8 files changed, 160 insertions(+), 306 deletions(-) create mode 100644 components/vc-checkbox/Checkbox.tsx delete mode 100644 components/vc-checkbox/assets/index.less delete mode 100644 components/vc-checkbox/index.js delete mode 100644 components/vc-checkbox/src/Checkbox.jsx delete mode 100644 components/vc-checkbox/src/index.js diff --git a/components/checkbox/Checkbox.tsx b/components/checkbox/Checkbox.tsx index 84e96830e..c1a9aea99 100644 --- a/components/checkbox/Checkbox.tsx +++ b/components/checkbox/Checkbox.tsx @@ -2,7 +2,7 @@ import type { ExtractPropTypes } from 'vue'; import { defineComponent, inject, nextTick } from 'vue'; import PropTypes from '../_util/vue-types'; import classNames from '../_util/classNames'; -import VcCheckbox from '../vc-checkbox'; +import VcCheckbox from '../vc-checkbox/Checkbox'; import hasProp, { getOptionProps, getSlot } from '../_util/props-util'; import { defaultConfigProvider } from '../config-provider'; import warning from '../_util/warning'; diff --git a/components/checkbox/demo/disabled.vue b/components/checkbox/demo/disabled.vue index 23ee57d15..6586d9f36 100644 --- a/components/checkbox/demo/disabled.vue +++ b/components/checkbox/demo/disabled.vue @@ -27,7 +27,7 @@ export default defineComponent({ setup() { return { checked1: ref(false), - checked2: ref(false), + checked2: ref(true), }; }, }); diff --git a/components/radio/Radio.tsx b/components/radio/Radio.tsx index 74834e06f..6eeaf1064 100644 --- a/components/radio/Radio.tsx +++ b/components/radio/Radio.tsx @@ -1,7 +1,7 @@ import type { ExtractPropTypes } from 'vue'; import { defineComponent, inject, ref } from 'vue'; import PropTypes from '../_util/vue-types'; -import VcCheckbox from '../vc-checkbox'; +import VcCheckbox from '../vc-checkbox/Checkbox'; import classNames from '../_util/classNames'; import useConfigInject from '../_util/hooks/useConfigInject'; import type { RadioChangeEvent, RadioGroupContext } from './interface'; diff --git a/components/vc-checkbox/Checkbox.tsx b/components/vc-checkbox/Checkbox.tsx new file mode 100644 index 000000000..be469c537 --- /dev/null +++ b/components/vc-checkbox/Checkbox.tsx @@ -0,0 +1,157 @@ +// based on rc-checkbox 2.3.2 +import type { HTMLAttributes } from 'vue'; +import { nextTick, defineComponent, ref, watch, onMounted } from 'vue'; +import classNames from '../_util/classNames'; +import PropTypes from '../_util/vue-types'; +import { initDefaultProps } from '../_util/props-util'; + +const checkboxProps = { + prefixCls: String, + name: String, + id: String, + type: String, + defaultChecked: { type: [Boolean, Number], default: undefined }, + checked: { type: [Boolean, Number], default: undefined }, + disabled: Boolean, + tabindex: { type: [Number, String] }, + readonly: Boolean, + autofocus: Boolean, + value: PropTypes.any, + required: Boolean, +}; +export default defineComponent({ + name: 'Checkbox', + inheritAttrs: false, + props: initDefaultProps(checkboxProps, { + prefixCls: 'rc-checkbox', + type: 'checkbox', + defaultChecked: false, + }), + emits: ['click', 'focus', 'blur', 'change', 'keydown', 'keypress', 'keyup'], + setup(props, { attrs, emit, expose }) { + const checked = ref(props.checked === undefined ? props.defaultChecked : props.checked); + const inputRef = ref(); + watch( + () => props.checked, + () => { + checked.value = props.checked; + }, + ); + onMounted(() => { + nextTick(() => { + if (process.env.NODE_ENV === 'test') { + if (props.autofocus) { + inputRef.value?.focus(); + } + } + }); + }); + expose({ + focus() { + inputRef.value?.focus(); + }, + + blur() { + inputRef.value?.blur(); + }, + }); + const eventShiftKey = ref(); + const handleChange = e => { + if (props.disabled) { + return; + } + if (props.checked === undefined) { + checked.value = e.target.checked; + } + e.shiftKey = eventShiftKey.value; + const eventObj = { + target: { + ...props, + checked: e.target.checked, + }, + stopPropagation() { + e.stopPropagation(); + }, + preventDefault() { + e.preventDefault(); + }, + nativeEvent: e, + }; + + // fix https://github.com/vueComponent/ant-design-vue/issues/3047 + // 受控模式下维持现有状态 + if (props.checked !== undefined) { + inputRef.value.checked = !!props.checked; + } + emit('change', eventObj); + eventShiftKey.value = false; + }; + const onClick = (e: MouseEvent) => { + emit('click', e); + // onChange没能获取到shiftKey,使用onClick hack + eventShiftKey.value = e.shiftKey; + }; + return () => { + const { + prefixCls, + name, + id, + type, + disabled, + readonly, + tabindex, + autofocus, + value, + required, + ...others + } = props; + const { + class: className, + onFocus, + onBlur, + onKeydown, + onKeypress, + onKeyup, + } = attrs as HTMLAttributes; + const globalProps = Object.keys({ ...others, ...attrs }).reduce((prev, key) => { + if (key.substr(0, 5) === 'aria-' || key.substr(0, 5) === 'data-' || key === 'role') { + prev[key] = others[key]; + } + return prev; + }, {}); + + const classString = classNames(prefixCls, className, { + [`${prefixCls}-checked`]: checked.value, + [`${prefixCls}-disabled`]: disabled, + }); + const inputProps = { + name, + id, + type, + readonly, + disabled, + tabindex, + class: `${prefixCls}-input`, + checked: !!checked.value, + autofocus, + value, + ...globalProps, + onChange: handleChange, + onClick, + onFocus, + onBlur, + onKeydown, + onKeypress, + onKeyup, + required, + }; + + return ( + + + + + ); + }; + }, +}); diff --git a/components/vc-checkbox/assets/index.less b/components/vc-checkbox/assets/index.less deleted file mode 100644 index f59a71a53..000000000 --- a/components/vc-checkbox/assets/index.less +++ /dev/null @@ -1,155 +0,0 @@ -@checkboxWarpPrefixCls: rc-checkbox; -@checkboxInnerPrefixCls: ~'@{checkboxWarpPrefixCls}-inner'; - -/* 一般状态 */ -.@{checkboxWarpPrefixCls} { - white-space: nowrap; - cursor: pointer; - outline: none; - display: inline-block; - position: relative; - line-height: 1; - vertical-align: middle; - - &:hover .@{checkboxInnerPrefixCls}, - &-input:focus + .@{checkboxInnerPrefixCls} { - border-color: #3dbcf6; - } - - &-inner { - &:after { - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - position: absolute; - left: 4px; - top: 1px; - display: table; - width: 5px; - height: 8px; - border: 2px solid #ffffff; - border-top: 0; - border-left: 0; - content: ' '; - animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); - animation-duration: 0.3s; - animation-name: amCheckboxOut; - } - - position: relative; - top: 0; - left: 0; - display: inline-block; - width: 14px; - height: 14px; - border-width: 1px; - border-style: solid; - border-radius: 3px; - border-color: #d9d9d9; - background-color: #ffffff; - transition: border-color 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55), - background-color 0.3s cubic-bezier(0.68, -0.55, 0.27, 1.55); - } - - &-input { - position: absolute; - left: 0; - z-index: 9999; - cursor: pointer; - opacity: 0; - top: 0; - bottom: 0; - right: 0; - } -} - -/* 选中状态 */ -.@{checkboxWarpPrefixCls}-checked { - &:hover { - .@{checkboxInnerPrefixCls} { - border-color: #3dbcf6; - } - } - - .@{checkboxInnerPrefixCls} { - border-color: #3dbcf6; - background-color: #3dbcf6; - - &:after { - transform: rotate(45deg); - position: absolute; - left: 4px; - top: 1px; - display: table; - width: 5px; - height: 8px; - border: 2px solid #ffffff; - border-top: 0; - border-left: 0; - content: ' '; - animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); - animation-duration: 0.3s; - animation-name: amCheckboxOut; - } - } -} - -.@{checkboxWarpPrefixCls}-disabled { - &.@{checkboxWarpPrefixCls}-checked { - &:hover { - .@{checkboxInnerPrefixCls} { - border-color: #d9d9d9; - } - } - - .@{checkboxInnerPrefixCls} { - background-color: #f3f3f3; - border-color: #d9d9d9; - - &:after { - animation-name: none; - border-color: #cccccc; - } - } - } - - &:hover { - .@{checkboxInnerPrefixCls} { - border-color: #d9d9d9; - } - } - - .@{checkboxInnerPrefixCls} { - border-color: #d9d9d9; - background-color: #f3f3f3; - &:after { - animation-name: none; - border-color: #f3f3f3; - } - } - - .@{checkboxInnerPrefixCls}-input { - cursor: default; - } -} - -@keyframes amCheckboxIn { - 0% { - opacity: 0; - transform-origin: 50% 50%; - transform: scale(0, 0) rotate(45deg); - } - 100% { - opacity: 1; - transform-origin: 50% 50%; - transform: scale(1, 1) rotate(45deg); - } -} - -@keyframes amCheckboxOut { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} diff --git a/components/vc-checkbox/index.js b/components/vc-checkbox/index.js deleted file mode 100644 index 54968985f..000000000 --- a/components/vc-checkbox/index.js +++ /dev/null @@ -1,2 +0,0 @@ -// based on rc-checkbox 2.1.7 -export { default } from './src/'; diff --git a/components/vc-checkbox/src/Checkbox.jsx b/components/vc-checkbox/src/Checkbox.jsx deleted file mode 100644 index 92016e7da..000000000 --- a/components/vc-checkbox/src/Checkbox.jsx +++ /dev/null @@ -1,143 +0,0 @@ -import { nextTick, defineComponent } from 'vue'; -import classNames from '../../_util/classNames'; -import PropTypes, { withUndefined } from '../../_util/vue-types'; -import BaseMixin from '../../_util/BaseMixin'; -import { getOptionProps, hasProp, initDefaultProps } from '../../_util/props-util'; - -export default defineComponent({ - name: 'Checkbox', - mixins: [BaseMixin], - inheritAttrs: false, - props: initDefaultProps( - { - prefixCls: PropTypes.string, - name: PropTypes.string, - id: PropTypes.string, - type: PropTypes.string, - defaultChecked: withUndefined(PropTypes.oneOfType([PropTypes.number, PropTypes.looseBool])), - checked: withUndefined(PropTypes.oneOfType([PropTypes.number, PropTypes.looseBool])), - disabled: PropTypes.looseBool, - // onFocus: PropTypes.func, - // onBlur: PropTypes.func, - // onChange: PropTypes.func, - // onClick: PropTypes.func, - tabindex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - readonly: PropTypes.looseBool, - autofocus: PropTypes.looseBool, - value: PropTypes.any, - }, - { - prefixCls: 'rc-checkbox', - type: 'checkbox', - defaultChecked: false, - }, - ), - data() { - const checked = hasProp(this, 'checked') ? this.checked : this.defaultChecked; - return { - sChecked: checked, - }; - }, - watch: { - checked(val) { - this.sChecked = val; - }, - }, - mounted() { - nextTick(() => { - if (process.env.NODE_ENV === 'test') { - if (this.autofocus) { - this.$refs.input && this.$refs.input.focus(); - } - } - }); - }, - methods: { - focus() { - this.$refs.input.focus(); - }, - - blur() { - this.$refs.input.blur(); - }, - - handleChange(e) { - const props = getOptionProps(this); - if (props.disabled) { - return; - } - if (!('checked' in props)) { - this.sChecked = e.target.checked; - } - e.shiftKey = this.eventShiftKey; - const eventObj = { - target: { - ...props, - checked: e.target.checked, - }, - stopPropagation() { - e.stopPropagation(); - }, - preventDefault() { - e.preventDefault(); - }, - nativeEvent: e, - }; - - // fix https://github.com/vueComponent/ant-design-vue/issues/3047 - // 受控模式下维持现有状态 - if ('checked' in props) { - this.$refs.input.checked = props.checked; - } - this.__emit('change', eventObj); - this.eventShiftKey = false; - }, - onClick(e) { - this.__emit('click', e); - // onChange没能获取到shiftKey,使用onClick hack - this.eventShiftKey = e.shiftKey; - }, - }, - - render() { - const { prefixCls, name, id, type, disabled, readonly, tabindex, autofocus, value, ...others } = - getOptionProps(this); - const { class: className, onFocus, onBlur } = this.$attrs; - const globalProps = Object.keys({ ...others, ...this.$attrs }).reduce((prev, key) => { - if (key.substr(0, 5) === 'aria-' || key.substr(0, 5) === 'data-' || key === 'role') { - prev[key] = others[key]; - } - return prev; - }, {}); - - const { sChecked } = this; - const classString = classNames(prefixCls, className, { - [`${prefixCls}-checked`]: sChecked, - [`${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, - onFocus, - onBlur, - }; - - return ( - - - - - ); - }, -}); diff --git a/components/vc-checkbox/src/index.js b/components/vc-checkbox/src/index.js deleted file mode 100644 index 36fa16d80..000000000 --- a/components/vc-checkbox/src/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import Checkbox from './Checkbox'; - -export default Checkbox;