From e788bac953e4ec81aaa938fa0ee1cffdd83fd940 Mon Sep 17 00:00:00 2001 From: dundun003 Date: Thu, 26 Dec 2024 11:39:12 +0800 Subject: [PATCH 01/13] docs: update the docs of tagInput --- docs/web/api/tag-input.en-US.md | 8 +++++++- docs/web/api/tag-input.md | 9 +++++++-- style/web/components/tag-input/_index.less | 23 ++++++++++++++++++---- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/docs/web/api/tag-input.en-US.md b/docs/web/api/tag-input.en-US.md index 19d12b31ab..fe85b4a8f2 100644 --- a/docs/web/api/tag-input.en-US.md +++ b/docs/web/api/tag-input.en-US.md @@ -2,7 +2,7 @@ title: TagInput description: Used to enter a text label. isComponent: true -usage: { title: '', description: '' } +usage: { title: "", description: "" } spline: data --- @@ -16,6 +16,12 @@ Use `excessTagsDisplayType` to control the rendering method when the tag exceeds {{ excess }} +### Maximum Number of Rows When Tags Exceed Limit + +Use `maxRows` to control the maximum number of rows when tags exceed the limit. A scrollbar will appear when the number of rows exceeds this limit. By default, there is no limit. + +{{ max-row }} + ### Tag input box with limited number Use `max` to control the maximum number of tags. diff --git a/docs/web/api/tag-input.md b/docs/web/api/tag-input.md index c5bbafb8c4..77fd0b949f 100644 --- a/docs/web/api/tag-input.md +++ b/docs/web/api/tag-input.md @@ -2,7 +2,7 @@ title: TagInput 标签输入框 description: 用于输入文本标签。 isComponent: true -usage: { title: '', description: '' } +usage: { title: "", description: "" } spline: data --- @@ -16,6 +16,11 @@ spline: data {{ excess }} +### 标签数量超出后限制最大行数的输入框 + +使用 maxRows 控制标签超出时的最大行数,超出会出现滚动条,默认为不限制。 + +{{ max-row }} ### 有数量限制的标签输入框 @@ -43,7 +48,6 @@ spline: data {{ custom-tag }} - ### 不同状态的标签输入框 标签输入框状态可分为:正常、只读、禁用、成功、告警、错误等,其中 成功、告警、错误 等状态一般用于表单验证。此特性继承至 Input 输入框组件。 @@ -61,4 +65,5 @@ spline: data {{ auto-width }} ### 可拖拽调整顺序的标签输入框 + {{ draggable }} diff --git a/style/web/components/tag-input/_index.less b/style/web/components/tag-input/_index.less index ee503fee4a..8c9333674c 100644 --- a/style/web/components/tag-input/_index.less +++ b/style/web/components/tag-input/_index.less @@ -45,7 +45,6 @@ /** 设计稿:未填充标签场景,边距和已填充不同 */ &.@{prefix}-is-empty { - .@{prefix}-input__inner { margin-left: @comp-margin-xs; } @@ -72,7 +71,6 @@ } &.@{prefix}-input--auto-width { - .@{prefix}-input.@{prefix}-input--focused { padding-right: @tag-input-clear-icon-padding-m; } @@ -95,7 +93,6 @@ // 标签数量超出时,换行显示 .@{prefix}-tag-input--break-line:not(.@{prefix}-is-empty) { - .@{prefix}-input { display: block; @@ -122,7 +119,9 @@ } /** 换行模式避免标签和右侧图标重合,需保留图标宽度 22px 和左侧距离标签间距 8px */ -.@{prefix}-tag-input--break-line.@{prefix}-tag-input--with-tag:not(.@{prefix}-input--auto-width), +.@{prefix}-tag-input--break-line.@{prefix}-tag-input--with-tag:not( + .@{prefix}-input--auto-width + ), .@{prefix}-tag-input.@{prefix}-input--auto-width:hover { .@{prefix}-input { padding-right: @tag-input-clear-icon-padding-m; @@ -141,3 +140,19 @@ padding-right: 0; } } + +/** max-rows模式,限制最大高度 */ +.@{prefix}-tag-input--max-rows { + .@{prefix}-input { + &.@{prefix}-size-s { + max-height: calc(var(--max-rows, 1) * @tag-input-height-s) !important; + } + + &.@{prefix}-size-l { + max-height: calc(var(--max-rows, 1) * @tag-input-height-l) !important; + } + + max-height: calc(var(--max-rows, 1) * @tag-input-height-default) !important; + overflow-y: scroll; + } +} From 42678e21ac8588024ffb8ae97399529e1639690f Mon Sep 17 00:00:00 2001 From: dundun003 Date: Thu, 26 Dec 2024 11:56:01 +0800 Subject: [PATCH 02/13] lint: fix stylelint err --- docs/web/api/tag-input.md | 2 +- style/web/components/tag-input/_index.less | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/web/api/tag-input.md b/docs/web/api/tag-input.md index 77fd0b949f..ebc0ef25a3 100644 --- a/docs/web/api/tag-input.md +++ b/docs/web/api/tag-input.md @@ -2,7 +2,7 @@ title: TagInput 标签输入框 description: 用于输入文本标签。 isComponent: true -usage: { title: "", description: "" } +usage: { title: '', description: '' } spline: data --- diff --git a/style/web/components/tag-input/_index.less b/style/web/components/tag-input/_index.less index 8c9333674c..abdf4385aa 100644 --- a/style/web/components/tag-input/_index.less +++ b/style/web/components/tag-input/_index.less @@ -45,6 +45,7 @@ /** 设计稿:未填充标签场景,边距和已填充不同 */ &.@{prefix}-is-empty { + .@{prefix}-input__inner { margin-left: @comp-margin-xs; } @@ -71,6 +72,7 @@ } &.@{prefix}-input--auto-width { + .@{prefix}-input.@{prefix}-input--focused { padding-right: @tag-input-clear-icon-padding-m; } @@ -93,6 +95,7 @@ // 标签数量超出时,换行显示 .@{prefix}-tag-input--break-line:not(.@{prefix}-is-empty) { + .@{prefix}-input { display: block; @@ -119,9 +122,7 @@ } /** 换行模式避免标签和右侧图标重合,需保留图标宽度 22px 和左侧距离标签间距 8px */ -.@{prefix}-tag-input--break-line.@{prefix}-tag-input--with-tag:not( - .@{prefix}-input--auto-width - ), +.@{prefix}-tag-input--break-line.@{prefix}-tag-input--with-tag:not(.@{prefix}-input--auto-width), .@{prefix}-tag-input.@{prefix}-input--auto-width:hover { .@{prefix}-input { padding-right: @tag-input-clear-icon-padding-m; From 500259adca051f9f85ccf00346016b38947c5cc6 Mon Sep 17 00:00:00 2001 From: liangshaojun-666 <2936670268@qq.com> Date: Tue, 31 Dec 2024 10:02:03 +0800 Subject: [PATCH 03/13] fix: delete unnecessay !important --- docs/web/api/tag-input.en-US.md | 2 +- style/web/components/tag-input/_index.less | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/web/api/tag-input.en-US.md b/docs/web/api/tag-input.en-US.md index fe85b4a8f2..350feabe92 100644 --- a/docs/web/api/tag-input.en-US.md +++ b/docs/web/api/tag-input.en-US.md @@ -2,7 +2,7 @@ title: TagInput description: Used to enter a text label. isComponent: true -usage: { title: "", description: "" } +usage: { title: '', description: '' } spline: data --- diff --git a/style/web/components/tag-input/_index.less b/style/web/components/tag-input/_index.less index abdf4385aa..3c51949a02 100644 --- a/style/web/components/tag-input/_index.less +++ b/style/web/components/tag-input/_index.less @@ -146,14 +146,14 @@ .@{prefix}-tag-input--max-rows { .@{prefix}-input { &.@{prefix}-size-s { - max-height: calc(var(--max-rows, 1) * @tag-input-height-s) !important; + max-height: calc(var(--max-rows, 1) * @tag-input-height-s); } &.@{prefix}-size-l { - max-height: calc(var(--max-rows, 1) * @tag-input-height-l) !important; + max-height: calc(var(--max-rows, 1) * (@tag-input-height-l - 2px)); } - max-height: calc(var(--max-rows, 1) * @tag-input-height-default) !important; + max-height: calc(var(--max-rows, 1) * (@tag-input-height-default - 2px)); overflow-y: scroll; } } From 72884e5672d0db532129f891bcc0fde25e114ea1 Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Wed, 30 Apr 2025 17:42:28 +0800 Subject: [PATCH 04/13] fix: cascader unchecked bug when childNode is disabled --- js/tree/tree-node.ts | 48 +++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index a7c7355d94..f3046ada07 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -863,6 +863,11 @@ export class TreeNode { if (!tree.nodeMap.get(value)) return false; // 节点不可选,视为未选中 if (!this.isCheckable()) return false; + // 禁用节点保持原有选中状态 + if (this.isDisabledState()) { + const checkedMap = map || tree.checkedMap; + return !!checkedMap.get(value); + } const checkedMap = map || tree.checkedMap; // 严格模式,则已经可以判定选中状态 if (checkStrictly) { @@ -872,7 +877,7 @@ export class TreeNode { // 在 checkedMap 中,则根据 valueMode 的值进行判断 if (checkedMap.get(value) && ( - // 如果 valueMode 为 all、parentFirst,则视为选中 + // 如果 valueMode 为 all、parentFirst,则视为选中 valueMode !== 'onlyLeaf' // 如果 valueMode 为 onlyLeaf 并且当前节点是叶子节点,则视为选中 || this.isLeaf() @@ -881,18 +886,24 @@ export class TreeNode { return true; } // 如果 valueMode 为 onlyLeaf 并且当前节点是父节点,则进一步判断 - if (Array.isArray(children) && children.length > 0) { - // 子节点全部选中,则当前节点选中 - checked = children.every((node) => { - const childIsChecked = node.isChecked(checkedMap); - return childIsChecked; - }); - } else { - // 从父节点状态推断子节点状态 - // 这里再调用 isChecked 会导致死循环 - const parents = this.getParents(); - checked = parents.some((node) => checkedMap.get(node.value)); - } + if (Array.isArray(children) && children.length > 0) { + // 子节点全部选中(排除禁用节点),则当前节点选中 + const enabledChildren = children.filter((node) => !node.isDisabled()); + if (enabledChildren.length > 0) { + checked = enabledChildren.every((node) => { + const childIsChecked = node.isChecked(checkedMap); + return childIsChecked; + }); + } else { + // 如果所有子节点都被禁用,则视为未选中 + checked = false; + } + } else { + // 从父节点状态推断子节点状态 + // 这里再调用 isChecked 会导致死循环 + const parents = this.getParents(); + checked = parents.some((node) => checkedMap.get(node.value)); + } return checked; } @@ -1306,7 +1317,16 @@ export class TreeNode { map.delete(this.value); children.forEach((node) => { // 对于 UI 动作,向下扩散时,禁用状态会阻止状态切换 - if (options.isAction && node.isDisabledState()) return; + if (options.isAction && node.isDisabledState()) { + // 保持禁用节点的原有选中状态 + const originalChecked = node.isChecked(); + if (originalChecked) { + map.set(node.value, true); + } else { + map.delete(node.value); + } + return; + } if (checked) { map.set(node.value, true); } else { From 8de38950dd23664fcd9b0d9a1546121611af4705 Mon Sep 17 00:00:00 2001 From: Shabix <131671885+Shabi-x@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:14:35 +0800 Subject: [PATCH 05/13] Update tree-node.ts From 95e11f9de5a572711f2ce0ef39ae70097404152e Mon Sep 17 00:00:00 2001 From: Shabix <131671885+Shabi-x@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:18:06 +0800 Subject: [PATCH 06/13] Update tree-node.ts --- js/tree/tree-node.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index f3046ada07..51b75340e6 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -890,20 +890,20 @@ export class TreeNode { // 子节点全部选中(排除禁用节点),则当前节点选中 const enabledChildren = children.filter((node) => !node.isDisabled()); if (enabledChildren.length > 0) { - checked = enabledChildren.every((node) => { - const childIsChecked = node.isChecked(checkedMap); - return childIsChecked; - }); - } else { - // 如果所有子节点都被禁用,则视为未选中 - checked = false; - } - } else { - // 从父节点状态推断子节点状态 - // 这里再调用 isChecked 会导致死循环 - const parents = this.getParents(); - checked = parents.some((node) => checkedMap.get(node.value)); - } + checked = enabledChildren.every((node) => { + const childIsChecked = node.isChecked(checkedMap); + return childIsChecked; + }); + } else { + // 如果所有子节点都被禁用,则视为未选中 + checked = false; + } + } else { + // 从父节点状态推断子节点状态 + // 这里再调用 isChecked 会导致死循环 + const parents = this.getParents(); + checked = parents.some((node) => checkedMap.get(node.value)); + } return checked; } From eb0cbeb51cda446a37d8f2cdf603345f99bf3e72 Mon Sep 17 00:00:00 2001 From: Shabix <131671885+Shabi-x@users.noreply.github.com> Date: Wed, 30 Apr 2025 18:26:47 +0800 Subject: [PATCH 07/13] lint err --- js/tree/tree-node.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 51b75340e6..f4a8324257 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -890,10 +890,10 @@ export class TreeNode { // 子节点全部选中(排除禁用节点),则当前节点选中 const enabledChildren = children.filter((node) => !node.isDisabled()); if (enabledChildren.length > 0) { - checked = enabledChildren.every((node) => { - const childIsChecked = node.isChecked(checkedMap); - return childIsChecked; - }); + checked = enabledChildren.every((node) => { + const childIsChecked = node.isChecked(checkedMap); + return childIsChecked; + }); } else { // 如果所有子节点都被禁用,则视为未选中 checked = false; From cfed67369dce5fc58404a4c7a562ae7fd386a569 Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Tue, 6 May 2025 09:46:57 +0800 Subject: [PATCH 08/13] fix: lint err --- js/tree/tree-node.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index f4a8324257..480c40fe94 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -877,7 +877,7 @@ export class TreeNode { // 在 checkedMap 中,则根据 valueMode 的值进行判断 if (checkedMap.get(value) && ( - // 如果 valueMode 为 all、parentFirst,则视为选中 + // 如果 valueMode 为 all、parentFirst,则视为选中 valueMode !== 'onlyLeaf' // 如果 valueMode 为 onlyLeaf 并且当前节点是叶子节点,则视为选中 || this.isLeaf() @@ -886,14 +886,14 @@ export class TreeNode { return true; } // 如果 valueMode 为 onlyLeaf 并且当前节点是父节点,则进一步判断 - if (Array.isArray(children) && children.length > 0) { - // 子节点全部选中(排除禁用节点),则当前节点选中 - const enabledChildren = children.filter((node) => !node.isDisabled()); - if (enabledChildren.length > 0) { - checked = enabledChildren.every((node) => { - const childIsChecked = node.isChecked(checkedMap); - return childIsChecked; - }); + if (Array.isArray(children) && children.length > 0) { + // 子节点全部选中(排除禁用节点),则当前节点选中 + const enabledChildren = children.filter(node => !node.isDisabled()); + if (enabledChildren.length > 0) { + checked = enabledChildren.every((node) => { + const childIsChecked = node.isChecked(checkedMap); + return childIsChecked; + }); } else { // 如果所有子节点都被禁用,则视为未选中 checked = false; @@ -1285,7 +1285,7 @@ export class TreeNode { const { children } = this; if (Array.isArray(children) && children.length > 0) { // 有子节点,则选中态由子节点选中态集合来决定 - map.delete(this.value); + map.delete(this.value); } const { parent } = this; @@ -1318,15 +1318,15 @@ export class TreeNode { children.forEach((node) => { // 对于 UI 动作,向下扩散时,禁用状态会阻止状态切换 if (options.isAction && node.isDisabledState()) { - // 保持禁用节点的原有选中状态 - const originalChecked = node.isChecked(); + // 保持禁用节点的原有选中状态 + const originalChecked = node.isChecked(); if (originalChecked) { map.set(node.value, true); } else { map.delete(node.value); - } - return; - } + } + return; + } if (checked) { map.set(node.value, true); } else { From c0bf5fdfc26dc07a16f6efeee6c87ab52385e4d9 Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Tue, 6 May 2025 09:51:13 +0800 Subject: [PATCH 09/13] fix: lint err --- js/tree/tree-node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 480c40fe94..5a533eb649 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -1285,7 +1285,7 @@ export class TreeNode { const { children } = this; if (Array.isArray(children) && children.length > 0) { // 有子节点,则选中态由子节点选中态集合来决定 - map.delete(this.value); + map.delete(this.value); } const { parent } = this; From dee604b0ee21817767c16e8b64424e21bf039bbb Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Tue, 6 May 2025 10:16:18 +0800 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20=E7=AE=80=E5=8C=96=E9=9D=9E?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=9A=84=E3=80=81=E5=AF=B9=E4=BA=8Edisabled?= =?UTF-8?q?=E5=AD=90=E9=A1=B9=E5=A7=8B=E7=BB=88=E4=B8=BAfalse=E7=9A=84?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=9A=84=E7=BB=B4=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/tree/tree-node.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 5a533eb649..42e1279316 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -1317,16 +1317,7 @@ export class TreeNode { map.delete(this.value); children.forEach((node) => { // 对于 UI 动作,向下扩散时,禁用状态会阻止状态切换 - if (options.isAction && node.isDisabledState()) { - // 保持禁用节点的原有选中状态 - const originalChecked = node.isChecked(); - if (originalChecked) { - map.set(node.value, true); - } else { - map.delete(node.value); - } - return; - } + if (options.isAction && node.isDisabledState()) return; if (checked) { map.set(node.value, true); } else { From 48788574ec5e7317c8f14d135017d336c1eea474 Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Tue, 6 May 2025 10:22:38 +0800 Subject: [PATCH 11/13] lint: fix expected parentheses around arrow function argument arrow-parens --- js/tree/tree-node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 42e1279316..1e53fae675 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -888,7 +888,7 @@ export class TreeNode { // 如果 valueMode 为 onlyLeaf 并且当前节点是父节点,则进一步判断 if (Array.isArray(children) && children.length > 0) { // 子节点全部选中(排除禁用节点),则当前节点选中 - const enabledChildren = children.filter(node => !node.isDisabled()); + const enabledChildren = children.filter((node) => !node.isDisabled()); if (enabledChildren.length > 0) { checked = enabledChildren.every((node) => { const childIsChecked = node.isChecked(checkedMap); From 52d08ee8447095db5c91ecbeacf7f3d6bf86cdfa Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Wed, 7 May 2025 11:47:53 +0800 Subject: [PATCH 12/13] =?UTF-8?q?fix(tree-node):=20=E7=AE=80=E5=8C=96check?= =?UTF-8?q?ed=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/tree/tree-node.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 1e53fae675..7c6f41e717 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -864,15 +864,16 @@ export class TreeNode { // 节点不可选,视为未选中 if (!this.isCheckable()) return false; // 禁用节点保持原有选中状态 - if (this.isDisabledState()) { - const checkedMap = map || tree.checkedMap; - return !!checkedMap.get(value); - } + const checkedMap = map || tree.checkedMap; // 严格模式,则已经可以判定选中状态 if (checkStrictly) { return !!checkedMap.get(value); } + if (this.isDisabledState()) { + return !!checkedMap.get(value); + } + let checked = false; // 在 checkedMap 中,则根据 valueMode 的值进行判断 if (checkedMap.get(value) From ae74566e9e0ba4b6841cbec689a245aac001fcb8 Mon Sep 17 00:00:00 2001 From: clutchLiang Date: Wed, 7 May 2025 11:51:34 +0800 Subject: [PATCH 13/13] =?UTF-8?q?docs:=20=E8=B0=83=E6=95=B4=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/tree/tree-node.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/tree/tree-node.ts b/js/tree/tree-node.ts index 7c6f41e717..fa450ec0db 100644 --- a/js/tree/tree-node.ts +++ b/js/tree/tree-node.ts @@ -863,17 +863,16 @@ export class TreeNode { if (!tree.nodeMap.get(value)) return false; // 节点不可选,视为未选中 if (!this.isCheckable()) return false; - // 禁用节点保持原有选中状态 const checkedMap = map || tree.checkedMap; // 严格模式,则已经可以判定选中状态 if (checkStrictly) { return !!checkedMap.get(value); } + // 节点为禁用状态,则保留原有节点状态 if (this.isDisabledState()) { return !!checkedMap.get(value); } - let checked = false; // 在 checkedMap 中,则根据 valueMode 的值进行判断 if (checkedMap.get(value)