mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
chore: auto merge branches (#51620)
Some checks are pending
Publish Any Commit / build (push) Waiting to run
🔀 Sync mirror to Gitee / mirror (push) Waiting to run
✅ test / lint (push) Waiting to run
✅ test / test-react-legacy (16, 1/2) (push) Waiting to run
✅ test / test-react-legacy (16, 2/2) (push) Waiting to run
✅ test / test-react-legacy (17, 1/2) (push) Waiting to run
✅ test / test-react-legacy (17, 2/2) (push) Waiting to run
✅ test / test-node (push) Waiting to run
✅ test / test-react-latest (dom, 1/2) (push) Waiting to run
✅ test / test-react-latest (dom, 2/2) (push) Waiting to run
✅ test / test-react-latest-dist (dist, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist, 2/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 2/2) (push) Blocked by required conditions
✅ test / test-coverage (push) Blocked by required conditions
✅ test / build (push) Waiting to run
✅ test / test lib/es module (es, 1/2) (push) Waiting to run
✅ test / test lib/es module (es, 2/2) (push) Waiting to run
✅ test / test lib/es module (lib, 1/2) (push) Waiting to run
✅ test / test lib/es module (lib, 2/2) (push) Waiting to run
👁️ Visual Regression Persist Start / test image (push) Waiting to run
Some checks are pending
Publish Any Commit / build (push) Waiting to run
🔀 Sync mirror to Gitee / mirror (push) Waiting to run
✅ test / lint (push) Waiting to run
✅ test / test-react-legacy (16, 1/2) (push) Waiting to run
✅ test / test-react-legacy (16, 2/2) (push) Waiting to run
✅ test / test-react-legacy (17, 1/2) (push) Waiting to run
✅ test / test-react-legacy (17, 2/2) (push) Waiting to run
✅ test / test-node (push) Waiting to run
✅ test / test-react-latest (dom, 1/2) (push) Waiting to run
✅ test / test-react-latest (dom, 2/2) (push) Waiting to run
✅ test / test-react-latest-dist (dist, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist, 2/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 1/2) (push) Blocked by required conditions
✅ test / test-react-latest-dist (dist-min, 2/2) (push) Blocked by required conditions
✅ test / test-coverage (push) Blocked by required conditions
✅ test / build (push) Waiting to run
✅ test / test lib/es module (es, 1/2) (push) Waiting to run
✅ test / test lib/es module (es, 2/2) (push) Waiting to run
✅ test / test lib/es module (lib, 1/2) (push) Waiting to run
✅ test / test lib/es module (lib, 2/2) (push) Waiting to run
👁️ Visual Regression Persist Start / test image (push) Waiting to run
chore: feature merge master
This commit is contained in:
commit
7f52f4a75c
@ -61,5 +61,6 @@
|
|||||||
"5.21.0": [
|
"5.21.0": [
|
||||||
"https://github.com/ant-design/ant-design/issues/50960",
|
"https://github.com/ant-design/ant-design/issues/50960",
|
||||||
"https://github.com/ant-design/ant-design/issues/50969"
|
"https://github.com/ant-design/ant-design/issues/50969"
|
||||||
]
|
],
|
||||||
|
"5.22.0": ["https://github.com/ant-design/ant-design/issues/51601"]
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,61 @@ tag: vVERSION
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 5.22.1
|
||||||
|
|
||||||
|
`2024-11-13`
|
||||||
|
|
||||||
|
- 🛠 Adjust DatePicker.RangePicker to not allow switching to the next field by clicking the input when `needConfirm` and the user has not submitted the date. [#51591](https://github.com/ant-design/ant-design/pull/51591) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🛠 Lock Input.OTP `ctrl + z` operation to avoid data not correct. [#51609](https://github.com/ant-design/ant-design/pull/51609) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 Fix Select `tags` or `multiple` mode display issue. [#51605](https://github.com/ant-design/ant-design/pull/51605) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 🐞 Fix Badge `count` motion missing in Safari. [#51598](https://github.com/ant-design/ant-design/pull/51598) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 Fix Tabs with `centered` the tabs can not fully display. [#51571](https://github.com/ant-design/ant-design/pull/51571) [@DDDDD12138](https://github.com/DDDDD12138)
|
||||||
|
- 🐞 Fix Transfer with controlled `dataSource` & `selectedKeys` sometime miss sync checked state. [#51523](https://github.com/ant-design/ant-design/pull/51523) [@IsKaros](https://github.com/IsKaros)
|
||||||
|
- 🐞 Revert Button `display` `inline-flex` back to `inline-block` to resolve Icon align issue. [#51588](https://github.com/ant-design/ant-design/pull/51588) [@Wxh16144](https://github.com/Wxh16144)
|
||||||
|
|
||||||
|
## 5.22.0
|
||||||
|
|
||||||
|
`2024-11-12`
|
||||||
|
|
||||||
|
- Form
|
||||||
|
- 🆕 Form.Item supports hiding labels. [#51524](https://github.com/ant-design/ant-design/pull/51524) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🐞 Form removes the div used to expand the error height, wraps errorDom and extraDom with a div, and sets a minimum height for the div. [#51254](https://github.com/ant-design/ant-design/pull/51254) [@hongzzz](https://github.com/hongzzz)
|
||||||
|
- 🐞 Fix the problem that `onValuesChange` is still triggered when the Form field triggers change but the value does not change. [#51437](https://github.com/ant-design/ant-design/pull/51437) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🆕 Form supports the focus property in scrollToFirstError when form validation fails. [#51231](https://github.com/ant-design/ant-design/pull/51231) [@nathanlao](https://github.com/nathanlao)
|
||||||
|
- Table
|
||||||
|
- 🆕 Table column filter drop-down box supports `filterDropdownProps`. [#51297](https://github.com/ant-design/ant-design/pull/51297) [@Wxh16144](https://github.com/Wxh16144)
|
||||||
|
- 🆕 Table `expandedRowClassName` supports string . [#51067](https://github.com/ant-design/ant-design/pull/51067) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||||
|
- Tree
|
||||||
|
- 💄 Fix the problem of missing padding style for selected nodes in Tree. [#51492](https://github.com/ant-design/ant-design/pull/51492) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🆕 Tree component Token adds `nodeHoverColor` and `nodeSelectedColor` support. [#51367](https://github.com/ant-design/ant-design/pull/51367) [@zmbxy](https://github.com/zmbxy)
|
||||||
|
- 🆕 Tree adds `indentSize` token for custom indent width. [#51010](https://github.com/ant-design/ant-design/pull/51010) [@afc163](https://github.com/afc163)
|
||||||
|
- DatePicker
|
||||||
|
- 🆕 DatePicker supports prefix attribute. [#51335](https://github.com/ant-design/ant-design/pull/51335) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 💄 Fixed the issue of DatePicker.RangePicker flashing when the mouse moves between cells. [#51533](https://github.com/ant-design/ant-design/pull/51533) [@afc163](https://github.com/afc163)
|
||||||
|
- Input.OTP
|
||||||
|
- 🆕 In the `Input.OTP` component, add `onInput` event to get the value of each user input. At the same time, the relevant documentation has been updated. [#51289](https://github.com/ant-design/ant-design/pull/51289) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🐞 Fixed the problem that Input.OTP cannot specify `inputMode`. [#51271](https://github.com/ant-design/ant-design/pull/51271) [@alan-rudzinski](https://github.com/alan-rudzinski)
|
||||||
|
- 🆕 ColorPicker supports `disabledFormat`. [#51539](https://github.com/ant-design/ant-design/pull/51539) [@su-muzhi](https://github.com/su-muzhi)
|
||||||
|
- 🆕 Add `cursor` configuration item to the `focus` method of InputNumber component to control the cursor position. [#51444](https://github.com/ant-design/ant-design/pull/51444) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🆕 Cascader adds `disabled` attribute to disable all first-level directory items of the component. [#51272](https://github.com/ant-design/ant-design/pull/51272) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🆕 Descriptions supports single-line spreading. [#51365](https://github.com/ant-design/ant-design/pull/51365) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🆕 Select/TreeSelect/Cascader components add `prefix` property to support custom prefix. [#51186](https://github.com/ant-design/ant-design/pull/51186) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 🐞 Fix the problem that the preview image class name is lost when setting `ImageProps.preview.rootClassName` in Image. [#51538](https://github.com/ant-design/ant-design/pull/51538) [@dislido](https://github.com/dislido)
|
||||||
|
- 🐞 Fixed the issue that the last item in the TimePicker panel column cannot be scrolled to the top. [#51481](https://github.com/ant-design/ant-design/pull/51481) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 Fix TreeSelect dropdown height not enough. [#51567](https://github.com/ant-design/ant-design/pull/51567) [@afc163](https://github.com/afc163)
|
||||||
|
- 🐞 Fixed the issue that Typography is not updated immediately when the ConfigProvider language is switched. [#51453](https://github.com/ant-design/ant-design/pull/51453) [@thinkasany](https://github.com/thinkasany)
|
||||||
|
- 🐞 Fixed the issue that Upload `itemRender` calling `action.preview` will cause a crash. [#51419](https://github.com/ant-design/ant-design/pull/51419) [@yoyo837](https://github.com/yoyo837)
|
||||||
|
- 🐞 Fixed Splitter pseudo-element symbol issue. [#51536](https://github.com/ant-design/ant-design/pull/51536) [@dislido](https://github.com/dislido)
|
||||||
|
- 💄 Optimize Collapse accessibility attribute and mouse hover style. [#51400](https://github.com/ant-design/ant-design/pull/51400) [@afc163](https://github.com/afc163)
|
||||||
|
- 💄 Fix styling issue of Menu title content. [#51425](https://github.com/ant-design/ant-design/pull/51425) [@coding-ice](https://github.com/coding-ice)
|
||||||
|
- 🇵🇹 Fix translation in Portuguese (pt_PT) localization file for better accuracy and consistency. [#51501](https://github.com/ant-design/ant-design/pull/51501) [@alexandre-p-marques-alb](https://github.com/alexandre-p-marques-alb)
|
||||||
|
- 🇺🇿 Optimize uz_UZ internationalization. [#51407](https://github.com/ant-design/ant-design/pull/51407) [@Zukhrik](https://github.com/Zukhrik)
|
||||||
|
- TypeScript
|
||||||
|
- 🤖 Upload exports type DraggerProps. [#51546](https://github.com/ant-design/ant-design/pull/51546) [@DBvc](https://github.com/DBvc)
|
||||||
|
- 🤖 Add defaultValue property to TimePicker.RangePicker example. [#51413](https://github.com/ant-design/ant-design/pull/51413) [@nathanlao](https://github.com/nathanlao)
|
||||||
|
- 🤖 Message Optimize the top type in message.config. [#51468](https://github.com/ant-design/ant-design/pull/51468) [@Fog3211](https://github.com/Fog3211)
|
||||||
|
- 🤖 Optimize the TS definition of Tree and TreeSelect. [#51251](https://github.com/ant-design/ant-design/pull/51251) [@afc163](https://github.com/afc163)
|
||||||
|
|
||||||
## 5.21.6
|
## 5.21.6
|
||||||
|
|
||||||
`2024-10-28`
|
`2024-10-28`
|
||||||
|
@ -15,6 +15,61 @@ tag: vVERSION
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 5.22.1
|
||||||
|
|
||||||
|
`2024-11-13`
|
||||||
|
|
||||||
|
- 🛠 调整 DatePicker.RangePicker 当 `needConfirm` 切用户未提交日期时,不允许通过点击输入框切换到下一个字段。[#51591](https://github.com/ant-design/ant-design/pull/51591) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🛠 禁用 Input.OTP `ctrl + z` 操作以防止数据变化非预期的问题。[#51609](https://github.com/ant-design/ant-design/pull/51609) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 修复 Select 标签模式下展示异常的问题。[#51605](https://github.com/ant-design/ant-design/pull/51605) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 🐞 修复 Badge `count` 在 Safari 下动画丢失的问题。[#51598](https://github.com/ant-design/ant-design/pull/51598) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 修复 Tabs `centered` 下标签展示不全的问题。[#51571](https://github.com/ant-design/ant-design/pull/51571) [@DDDDD12138](https://github.com/DDDDD12138)
|
||||||
|
- 🐞 修复 Transfer 受控 `dataSource` 和 `selectedKeys` 时,偶尔会出现勾选不正确的问题。[#51523](https://github.com/ant-design/ant-design/pull/51523) [@IsKaros](https://github.com/IsKaros)
|
||||||
|
- 🐞 回滚 Button `display` 的 `inline-flex` 为 `inline-block` 以解决 Icon 位置偏移的问题。[#51588](https://github.com/ant-design/ant-design/pull/51588) [@Wxh16144](https://github.com/Wxh16144)
|
||||||
|
|
||||||
|
## 5.22.0
|
||||||
|
|
||||||
|
`2024-11-12`
|
||||||
|
|
||||||
|
- Form
|
||||||
|
- 🆕 Form.Item 支持隐藏 label。[#51524](https://github.com/ant-design/ant-design/pull/51524) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🐞 Form 移除了用于撑开 error 高度的 div,将 errorDom 和 extraDom 用一个 div 包裹,并为该 div 设置了最小高度。[#51254](https://github.com/ant-design/ant-design/pull/51254) [@hongzzz](https://github.com/hongzzz)
|
||||||
|
- 🐞 修复 Form 在字段触发 change 但是值没有变化时,`onValuesChange` 仍然会触发的问题。[#51437](https://github.com/ant-design/ant-design/pull/51437) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🆕 Form 支持在表单验证失败时,scrollToFirstError 中的 focus 属性。[#51231](https://github.com/ant-design/ant-design/pull/51231) [@nathanlao](https://github.com/nathanlao)
|
||||||
|
- Table
|
||||||
|
- 🆕 Table 列过滤下拉框支持 `filterDropdownProps`。[#51297](https://github.com/ant-design/ant-design/pull/51297) [@Wxh16144](https://github.com/Wxh16144)
|
||||||
|
- 🆕 Table `expandedRowClassName` 支持 string 。[#51067](https://github.com/ant-design/ant-design/pull/51067) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||||
|
- Tree
|
||||||
|
- 💄 修复 Tree 选中节点丢失 padding 样式的问题。[#51492](https://github.com/ant-design/ant-design/pull/51492) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🆕 Tree 组件 Token 增加 `nodeHoverColor` 和 `nodeSelectedColor` 支持。[#51367](https://github.com/ant-design/ant-design/pull/51367) [@zmbxy](https://github.com/zmbxy)
|
||||||
|
- 🆕 Tree 新增 `indentSize` token 用于自定义缩进宽度。[#51010](https://github.com/ant-design/ant-design/pull/51010) [@afc163](https://github.com/afc163)
|
||||||
|
- DatePicker
|
||||||
|
- 🆕 DatePicker 支持 `prefix` 属性。[#51335](https://github.com/ant-design/ant-design/pull/51335) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 💄 修复 DatePicker.RangePicker 当鼠标移动到单元格之间时出现闪烁样式的问题。[#51533](https://github.com/ant-design/ant-design/pull/51533) [@afc163](https://github.com/afc163)
|
||||||
|
- Input.OTP
|
||||||
|
- 🆕 Input.OTP 组件新增 `onInput` 事件用于获取用户每一次输入的值。[#51289](https://github.com/ant-design/ant-design/pull/51289) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🐞 修复 Input.OTP 无法指定 `inputMode` 的问题。[#51271](https://github.com/ant-design/ant-design/pull/51271) [@alan-rudzinski](https://github.com/alan-rudzinski)
|
||||||
|
- 🆕 ColorPicker 支持 `disabledFormat` 属性以禁用格式切换器。[#51539](https://github.com/ant-design/ant-design/pull/51539) [@su-muzhi](https://github.com/su-muzhi)
|
||||||
|
- 🆕 为 InputNumber 组件的 `focus` 方法增加 `cursor` 配置项以控制光标位置。[#51444](https://github.com/ant-design/ant-design/pull/51444) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🆕 Cascader 新增 `disabled` 属性以禁用组件的所有一级目录项。[#51272](https://github.com/ant-design/ant-design/pull/51272) [@aojunhao123](https://github.com/aojunhao123)
|
||||||
|
- 🆕 Descriptions 支持单行铺满。[#51365](https://github.com/ant-design/ant-design/pull/51365) [@crazyair](https://github.com/crazyair)
|
||||||
|
- 🆕 Select/TreeSelect/Cascader 组件增加 `prefix` 属性以支持自定义前缀。[#51186](https://github.com/ant-design/ant-design/pull/51186) [@guoyunhe](https://github.com/guoyunhe)
|
||||||
|
- 🐞 修复 Image 设置 `ImageProps.preview.rootClassName` 导致预览图类名丢失。[#51538](https://github.com/ant-design/ant-design/pull/51538) [@dislido](https://github.com/dislido)
|
||||||
|
- 🐞 修复 TimePicker 面板列的最后一项无法滚动到最上面的问题。[#51481](https://github.com/ant-design/ant-design/pull/51481) [@zombieJ](https://github.com/zombieJ)
|
||||||
|
- 🐞 修复 TreeSelect 弹层高度不够的问题。[#51567](https://github.com/ant-design/ant-design/pull/51567) [@afc163](https://github.com/afc163)
|
||||||
|
- 🐞 修复 Typography 在 ConfigProvider 语言切换时候没有立即更新。[#51453](https://github.com/ant-design/ant-design/pull/51453) [@thinkasany](https://github.com/thinkasany)
|
||||||
|
- 🐞 修复 Upload `itemRender` 调用 `action.preview` 会导致崩溃的问题。[#51419](https://github.com/ant-design/ant-design/pull/51419) [@yoyo837](https://github.com/yoyo837)
|
||||||
|
- 🐞 修复 Splitter 伪元素符号问题。[#51536](https://github.com/ant-design/ant-design/pull/51536) [@dislido](https://github.com/dislido)
|
||||||
|
- 💄 优化 Collapse 可访问性属性和鼠标 hover 样式。[#51400](https://github.com/ant-design/ant-design/pull/51400) [@afc163](https://github.com/afc163)
|
||||||
|
- 💄 修复 Menu title 内容的样式问题。[#51425](https://github.com/ant-design/ant-design/pull/51425) [@coding-ice](https://github.com/coding-ice)
|
||||||
|
- 🇵🇹 修正葡萄牙语 (pt_PT) 本地化文件中的翻译,以提高准确性和一致性。[#51501](https://github.com/ant-design/ant-design/pull/51501) [@alexandre-p-marques-alb](https://github.com/alexandre-p-marques-alb)
|
||||||
|
- 🇺🇿 优化 uz_UZ 国际化。[#51407](https://github.com/ant-design/ant-design/pull/51407) [@Zukhrik](https://github.com/Zukhrik)
|
||||||
|
- TypeScript
|
||||||
|
- 🤖 Upload 导出类型 DraggerProps。[#51546](https://github.com/ant-design/ant-design/pull/51546) [@DBvc](https://github.com/DBvc)
|
||||||
|
- 🤖 将 defaultValue 属性添加到 TimePicker.RangePicker 示例中。[#51413](https://github.com/ant-design/ant-design/pull/51413) [@nathanlao](https://github.com/nathanlao)
|
||||||
|
- 🤖 Message 优化 message.config 中的 top 类型。[#51468](https://github.com/ant-design/ant-design/pull/51468) [@Fog3211](https://github.com/Fog3211)
|
||||||
|
- 🤖 优化 Tree 和 TreeSelect 的 TS 定义。[#51251](https://github.com/ant-design/ant-design/pull/51251) [@afc163](https://github.com/afc163)
|
||||||
|
|
||||||
## 5.21.6
|
## 5.21.6
|
||||||
|
|
||||||
`2024-10-28`
|
`2024-10-28`
|
||||||
|
@ -79,23 +79,29 @@ const SingleNumber: React.FC<Readonly<SingleNumberProps>> = (props) => {
|
|||||||
unitNumberList.push(index);
|
unitNumberList.push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unit = prevCount < count ? 1 : -1;
|
||||||
|
|
||||||
// Fill with number unit nodes
|
// Fill with number unit nodes
|
||||||
const prevIndex = unitNumberList.findIndex((n) => n % 10 === prevValue);
|
const prevIndex = unitNumberList.findIndex((n) => n % 10 === prevValue);
|
||||||
unitNodes = unitNumberList.map((n, index) => {
|
|
||||||
|
// Cut list
|
||||||
|
const cutUnitNumberList =
|
||||||
|
unit < 0 ? unitNumberList.slice(0, prevIndex + 1) : unitNumberList.slice(prevIndex);
|
||||||
|
|
||||||
|
unitNodes = cutUnitNumberList.map((n, index) => {
|
||||||
const singleUnit = n % 10;
|
const singleUnit = n % 10;
|
||||||
return (
|
return (
|
||||||
<UnitNumber
|
<UnitNumber
|
||||||
{...props}
|
{...props}
|
||||||
key={n}
|
key={n}
|
||||||
value={singleUnit}
|
value={singleUnit}
|
||||||
offset={index - prevIndex}
|
offset={unit < 0 ? index - prevIndex : index}
|
||||||
current={index === prevIndex}
|
current={index === prevIndex}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Calculate container offset value
|
// Calculate container offset value
|
||||||
const unit = prevCount < count ? 1 : -1;
|
|
||||||
offsetStyle = {
|
offsetStyle = {
|
||||||
transform: `translateY(${-getOffset(prevValue, value, unit)}00%)`,
|
transform: `translateY(${-getOffset(prevValue, value, unit)}00%)`,
|
||||||
};
|
};
|
||||||
|
@ -305,60 +305,6 @@ exports[`Badge should render when count is changed 1`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-scroll-number-only-unit"
|
class="ant-scroll-number-only-unit"
|
||||||
style="position: absolute; top: -900%; left: 0px;"
|
|
||||||
>
|
|
||||||
0
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -800%; left: 0px;"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -700%; left: 0px;"
|
|
||||||
>
|
|
||||||
2
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -600%; left: 0px;"
|
|
||||||
>
|
|
||||||
3
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -500%; left: 0px;"
|
|
||||||
>
|
|
||||||
4
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -400%; left: 0px;"
|
|
||||||
>
|
|
||||||
5
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -300%; left: 0px;"
|
|
||||||
>
|
|
||||||
6
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -200%; left: 0px;"
|
|
||||||
>
|
|
||||||
7
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -100%; left: 0px;"
|
|
||||||
>
|
|
||||||
8
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit current"
|
|
||||||
>
|
>
|
||||||
9
|
9
|
||||||
</span>
|
</span>
|
||||||
@ -400,60 +346,6 @@ exports[`Badge should render when count is changed 2`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-scroll-number-only-unit"
|
class="ant-scroll-number-only-unit"
|
||||||
style="position: absolute; top: -900%; left: 0px;"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -800%; left: 0px;"
|
|
||||||
>
|
|
||||||
2
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -700%; left: 0px;"
|
|
||||||
>
|
|
||||||
3
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -600%; left: 0px;"
|
|
||||||
>
|
|
||||||
4
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -500%; left: 0px;"
|
|
||||||
>
|
|
||||||
5
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -400%; left: 0px;"
|
|
||||||
>
|
|
||||||
6
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -300%; left: 0px;"
|
|
||||||
>
|
|
||||||
7
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -200%; left: 0px;"
|
|
||||||
>
|
|
||||||
8
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: -100%; left: 0px;"
|
|
||||||
>
|
|
||||||
9
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit current"
|
|
||||||
>
|
>
|
||||||
0
|
0
|
||||||
</span>
|
</span>
|
||||||
@ -495,7 +387,6 @@ exports[`Badge should render when count is changed 3`] = `
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="ant-scroll-number-only-unit current"
|
class="ant-scroll-number-only-unit current"
|
||||||
style=""
|
|
||||||
>
|
>
|
||||||
1
|
1
|
||||||
</span>
|
</span>
|
||||||
@ -579,60 +470,6 @@ exports[`Badge should render when count is changed 6`] = `
|
|||||||
>
|
>
|
||||||
0
|
0
|
||||||
</span>
|
</span>
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 100%; left: 0px;"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 200%; left: 0px;"
|
|
||||||
>
|
|
||||||
2
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 300%; left: 0px;"
|
|
||||||
>
|
|
||||||
3
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 400%; left: 0px;"
|
|
||||||
>
|
|
||||||
4
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 500%; left: 0px;"
|
|
||||||
>
|
|
||||||
5
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 600%; left: 0px;"
|
|
||||||
>
|
|
||||||
6
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 700%; left: 0px;"
|
|
||||||
>
|
|
||||||
7
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 800%; left: 0px;"
|
|
||||||
>
|
|
||||||
8
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="ant-scroll-number-only-unit"
|
|
||||||
style="position: absolute; top: 900%; left: 0px;"
|
|
||||||
>
|
|
||||||
9
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</bdi>
|
</bdi>
|
||||||
</sup>
|
</sup>
|
||||||
|
@ -39,8 +39,7 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
|||||||
},
|
},
|
||||||
|
|
||||||
'> span': {
|
'> span': {
|
||||||
// https://github.com/ant-design/ant-design/issues/51380
|
display: 'inline-block',
|
||||||
display: 'inline-flex',
|
|
||||||
},
|
},
|
||||||
|
|
||||||
[`${componentCls}-icon`]: {
|
[`${componentCls}-icon`]: {
|
||||||
|
@ -52,7 +52,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
|||||||
| disabledFormat | Disable format of color | boolean | - |
|
| disabledFormat | Disable format of color | boolean | - |
|
||||||
| destroyTooltipOnHide | Whether destroy popover when hidden | `boolean` | false | 5.7.0 |
|
| destroyTooltipOnHide | Whether destroy popover when hidden | `boolean` | false | 5.7.0 |
|
||||||
| format | Format of color | `rgb` \| `hex` \| `hsb` | `hex` | |
|
| format | Format of color | `rgb` \| `hex` \| `hsb` | `hex` | |
|
||||||
| mode | Configure single or gradient color | `('single' \| 'gradient')[]` | `single` | 5.20.0 |
|
| mode | Configure single or gradient color | `'single' \| 'gradient' \| ('single' \| 'gradient')[]` | `single` | 5.20.0 |
|
||||||
| open | Whether to show popup | boolean | - | |
|
| open | Whether to show popup | boolean | - | |
|
||||||
| presets | Preset colors | `{ label: ReactNode, colors: Array<string \| Color>, defaultOpen?: boolean }[]` | - | `defaultOpen: 5.11.0` |
|
| presets | Preset colors | `{ label: ReactNode, colors: Array<string \| Color>, defaultOpen?: boolean }[]` | - | `defaultOpen: 5.11.0` |
|
||||||
| placement | Placement of popup | The design of the [placement](/components/tooltip/#api) parameter is the same as the `Tooltips` component. | `bottomLeft` | |
|
| placement | Placement of popup | The design of the [placement](/components/tooltip/#api) parameter is the same as the `Tooltips` component. | `bottomLeft` | |
|
||||||
|
@ -53,7 +53,7 @@ group:
|
|||||||
| disabledFormat | 禁用选择颜色格式 | boolean | - |
|
| disabledFormat | 禁用选择颜色格式 | boolean | - |
|
||||||
| destroyTooltipOnHide | 关闭后是否销毁弹窗 | `boolean` | false | 5.7.0 |
|
| destroyTooltipOnHide | 关闭后是否销毁弹窗 | `boolean` | false | 5.7.0 |
|
||||||
| format | 颜色格式 | `rgb` \| `hex` \| `hsb` | `hex` | |
|
| format | 颜色格式 | `rgb` \| `hex` \| `hsb` | `hex` | |
|
||||||
| mode | 选择器模式,用于配置单色与渐变 | `('single' \| 'gradient')[]` | `single` | 5.20.0 |
|
| mode | 选择器模式,用于配置单色与渐变 | `'single' \| 'gradient' \| ('single' \| 'gradient')[]` | `single` | 5.20.0 |
|
||||||
| open | 是否显示弹出窗口 | boolean | - | |
|
| open | 是否显示弹出窗口 | boolean | - | |
|
||||||
| presets | 预设的颜色 | `{ label: ReactNode, colors: Array<string \| Color>, defaultOpen?: boolean }[]` | - | `defaultOpen: 5.11.0` |
|
| presets | 预设的颜色 | `{ label: ReactNode, colors: Array<string \| Color>, defaultOpen?: boolean }[]` | - | `defaultOpen: 5.11.0` |
|
||||||
| placement | 弹出窗口的位置 | 同 `Tooltips` 组件的 [placement](/components/tooltip-cn/#api) 参数设计 | `bottomLeft` | |
|
| placement | 弹出窗口的位置 | 同 `Tooltips` 组件的 [placement](/components/tooltip-cn/#api) 参数设计 | `bottomLeft` | |
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Cascader,
|
Cascader,
|
||||||
@ -11,7 +11,6 @@ import {
|
|||||||
TreeSelect,
|
TreeSelect,
|
||||||
Segmented,
|
Segmented,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import type { FormProps } from 'antd';
|
|
||||||
|
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
||||||
@ -27,18 +26,15 @@ const formItemLayout = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [componentVariant, setComponentVariant] = useState<FormProps['variant']>('filled');
|
const [form] = Form.useForm();
|
||||||
|
const variant = Form.useWatch('variant', form);
|
||||||
const onFormVariantChange = ({ variant }: { variant: FormProps['variant'] }) => {
|
|
||||||
setComponentVariant(variant);
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
{...formItemLayout}
|
{...formItemLayout}
|
||||||
onValuesChange={onFormVariantChange}
|
form={form}
|
||||||
variant={componentVariant}
|
variant={variant || 'filled'}
|
||||||
style={{ maxWidth: 600 }}
|
style={{ maxWidth: 600 }}
|
||||||
initialValues={{ variant: componentVariant }}
|
initialValues={{ variant: 'filled' }}
|
||||||
>
|
>
|
||||||
<Form.Item label="Form variant" name="variant">
|
<Form.Item label="Form variant" name="variant">
|
||||||
<Segmented options={['outlined', 'filled', 'borderless']} />
|
<Segmented options={['outlined', 'filled', 'borderless']} />
|
||||||
|
@ -37,11 +37,15 @@ const OTPInput = React.forwardRef<InputRef, OTPInputProps>((props, ref) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ======================== Keyboard ========================
|
// ======================== Keyboard ========================
|
||||||
const onInternalKeyDown: React.KeyboardEventHandler<HTMLInputElement> = ({ key }) => {
|
const onInternalKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
|
||||||
|
const { key, ctrlKey, metaKey } = event;
|
||||||
|
|
||||||
if (key === 'ArrowLeft') {
|
if (key === 'ArrowLeft') {
|
||||||
onActiveChange(index - 1);
|
onActiveChange(index - 1);
|
||||||
} else if (key === 'ArrowRight') {
|
} else if (key === 'ArrowRight') {
|
||||||
onActiveChange(index + 1);
|
onActiveChange(index + 1);
|
||||||
|
} else if (key === 'z' && (ctrlKey || metaKey)) {
|
||||||
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
syncSelection();
|
syncSelection();
|
||||||
|
@ -4,7 +4,7 @@ import Input from '..';
|
|||||||
import focusTest from '../../../tests/shared/focusTest';
|
import focusTest from '../../../tests/shared/focusTest';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
import { createEvent, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||||
|
|
||||||
const { OTP } = Input;
|
const { OTP } = Input;
|
||||||
|
|
||||||
@ -191,4 +191,13 @@ describe('Input.OTP', () => {
|
|||||||
fireEvent.input(inputs[3], { target: { value: '4' } });
|
fireEvent.input(inputs[3], { target: { value: '4' } });
|
||||||
expect(onInput).toHaveBeenCalledWith(['1', '2', '3', '4']);
|
expect(onInput).toHaveBeenCalledWith(['1', '2', '3', '4']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('disabled ctrl + z', () => {
|
||||||
|
const { container } = render(<OTP length={4} defaultValue="1234" />);
|
||||||
|
const inputEle = container.querySelector('input')!;
|
||||||
|
const event = createEvent.keyDown(inputEle, { key: 'z', ctrlKey: true });
|
||||||
|
fireEvent(inputEle, event);
|
||||||
|
|
||||||
|
expect(event.defaultPrevented).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -80,6 +80,7 @@ const localeValues: Locale = {
|
|||||||
copy: 'Копировать',
|
copy: 'Копировать',
|
||||||
copied: 'Скопировано',
|
copied: 'Скопировано',
|
||||||
expand: 'Раскрыть',
|
expand: 'Раскрыть',
|
||||||
|
collapse: "Свернуть",
|
||||||
},
|
},
|
||||||
Form: {
|
Form: {
|
||||||
optional: '(необязательно)',
|
optional: '(необязательно)',
|
||||||
@ -138,6 +139,12 @@ const localeValues: Locale = {
|
|||||||
expired: 'QR-код устарел',
|
expired: 'QR-код устарел',
|
||||||
refresh: 'Обновить',
|
refresh: 'Обновить',
|
||||||
},
|
},
|
||||||
|
ColorPicker: {
|
||||||
|
presetEmpty: 'Пустой',
|
||||||
|
transparent: 'Прозрачный',
|
||||||
|
singleColor: 'Один цвет',
|
||||||
|
gradientColor: 'Градиент',
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default localeValues;
|
export default localeValues;
|
||||||
|
@ -232,6 +232,11 @@ const genSelectionStyle = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[`${componentCls}-selection-wrap`]: {
|
||||||
|
width: '100%',
|
||||||
|
overflow: 'hidden',
|
||||||
|
},
|
||||||
|
|
||||||
// ======================== Selections ========================
|
// ======================== Selections ========================
|
||||||
[`${componentCls}-selection-item`]: {
|
[`${componentCls}-selection-item`]: {
|
||||||
height: multipleSelectorUnit.itemHeight,
|
height: multipleSelectorUnit.itemHeight,
|
||||||
|
@ -50,7 +50,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*37T2R6O9oi0AAA
|
|||||||
| classNames | 语义化 className | [Record<SemanticDOM, string>](#semantic-dom) | - | |
|
| classNames | 语义化 className | [Record<SemanticDOM, string>](#semantic-dom) | - | |
|
||||||
| direction | 间距方向 | `vertical` \| `horizontal` | `horizontal` | 4.1.0 |
|
| direction | 间距方向 | `vertical` \| `horizontal` | `horizontal` | 4.1.0 |
|
||||||
| size | 间距大小 | [Size](#size) \| [Size\[\]](#size) | `small` | 4.1.0 \| Array: 4.9.0 |
|
| size | 间距大小 | [Size](#size) \| [Size\[\]](#size) | `small` | 4.1.0 \| Array: 4.9.0 |
|
||||||
| split | 设置拆分 | ReactNode | - | 4.7.0 |
|
| split | 设置分隔符 | ReactNode | - | 4.7.0 |
|
||||||
| styles | 语义化 style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | |
|
| styles | 语义化 style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | |
|
||||||
| wrap | 是否自动换行,仅在 `horizontal` 时有效 | boolean | false | 4.9.0 |
|
| wrap | 是否自动换行,仅在 `horizontal` 时有效 | boolean | false | 4.9.0 |
|
||||||
|
|
||||||
|
@ -1003,8 +1003,8 @@ const genTabsStyle: GenerateStyle<TabsToken> = (token: TabsToken): CSSObject =>
|
|||||||
[`${componentCls}-centered`]: {
|
[`${componentCls}-centered`]: {
|
||||||
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
[`> ${componentCls}-nav, > div > ${componentCls}-nav`]: {
|
||||||
[`${componentCls}-nav-wrap`]: {
|
[`${componentCls}-nav-wrap`]: {
|
||||||
[`&:not([class*='${componentCls}-nav-wrap-ping'])`]: {
|
[`&:not([class*='${componentCls}-nav-wrap-ping']) > ${componentCls}-nav-list`]: {
|
||||||
justifyContent: 'center',
|
margin: 'auto',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@ import Transfer from '..';
|
|||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
import Button from '../../button';
|
import Button from '../../button';
|
||||||
|
import { waitFakeTimer } from '../../../tests/utils';
|
||||||
|
|
||||||
const listCommonProps: {
|
const listCommonProps: {
|
||||||
dataSource: { key: string; title: string; disabled?: boolean }[];
|
dataSource: { key: string; title: string; disabled?: boolean }[];
|
||||||
@ -767,6 +768,70 @@ describe('Transfer', () => {
|
|||||||
|
|
||||||
errSpy.mockRestore();
|
errSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
it('it checks correctly after changing the dataSource', async () => {
|
||||||
|
const mockData = Array.from({ length: 10 }).map((_, i) => ({
|
||||||
|
key: i.toString(),
|
||||||
|
title: `content${i + 1}`,
|
||||||
|
description: `description of content${i + 1}`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const initialTargetKeys = mockData
|
||||||
|
.filter((item) => Number(item.key) > 4)
|
||||||
|
.map((item) => item.key);
|
||||||
|
|
||||||
|
const defaultCheckedKeys = ['1', '2'];
|
||||||
|
const handleSelectChange = jest.fn();
|
||||||
|
const App: React.FC = () => {
|
||||||
|
const [targetKeys, setTargetKeys] = useState<TransferProps['targetKeys']>(initialTargetKeys);
|
||||||
|
const [selectedKeys, setSelectedKeys] = useState<TransferProps['targetKeys']>([]);
|
||||||
|
|
||||||
|
const [dataSource, setDataSource] = useState(mockData);
|
||||||
|
|
||||||
|
const onChange: TransferProps['onChange'] = (nextTargetKeys) => {
|
||||||
|
setTargetKeys(nextTargetKeys);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
className="update-btn"
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedKeys(defaultCheckedKeys);
|
||||||
|
setDataSource([]);
|
||||||
|
setDataSource([...mockData]);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// setDataSource([...mockData]);
|
||||||
|
// });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
update
|
||||||
|
</Button>
|
||||||
|
<Transfer
|
||||||
|
dataSource={dataSource}
|
||||||
|
titles={['Source', 'Target']}
|
||||||
|
targetKeys={targetKeys}
|
||||||
|
selectedKeys={selectedKeys}
|
||||||
|
onChange={onChange}
|
||||||
|
onSelectChange={handleSelectChange}
|
||||||
|
render={(item) => item.title}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const { container } = render(<App />);
|
||||||
|
|
||||||
|
fireEvent.click(container.querySelector('.update-btn')!);
|
||||||
|
await waitFakeTimer();
|
||||||
|
|
||||||
|
defaultCheckedKeys.forEach((item) => {
|
||||||
|
expect(
|
||||||
|
container
|
||||||
|
?.querySelectorAll('.ant-transfer-list-content-item')
|
||||||
|
?.item(Number(item))
|
||||||
|
?.querySelector('input[type="checkbox"]')!,
|
||||||
|
).toBeChecked();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('immutable data', () => {
|
describe('immutable data', () => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useEvent, useMergedState } from 'rc-util';
|
||||||
|
|
||||||
import type { TransferKey } from '../interface';
|
import type { TransferKey } from '../interface';
|
||||||
|
|
||||||
@ -16,12 +17,12 @@ function flattenKeys(keys: Set<TransferKey>) {
|
|||||||
export default function useSelection<T extends { key: TransferKey }>(
|
export default function useSelection<T extends { key: TransferKey }>(
|
||||||
leftDataSource: T[],
|
leftDataSource: T[],
|
||||||
rightDataSource: T[],
|
rightDataSource: T[],
|
||||||
selectedKeys: TransferKey[] = EMPTY_KEYS,
|
selectedKeys?: TransferKey[],
|
||||||
): [
|
): [
|
||||||
sourceSelectedKeys: TransferKey[],
|
sourceSelectedKeys: TransferKey[],
|
||||||
targetSelectedKeys: TransferKey[],
|
targetSelectedKeys: TransferKey[],
|
||||||
setSourceSelectedKeys: React.Dispatch<React.SetStateAction<TransferKey[]>>,
|
setSourceSelectedKeys: (srcKeys: TransferKey[]) => void,
|
||||||
setTargetSelectedKeys: React.Dispatch<React.SetStateAction<TransferKey[]>>,
|
setTargetSelectedKeys: (srcKeys: TransferKey[]) => void,
|
||||||
] {
|
] {
|
||||||
// Prepare `dataSource` keys
|
// Prepare `dataSource` keys
|
||||||
const [leftKeys, rightKeys] = React.useMemo(
|
const [leftKeys, rightKeys] = React.useMemo(
|
||||||
@ -33,25 +34,35 @@ export default function useSelection<T extends { key: TransferKey }>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Selected Keys
|
// Selected Keys
|
||||||
const [sourceSelectedKeys, setSourceSelectedKeys] = React.useState(() =>
|
const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(EMPTY_KEYS, {
|
||||||
filterKeys(selectedKeys, leftKeys),
|
value: selectedKeys,
|
||||||
|
});
|
||||||
|
|
||||||
|
const sourceSelectedKeys = React.useMemo(
|
||||||
|
() => filterKeys(mergedSelectedKeys, leftKeys),
|
||||||
|
[mergedSelectedKeys, leftKeys],
|
||||||
);
|
);
|
||||||
const [targetSelectedKeys, setTargetSelectedKeys] = React.useState(() =>
|
const targetSelectedKeys = React.useMemo(
|
||||||
filterKeys(selectedKeys, rightKeys),
|
() => filterKeys(mergedSelectedKeys, rightKeys),
|
||||||
|
[mergedSelectedKeys, rightKeys],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fill selected keys
|
// // Reset when data changed
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setSourceSelectedKeys(filterKeys(selectedKeys, leftKeys));
|
setMergedSelectedKeys([
|
||||||
setTargetSelectedKeys(filterKeys(selectedKeys, rightKeys));
|
...filterKeys(mergedSelectedKeys, leftKeys),
|
||||||
}, [selectedKeys]);
|
...filterKeys(mergedSelectedKeys, rightKeys),
|
||||||
|
]);
|
||||||
// Reset when data changed
|
|
||||||
React.useEffect(() => {
|
|
||||||
setSourceSelectedKeys(filterKeys(sourceSelectedKeys, leftKeys));
|
|
||||||
setTargetSelectedKeys(filterKeys(targetSelectedKeys, rightKeys));
|
|
||||||
}, [flattenKeys(leftKeys), flattenKeys(rightKeys)]);
|
}, [flattenKeys(leftKeys), flattenKeys(rightKeys)]);
|
||||||
|
|
||||||
|
// Update keys
|
||||||
|
const setSourceSelectedKeys = useEvent((nextSrcKeys: TransferKey[]) => {
|
||||||
|
setMergedSelectedKeys([...nextSrcKeys, ...targetSelectedKeys]);
|
||||||
|
});
|
||||||
|
const setTargetSelectedKeys = useEvent((nextTargetKeys: TransferKey[]) => {
|
||||||
|
setMergedSelectedKeys([...sourceSelectedKeys, ...nextTargetKeys]);
|
||||||
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// Keys
|
// Keys
|
||||||
sourceSelectedKeys,
|
sourceSelectedKeys,
|
||||||
|
@ -69,7 +69,7 @@ Please refer to [Use custom date library](/docs/react/use-custom-date-library).
|
|||||||
|
|
||||||
## It doesn't work when I change `defaultValue` dynamically.
|
## It doesn't work when I change `defaultValue` dynamically.
|
||||||
|
|
||||||
The `defaultXxxx` (e.g. `defaultValue`) of `Input`/`Select`(etc...) only works on the first render. It is a specification of React. Please read [React's documentation](https://facebook.github.io/react/docs/forms.html#controlled-components).
|
The `defaultXxxx` (e.g. `defaultValue`) of `Input`/`Select`(etc...) only works on the first render. It is a specification of React. Please read [React's documentation](https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable).
|
||||||
|
|
||||||
## Why does modifying props in mutable way not trigger a component update?
|
## Why does modifying props in mutable way not trigger a component update?
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ antd use shallow compare of props to optimize performance. You should always pas
|
|||||||
|
|
||||||
## After I set the `value` of an `Input`/`Select`(etc.) component, the value cannot be changed by user's action.
|
## After I set the `value` of an `Input`/`Select`(etc.) component, the value cannot be changed by user's action.
|
||||||
|
|
||||||
Try `onChange` to change `value`, and please read [React's documentation](https://reactjs.org/docs/forms.html#controlled-components).
|
Try `onChange` to change `value`, and please read [React's documentation](https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable).
|
||||||
|
|
||||||
## Components are not vertically aligned when placed in single row.
|
## Components are not vertically aligned when placed in single row.
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ antd 在 minor 和 patch 版本迭代中会避免引入破坏性变更,遵从
|
|||||||
|
|
||||||
## 当我动态改变 `defaultValue` 的时候它并没有生效。
|
## 当我动态改变 `defaultValue` 的时候它并没有生效。
|
||||||
|
|
||||||
`Input`/`Select` 等的 `defaultXxxx`(例如 `defaultValue`)只有在第一次渲染的时候有效,这是 React 的规范,请阅读 [React 的文档](https://zh-hans.reactjs.org/docs/forms.html#controlled-components)。
|
`Input`/`Select` 等的 `defaultXxxx`(例如 `defaultValue`)只有在第一次渲染的时候有效,这是 React 的规范,请阅读 [React 的文档](https://zh-hans.react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable)。
|
||||||
|
|
||||||
## 为什么修改组件传入的对象或数组属性组件不会更新?
|
## 为什么修改组件传入的对象或数组属性组件不会更新?
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ antd 内部会对 props 进行浅比较实现性能优化。当状态变更,
|
|||||||
|
|
||||||
## 当我设置了 `Input`/`Select` 等的 `value` 时它就无法修改了。
|
## 当我设置了 `Input`/`Select` 等的 `value` 时它就无法修改了。
|
||||||
|
|
||||||
尝试使用 `onChange` 来改变 `value`,请参考 [React 的文档](https://zh-hans.reactjs.org/docs/forms.html#controlled-components)。
|
尝试使用 `onChange` 来改变 `value`,请参考 [React 的文档](https://zh-hans.react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable)。
|
||||||
|
|
||||||
## 多个组件放一排时没有垂直对齐怎么办?
|
## 多个组件放一排时没有垂直对齐怎么办?
|
||||||
|
|
||||||
|
@ -10,5 +10,8 @@
|
|||||||
"_nodeModulesRegexes": ["rc-.*"]
|
"_nodeModulesRegexes": ["rc-.*"]
|
||||||
},
|
},
|
||||||
"hmr": false,
|
"hmr": false,
|
||||||
"devtool": false
|
"devtool": false,
|
||||||
|
"experimental": {
|
||||||
|
"magicComment": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "antd",
|
"name": "antd",
|
||||||
"version": "5.21.6",
|
"version": "5.22.1",
|
||||||
"description": "An enterprise-class UI design language and React components implementation",
|
"description": "An enterprise-class UI design language and React components implementation",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
@ -126,7 +126,7 @@
|
|||||||
"rc-dialog": "~9.6.0",
|
"rc-dialog": "~9.6.0",
|
||||||
"rc-drawer": "~7.2.0",
|
"rc-drawer": "~7.2.0",
|
||||||
"rc-dropdown": "~4.2.0",
|
"rc-dropdown": "~4.2.0",
|
||||||
"rc-field-form": "~2.5.0",
|
"rc-field-form": "~2.5.1",
|
||||||
"rc-image": "~7.11.0",
|
"rc-image": "~7.11.0",
|
||||||
"rc-input": "~1.6.3",
|
"rc-input": "~1.6.3",
|
||||||
"rc-input-number": "~9.3.0",
|
"rc-input-number": "~9.3.0",
|
||||||
@ -135,7 +135,7 @@
|
|||||||
"rc-motion": "^2.9.3",
|
"rc-motion": "^2.9.3",
|
||||||
"rc-notification": "~5.6.2",
|
"rc-notification": "~5.6.2",
|
||||||
"rc-pagination": "~4.3.0",
|
"rc-pagination": "~4.3.0",
|
||||||
"rc-picker": "~4.7.2",
|
"rc-picker": "~4.8.1",
|
||||||
"rc-progress": "~4.0.0",
|
"rc-progress": "~4.0.0",
|
||||||
"rc-rate": "~2.13.0",
|
"rc-rate": "~2.13.0",
|
||||||
"rc-resize-observer": "^1.4.0",
|
"rc-resize-observer": "^1.4.0",
|
||||||
@ -149,7 +149,7 @@
|
|||||||
"rc-textarea": "~1.8.2",
|
"rc-textarea": "~1.8.2",
|
||||||
"rc-tooltip": "~6.2.1",
|
"rc-tooltip": "~6.2.1",
|
||||||
"rc-tree": "~5.10.1",
|
"rc-tree": "~5.10.1",
|
||||||
"rc-tree-select": "~5.24.3",
|
"rc-tree-select": "~5.24.4",
|
||||||
"rc-upload": "~4.8.1",
|
"rc-upload": "~4.8.1",
|
||||||
"rc-util": "^5.43.0",
|
"rc-util": "^5.43.0",
|
||||||
"scroll-into-view-if-needed": "^3.1.0",
|
"scroll-into-view-if-needed": "^3.1.0",
|
||||||
|
@ -62,6 +62,7 @@ const miscKeys = [
|
|||||||
'🇪🇸',
|
'🇪🇸',
|
||||||
'🇷🇺',
|
'🇷🇺',
|
||||||
'🇺🇦',
|
'🇺🇦',
|
||||||
|
'🇵🇹',
|
||||||
'🇲🇲',
|
'🇲🇲',
|
||||||
'🇸🇪',
|
'🇸🇪',
|
||||||
'🇻🇳',
|
'🇻🇳',
|
||||||
|
Loading…
Reference in New Issue
Block a user