From 7e9959419ee137180e20205ad3e2df46981059e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Fri, 21 Jul 2023 13:09:13 +0800 Subject: [PATCH 01/12] fix(button): disabled priority --- src/button/button.en-US.md | 18 +++++++++--------- src/button/button.md | 4 ++-- src/button/button.tsx | 32 +++++++++++++++++++++++++++----- src/button/props.ts | 9 ++++++--- src/button/type.ts | 3 +-- 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/button/button.en-US.md b/src/button/button.en-US.md index f466548e7e..a7666616fd 100644 --- a/src/button/button.en-US.md +++ b/src/button/button.en-US.md @@ -8,22 +8,22 @@ name | type | default | description | required block | Boolean | false | make button to be a block-level element | N content | String / Slot / Function | - | button's children elements。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N default | String / Slot / Function | - | default slot。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N -disabled | Boolean | false | disable the button, make it can not be clicked | N +disabled | Boolean | undefined | disable the button, make it can not be clicked | N ghost | Boolean | false | make background-color to be transparent | N href | String | - | \- | N icon | Slot / Function | - | use it to set left icon in button。Typescript:`TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N loading | Boolean | false | set button to be loading state | N -shape | String | rectangle | button shape。options:rectangle/square/round/circle | N -size | String | medium | a button has three size。options:small/medium/large。Typescript:`SizeEnum`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N +shape | String | rectangle | button shape。options: rectangle/square/round/circle | N +size | String | medium | a button has four size。options: extra-small/small/medium/large。Typescript:`SizeEnum`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N suffix | Slot / Function | - | Typescript:`TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N -tag | String | - | HTML Tag Element。options:button/a/div | N -theme | String | - | button theme。options:default/primary/danger/warning/success | N -type | String | button | type of button element in html。options:submit/reset/button | N -variant | String | base | variant of button。options:base/outline/dashed/text | N -onClick | Function | | Typescript:`(e: MouseEvent) => void`
| N +tag | String | - | HTML Tag Element。options: button/a/div | N +theme | String | - | button theme。options: default/primary/danger/warning/success | N +type | String | button | type of button element in html。options: submit/reset/button | N +variant | String | base | variant of button。options: base/outline/dashed/text | N +onClick | Function | | Typescript:`(e: MouseEvent) => void`
trigger on click | N ### Button Events name | params | description -- | -- | -- -click | `(e: MouseEvent)` | \- +click | `(e: MouseEvent)` | trigger on click diff --git a/src/button/button.md b/src/button/button.md index 847c62a520..6745f7a792 100644 --- a/src/button/button.md +++ b/src/button/button.md @@ -8,13 +8,13 @@ block | Boolean | false | 是否为块级元素 | N content | String / Slot / Function | - | 按钮内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N default | String / Slot / Function | - | 按钮内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N -disabled | Boolean | false | 禁用状态 | N +disabled | Boolean | undefined | 禁用状态。优先级:Button.disabled > Form.disabled | N ghost | Boolean | false | 是否为幽灵按钮(镂空按钮) | N href | String | - | 跳转地址。href 存在时,按钮标签默认使用 `` 渲染;如果指定了 `tag` 则使用指定的标签渲染 | N icon | Slot / Function | - | 按钮内部图标,可完全自定义。TS 类型:`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N loading | Boolean | false | 是否显示为加载状态 | N shape | String | rectangle | 按钮形状,有 4 种:长方形、正方形、圆角长方形、圆形。可选项:rectangle/square/round/circle | N -size | String | medium | 组件尺寸。可选项:small/medium/large。TS 类型:`SizeEnum`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N +size | String | medium | 组件尺寸。可选项:extra-small/small/medium/large。TS 类型:`SizeEnum`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N suffix | Slot / Function | - | 右侧内容,可用于定义右侧图标。TS 类型:`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue-next/blob/develop/src/common.ts) | N tag | String | - | 渲染按钮的 HTML 标签,默认使用标签 `
"`; -exports[`ssr snapshot test > ssr test ./src/button/_example/loading.vue 1`] = `"
"`; +exports[`ssr snapshot test > ssr test ./src/button/_example/loading.vue 1`] = `"
"`; exports[`ssr snapshot test > ssr test ./src/button/_example/shape.vue 1`] = `"
"`; exports[`ssr snapshot test > ssr test ./src/button/_example/size.vue 1`] = `"
"`; -exports[`ssr snapshot test > ssr test ./src/button/_example/status.vue 1`] = `"
"`; +exports[`ssr snapshot test > ssr test ./src/button/_example/status.vue 1`] = `"
"`; exports[`ssr snapshot test > ssr test ./src/button/_example/theme.vue 1`] = `"
"`; From 67613837488f3558dbb4d5123992610c30df187a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Fri, 21 Jul 2023 14:41:36 +0800 Subject: [PATCH 04/12] test: update snap --- src/button/__tests__/__snapshots__/index.test.jsx.snap | 1 - src/button/__tests__/__snapshots__/vitest-button.test.jsx.snap | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/button/__tests__/__snapshots__/index.test.jsx.snap b/src/button/__tests__/__snapshots__/index.test.jsx.snap index 930921cb69..a3fa902ca7 100644 --- a/src/button/__tests__/__snapshots__/index.test.jsx.snap +++ b/src/button/__tests__/__snapshots__/index.test.jsx.snap @@ -119,7 +119,6 @@ exports[`Button > :props > :icon function 1`] = ` exports[`Button > :props > :loading 1`] = ` + + + + diff --git a/test/unit/snap/__snapshots__/ssr.test.js.snap b/test/unit/snap/__snapshots__/ssr.test.js.snap index 154aeacef4..13defe2f11 100644 --- a/test/unit/snap/__snapshots__/ssr.test.js.snap +++ b/test/unit/snap/__snapshots__/ssr.test.js.snap @@ -409,7 +409,7 @@ exports[`ssr snapshot test > ssr test ./src/form/_example/clear-validate.vue 1`] exports[`ssr snapshot test > ssr test ./src/form/_example/custom-validator.vue 1`] = `"
同一个校验方法可输出不同的错误信息和类型,依次输入:1234 观察变化
自定义异步校验方法
"`; -exports[`ssr snapshot test > ssr test ./src/form/_example/disabled.vue 1`] = `"
接受
请选择单张图片文件上传
"`; +exports[`ssr snapshot test > ssr test ./src/form/_example/disabled.vue 1`] = `"
接受
请选择单张图片文件上传
"`; exports[`ssr snapshot test > ssr test ./src/form/_example/error-message.vue 1`] = `"
这是用户名字段帮助说明
一句话介绍自己
"`; From 2cd5c34cf4c05ac1e847cf28d9a0cbf91813e5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E4=BC=9F=E6=9D=B0?= <674416404@qq.com> Date: Mon, 24 Jul 2023 21:46:24 +0800 Subject: [PATCH 11/12] feat: useDisabled --- src/button/button.tsx | 3 ++- src/checkbox/checkbox.tsx | 42 ++++++++++++++------------------------- src/hooks/useDisabled.ts | 16 ++++++++------- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/button/button.tsx b/src/button/button.tsx index 49f8988b5a..c44493e074 100755 --- a/src/button/button.tsx +++ b/src/button/button.tsx @@ -15,10 +15,11 @@ export default defineComponent({ const COMPONENT_NAME = usePrefixClass('button'); const { STATUS, SIZE } = useCommonClassName(); const btnRef = ref(); - const isDisabled = useDisabled(); useRipple(btnRef); + const isDisabled = useDisabled(); + const mergeTheme = computed(() => { const { theme, variant } = props; if (theme) return theme; diff --git a/src/checkbox/checkbox.tsx b/src/checkbox/checkbox.tsx index c330830f40..7423dd7219 100644 --- a/src/checkbox/checkbox.tsx +++ b/src/checkbox/checkbox.tsx @@ -1,13 +1,13 @@ -import { defineComponent, ref, toRefs, inject, watch } from 'vue'; +import { defineComponent, ref, toRefs, inject, watch, computed } from 'vue'; import props from './props'; import useVModel from '../hooks/useVModel'; -import { useFormDisabled } from '../form/hooks'; import useRipple from '../hooks/useRipple'; import { useContent } from '../hooks/tnode'; import { useCommonClassName, usePrefixClass } from '../hooks/useConfig'; import { CheckboxGroupInjectionKey } from './constants'; import useCheckboxLazyLoad from './hooks/useCheckboxLazyLoad'; import useKeyboardEvent from './hooks/useKeyboardEvent'; +import { useDisabled } from '../hooks/useDisabled'; export default defineComponent({ name: 'TCheckbox', @@ -73,29 +73,17 @@ export default defineComponent({ { immediate: true }, ); - // Warn: Do not use computed to set tDisabled - // Form.disabled < CheckboxGroup.disabled < Checkbox.disabled - const tDisabled = ref(false); - const formDisabled = useFormDisabled(); - const getDisabled = () => { - const { checkAll, disabled } = props; - if (!checkAll && !tChecked.value && checkboxGroupData?.value.maxExceeded) { + // Checkbox.disabled > CheckboxGroup.disabled > Form.disabled + const beforeDisabled = computed(() => { + if (!props.checkAll && !tChecked.value && checkboxGroupData?.value.maxExceeded) { return true; } - if (disabled !== undefined) return disabled; - if (checkboxGroupData?.value.disabled !== undefined) { - return checkboxGroupData.value.disabled; - } - if (formDisabled.value !== undefined) return formDisabled.value; - return false; - }; - watch( - () => [props.checkAll, props.disabled, tChecked.value, formDisabled.value, checkboxGroupData?.value.maxExceeded], - () => { - tDisabled.value = getDisabled(); - }, - { immediate: true }, - ); + return null; + }); + const afterDisabled = computed(() => { + return checkboxGroupData?.value.disabled; + }); + const isDisabled = useDisabled({ beforeDisabled, afterDisabled }); const tIndeterminate = ref(false); watch( @@ -110,13 +98,13 @@ export default defineComponent({ const COMPONENT_NAME = usePrefixClass('checkbox'); const labelClasses = ref({}); watch( - [tChecked, tDisabled, tIndeterminate], + [tChecked, isDisabled, tIndeterminate], () => { labelClasses.value = [ `${COMPONENT_NAME.value}`, { [STATUS.value.checked]: tChecked.value, - [STATUS.value.disabled]: tDisabled.value, + [STATUS.value.disabled]: isDisabled.value, [STATUS.value.indeterminate]: tIndeterminate.value, }, ]; @@ -148,7 +136,7 @@ export default defineComponent({