diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index a5d810eedd..3e2711b40b 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -15,13 +15,45 @@ timeline: true --- +## 4.19.2 + +`2022-03-13` + +- 🐞 Fix Dropdown not auto adjust placement when position on the edge of window. [#34390](https://github.com/ant-design/ant-design/pull/34390) +- 💄 Change PageHeader elements margin from `12px` to `8px` inside `extra`. [#34428](https://github.com/ant-design/ant-design/pull/34428) +- 🛠 Export css variable function in `antd/es/config-provider` folder to enable ssr requirement. [#34436](https://github.com/ant-design/ant-design/pull/34436) +- 🛠 Refactor Menu with React hooks. [#34433](https://github.com/ant-design/ant-design/pull/34433) +- Input + - 💄 Fix Input font-size when `size` is large. [#34381](https://github.com/ant-design/ant-design/pull/34381) + - 💄 Fix Input.Group wrong border when status is error. [#34412](https://github.com/ant-design/ant-design/pull/34412) +- Form + - 🐞 Fix Form.Item removed in `form.validateFields` throw `Can't perform a React state update on an unmounted component` warning. [#34405](https://github.com/ant-design/ant-design/pull/34405) + - 🐞 Fix to Form that `initialValues` would change if `preserve` is false. [#34411](https://github.com/ant-design/ant-design/pull/34411) +- Tooltip + - 💄 Fix Tooltip width in Safari. [#34415](https://github.com/ant-design/ant-design/pull/34415) [@jiandandkl](https://github.com/jiandandkl) + - 💄 Fix arrow size of Tooltip/Popover/Popconfirm. [#34407](https://github.com/ant-design/ant-design/pull/34407) +- 💄 Remove Collapse bottom border in simple style. [#34366](https://github.com/ant-design/ant-design/pull/34366) [@PanStar](https://github.com/PanStar) +- TypeScript + - 🤖 Fix Input `data-*` type definition. [#34410](https://github.com/ant-design/ant-design/pull/34410) [@GitKou](https://github.com/GitKou) + - 🤖 Fix Transfer `footer` type definition. [#34337](https://github.com/ant-design/ant-design/pull/34337) [@zomixi](https://github.com/zomixi) + +## 4.19.1 + +`2022-03-08` + +- 🐞 Fix less compile error related to custom status. [#34350](https://github.com/ant-design/ant-design/pull/34350) + - 🐞 Fix error `ReferenceError: colorPalette is not defined` when customize theme. + - 🐞 Fix error `Error: Invalid class or id selector syntax` when import `antd/dist/antd.css`. +- 🐞 Fix Input.Passowrd icon color in site. [#34354](https://github.com/ant-design/ant-design/pull/34354) +- 🐞 Fix ConfigProvider `csp` sometime not effect on Icon. [#34356](https://github.com/ant-design/ant-design/pull/34356) + ## 4.19.0 `2022-03-08` - 💄 Optimize arrow style for some components. [#33710](https://github.com/ant-design/ant-design/pull/33710) -![image](https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png) + - Input - 🛠 Refactor Input with rc-input. [#34206](https://github.com/ant-design/ant-design/pull/34206) @@ -33,6 +65,7 @@ timeline: true - ⌨️ Table adds `aria-sort` attribute for screen readers. [#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1) - 🐞 Fix Table filters select-all Checkbox not changed when select item. [#34295](https://github.com/ant-design/ant-design/pull/34295) - 🆕 Data entry components add `status` prop to support custom status. + - Transfer [#34098](https://github.com/ant-design/ant-design/pull/34098) - AutoComplete [#34096](https://github.com/ant-design/ant-design/pull/34096) - TreeSelect [#34093](https://github.com/ant-design/ant-design/pull/34093) @@ -43,7 +76,7 @@ timeline: true - InputNumber [#34042](https://github.com/ant-design/ant-design/pull/34042) - Input [#33995](https://github.com/ant-design/ant-design/pull/33995) -![image](https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png) + - 🆕 InputNumber supports `controls={{ upIcon, downIcon }}` to customize icon up and down. [#33914](https://github.com/ant-design/ant-design/pull/33914) [@heiyu4585](https://github.com/heiyu4585) - 🆕 Notification `placement` support `top` / `bottom` [#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 4e7664b835..b46c47fa42 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -13,26 +13,59 @@ timeline: true - 次版本号:每月发布一个带有新特性的向下兼容的版本。 - 主版本号:含有破坏性更新和新特性,不在发布周期内。 ---- +-- + +## 4.19.2 + +`2022-03-13` + +- 🐞 修复 Dropdown 在边界情况下不会自动调整展示位置的问题。[#34390](https://github.com/ant-design/ant-design/pull/34390) +- 💄 缩小 PageHeader `extra` 内元素间距为 `8px`。[#34428](https://github.com/ant-design/ant-design/pull/34428) +- 🛠 导出 antd/es/config-provider 目录下的 css variable 函数以支持 ssr 的需求。[#34436](https://github.com/ant-design/ant-design/pull/34436) +- 🛠 使用 React hooks 重构 Menu。[#34433](https://github.com/ant-design/ant-design/pull/34433) +- Input + - 💄 修复大尺寸 Input 的字号问题。[#34381](https://github.com/ant-design/ant-design/pull/34381) + - 💄 修复 Input.Group 多余的错误边框样式。[#34412](https://github.com/ant-design/ant-design/pull/34412) +- Form + - 🐞 修复 Form.Item 在 `form.validateFields` 中移除时抛出 `Can't perform a React state update on an unmounted component` 警告的问题。[#34405](https://github.com/ant-design/ant-design/pull/34405) + - 🐞 修复 Form 组件当 `preserve` 为 `false` 时 `initialValues` 会被更改的问题。[#34411](https://github.com/ant-design/ant-design/pull/34411) +- Tooltip + - 💄 修复 Tooltip 在 Safari 下的内容宽度问题。[#34415](https://github.com/ant-design/ant-design/pull/34415) [@jiandandkl](https://github.com/jiandandkl) + - 💄 修复 Tooltip/Popover/Popconfirm 等组件箭头大小问题。[#34407](https://github.com/ant-design/ant-design/pull/34407) +- 💄 优化 Collapse 简洁模式的底边框。[#34366](https://github.com/ant-design/ant-design/pull/34366) [@PanStar](https://github.com/PanStar) +- TypeScript + - 🤖 修复 Input 不支持 `data-*` TS 定义的问题。[#34410](https://github.com/ant-design/ant-design/pull/34410) [@GitKou](https://github.com/GitKou) + - 🤖 修复 Transfer 的 `footer` 类型定义。[#34337](https://github.com/ant-design/ant-design/pull/34337) [@zomixi](https://github.com/zomixi) + +## 4.19.1 + +`2022-03-08` + +- 🐞 修复自定义状态相关的 less 编译错误。[#34350](htps://github.com/ant-dign/ant-design/pull/34350) + - 🐞 修复使用定制主题时 less 编译提示 `ReferenceError: colorPalette is not defined` 错误。 + - 🐞 修复引入 `antd/dist/antd.css` 时提示 `Error: Invalid class or id selector syntax` 错误。 +- 🐞 修复 Input.Passowrd 图标颜色错误。[#34354](https://github.com/ant-design/ant-design/pull/34354) +- 🐞 修复 ConfigProvider `csp` 有时在 Icon 上不会生效的问题。[#34356](https://github.com/ant-design/ant-design/pull/34356) ## 4.19.0 `2022-03-08` -- 💄 优化部分组件箭头样式。 [#33710](https://github.com/ant-design/ant-design/pull/33710) +- 💄 优化部分组件箭头样式。[#33710](https://github.com/ant-design/ant-design/pull/33710) -![image](https://user-images.githubusercontent.com/27722486/157088587-ca49cc29-bf25-42d1-8c14-020b5501c62e.png) + - Input - 🛠 引入 rc-input 重构 Input 组件为 function component。[#34206](https://github.com/ant-design/ant-design/pull/34206) - 注意:由于从 class component 变为 function component,Input 组件的 `ref` 类型及内容已经更新,可以通过 `import { InputRef } from 'antd'` 引入。其中的 `input` 属性作为获取 DOM 的途径被保留,同时支持 `focus` 和 `blur` 等文档中支持的方法。 - - 🆕 新增 `clearIcon` 属性,支持自定义清除按钮。 [#34325](https://github.com/ant-design/ant-design/pull/34325) + - 🆕 新增 `clearIcon` 属性,支持自定义清除按钮。[#34325](https://github.com/ant-design/ant-design/pull/34325) - Table - 🆕 `column.filterSearch` 属性现在支持返回一个函数用于自定义搜索条件。[#34085](https://github.com/ant-design/ant-design/pull/34085) [@heiyu4585](https://github.com/heiyu4585) - 🆕 `column.filterDropdown({ clearFilters })` 支持参数 `clearFilters({ confirm: false, closeDropdown: false })` 控制筛选。[#34120](https://github.com/ant-design/ant-design/pull/34120) [@heiyu4585](https://github.com/heiyu4585) - - ⌨️ 增加 `aria-sort` 属性以优化屏幕阅读器的使用体验。 [#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1) - - 🐞 修复 Table 列筛选器中选择全部 Checkbox 状态问题。 [#34295](https://github.com/ant-design/ant-design/pull/34295) + - ⌨️ 增加 `aria-sort` 属性以优化屏幕阅读器的使用体验。[#33603](https://github.com/ant-design/ant-design/pull/33603) [@dgreene1](https://github.com/dgreene1) + - 🐞 修复 Table 列筛选器中选择全部 Checkbox 状态问题。[#34295](https://github.com/ant-design/ant-design/pull/34295) - 🆕 表单组件新增 `status` 属性以支持自定义状态。 + - Transfer [#34098](https://github.com/ant-design/ant-design/pull/34098) - AutoComplete [#34096](https://github.com/ant-design/ant-design/pull/34096) - TreeSelect [#34093](https://github.com/ant-design/ant-design/pull/34093) @@ -43,18 +76,18 @@ timeline: true - InputNumber [#34042](https://github.com/ant-design/ant-design/pull/34042) - Input [#33995](https://github.com/ant-design/ant-design/pull/33995) -![image](https://user-images.githubusercontent.com/27722486/157089015-f96b0153-2cc4-4e04-94d6-e0e4b195d5d1.png) + - 🆕 InputNumber 组件支持 `controls={{ upIcon, downIcon }}` 用于自定义上下图标。[#33914](https://github.com/ant-design/ant-design/pull/33914) [@heiyu4585](https://github.com/heiyu4585) -- 🆕 Notification 组件弹窗位置新增支持 `top` / `bottom`。 [#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585) -- 🆕 Select、Cascader、DatePicker 等组件新增 `placement` 用于自定义弹层方向。 [#33641](https://github.com/ant-design/ant-design/pull/33541) [@ONLY-yours](https://github.com/ONLY-yours) -- 🆕 Dropdown 组件支持 `arrow={{ pointAtCenter: true }}` 用于指向元素正中间,并且新增 `top` `bottom` 两种 `placement` 位置。 [#33658](https://github.com/ant-design/ant-design/pull/33658) -- 🆕 Skeleton.Input 添加 `block` 属性。 [#33672](https://github.com/ant-design/ant-design/pull/33672) [@woochanleee](https://github.com/woochanleee) -- 🆕 合并 TimePicker `disabledHours`、`disabledMinutes`、`disabledSeconds` 至 `disabledTime` 以保持与 DatePicker 接口一致性。 [#33503](https://github.com/ant-design/ant-design/pull/33503) -- 💄 修改部分边框颜色和进度条的背景色为透明色以适应有色背景。 [#33506](https://github.com/ant-design/ant-design/pull/33506) -- 💄 Space 支持自定义 children 的 `key`。 [#33607](https://github.com/ant-design/ant-design/pull/33607) [@qin20](https://github.com/qin20) -- 🐞 修复 Typography.Title 进入编辑模式时大小不一致的问题。 [#34169](https://github.com/ant-design/ant-design/pull/34169) [@heiyu4585](https://github.com/heiyu4585) -- 🐞 修复 Form.Item 抛出 `React does not recognize the requiredMark prop on a DOM element` 的问题。 [#34323](https://github.com/ant-design/ant-design/pull/34323) +- 🆕 Notification 组件弹窗位置新增支持 `top` / `bottom`。[#33871](https://github.com/ant-design/ant-design/pull/33871) [@heiyu4585](https://github.com/heiyu4585) +- 🆕 Select、Cascader、DatePicker 等组件新增 `placement` 用于自定义弹层方向。[#33641](https://github.com/ant-design/ant-design/pull/33541) [@ONLY-yours](https://github.com/ONLY-yours) +- 🆕 Dropdown 组件支持 `arrow={{ pointAtCenter: true }}` 用于指向元素正中间,并且新增 `top` `bottom` 两种 `placement` 位置。[#33658](https://github.com/ant-design/ant-design/pull/33658) +- 🆕 Skeleton.Input 添加 `block` 属性。[#33672](https://github.com/ant-design/ant-design/pull/33672) [@woochanleee](https://github.com/woochanleee) +- 🆕 合并 TimePicker `disabledHours`、`disabledMinutes`、`disabledSeconds` 至 `disabledTime` 以保持与 DatePicker 接口一致性。[#33503](https://github.com/ant-design/ant-design/pull/33503) +- 💄 修改部分边框颜色和进度条的背景色为透明色以适应有色背景。[#33506](https://github.com/ant-design/ant-design/pull/33506) +- 💄 Space 支持自定义 children 的 `key`。[#33607](https://github.com/ant-design/ant-design/pull/33607) [@qin20](https://github.com/qin20) +- 🐞 修复 Typography.Title 进入编辑模式时大小不一致的问题。[#34169](https://github.com/ant-design/ant-design/pull/34169) [@heiyu4585](https://github.com/heiyu4585) +- 🐞 修复 Form.Item 抛出 `React does not recognize the requiredMark prop on a DOM element` 的问题。[#34323](https://github.com/ant-design/ant-design/pull/34323) ## 4.18.9 @@ -135,7 +168,7 @@ timeline: true - Typography - ⚡️ 优化 Typography 在配置 `tooltip` 时优先使用原生省略样式以提升性能。[#33669](https://github.com/ant-design/ant-design/pull/33669) - - 🐞 重构 Typography `ellipsis` 逻辑以修复 `children` 如果消费上游 Context 会报错的问题。 [#33725](https://github.com/ant-design/ant-design/pull/33725) + - 🐞 重构 Typography `ellipsis` 逻辑以修复 `children` 如果消费上游 Context 会报错的问题。[#33725](https://github.com/ant-design/ant-design/pull/33725) - Icon - 🐞 修复 `` 和 `` 不对齐的问题。[#33709](https://github.com/ant-design/ant-design/pull/33709) - 🐞 修复 `` 抖动的问题。[#33726](https://github.com/ant-design/ant-design/pull/33726) [@JX-Zhuang](https://github.com/JX-Zhuang) @@ -361,7 +394,7 @@ timeline: true - 🐞 修复 Button `ghost` 鼠标悬停样式。[#32289](https://github.com/ant-design/ant-design/pull/32289) - 🐞 修复 Button 配置 `loading` 时,无法触发 Tooltip 的问题。[#32158](https://github.com/ant-design/ant-design/pull/32158) - Pagination - - 🆕 Pagination 支持定制 `selectComponentClass`。 [#32132](https://github.com/ant-design/ant-design/pull/32132) [@JounQin](https://github.com/JounQin) + - 🆕 Pagination 支持定制 `selectComponentClass`。[#32132](https://github.com/ant-design/ant-design/pull/32132) [@JounQin](https://github.com/JounQin) - 💄 Pagination `simple` 属性下中翻页 input 增加 box-shadow。[#32528](https://github.com/ant-design/ant-design/pull/32528) [@chen-jingjie](https://github.com/chen-jingjie) - Upload - 🐞 修复 Upload `listStyle="picture"` 下加载中样式错位的问题。[#32664](https://github.com/ant-design/ant-design/pull/32664) @@ -414,7 +447,7 @@ timeline: true - 🤖 修复 Switch `id` 属性定义。[#32237](https://github.com/ant-design/ant-design/pull/32237) [@M-ZubairAhmed](https://github.com/M-ZubairAhmed) - 🤖 修复 Button 的 `type` 的 TS 类型定义。[#32004](https://github.com/ant-design/ant-design/pull/32004) [@jaredleechn](https://github.com/jaredleechn) - 🤖 完备 Pagination 的 `locale` TS 类型定义。[[#32128](https://github.com/ant-design/ant-design/pull/32128) [@JounQin](https://github.com/JounQin) - - 🤖 完善并导出 DropdownButton 的 `DropdownButtonType` TS 类型定义。 [[#31957](https://github.com/ant-design/ant-design/pull/31957) [@Dreamerryao](https://github.com/Dreamerryao) + - 🤖 完善并导出 DropdownButton 的 `DropdownButtonType` TS 类型定义。[[#31957](https://github.com/ant-design/ant-design/pull/31957) [@Dreamerryao](https://github.com/Dreamerryao) - 🤖 调整 List 组件 `rowKey` 类型为 React.key。[#32033](https://github.com/ant-design/ant-design/pull/32033) [@lironhl](https://github.com/lironhl) - 🐞 修复 DatePicker `ref` 类型。[#31993](https://github.com/ant-design/ant-design/pull/31993) [@acfasj](https://github.com/acfasj) - 🤖 更新 Drawer 中 `levelMove` 类型定义。[#30714](https://github.com/ant-design/ant-design/pull/30714) [@g0shed](https://github.com/g0shed) @@ -463,7 +496,7 @@ timeline: true - 🐞 修复 Progress 环形进度条 `success.strokeColor` 不生效的问题。[#31589](https://github.com/ant-design/ant-design/pull/31589) - 🐞 修复 Select 组件没有忽略 `getRawInputElement` 属性导致的类型报错问题。[#31566](https://github.com/ant-design/ant-design/pull/31566) [@aoilti](https://github.com/aoilti) - 🐞 修复 Pagination 的 `totalBoundaryShowSizeChanger` 属性类型错误。[#31549](https://github.com/ant-design/ant-design/pull/31549) [@Monty-Ma](https://github.com/Monty-Ma) -- 🐞 修复 Skeleton.Avatar `className` 重复应用的问题。 [#31536](https://github.com/ant-design/ant-design/pull/31536) [@Greatshock](https://github.com/Greatshock) +- 🐞 修复 Skeleton.Avatar `className` 重复应用的问题。[#31536](https://github.com/ant-design/ant-design/pull/31536) [@Greatshock](https://github.com/Greatshock) - 🌐 国际化 - 🇹🇷 为 Image 组件中 `预览` 文案增加土耳其语翻译。[#31593](https://github.com/ant-design/ant-design/pull/31593) [@mburakkalkan](https://github.com/mburakkalkan) - 🇰🇷 修复韩语中的错别字。[#31575](https://github.com/ant-design/ant-design/pull/31575) [@chatoo2412](https://github.com/chatoo2412) @@ -784,7 +817,7 @@ timeline: true - 🐞 修复 Modal 页脚里使用 href 按钮导致的间距丢失问题。[#29681](https://github.com/ant-design/ant-design/pull/29681) [@n0ruSh](https://github.com/n0ruSh) - 💄 修复 Input 组件配置附件元素时禁用样式异常的问题。[#29670](https://github.com/ant-design/ant-design/pull/29670) - 💄 优化 Form.Item 提示信息的鼠标显示样式。[#29650](https://github.com/ant-design/ant-design/pull/29650) -- 🇨🇿 修复 cs_CZ 语言环境中的错字。 [#29675](https://github.com/ant-design/ant-design/pull/29675) [@jvaclavik](https://github.com/jvaclavik) +- 🇨🇿 修复 cs_CZ 语言环境中的错字。[#29675](https://github.com/ant-design/ant-design/pull/29675) [@jvaclavik](https://github.com/jvaclavik) - 🇨🇦 添加 fr_CA 语言。[#29748](https://github.com/ant-design/ant-design/pull/29748) [@liufenghua808](https://github.com/liufenghua808) ## 4.13.1 @@ -884,7 +917,7 @@ timeline: true - TypeScript - 🤖 更新 Table TypeScript 定义 `dataSource` 至 `readonly`。[#29084](https://github.com/ant-design/ant-design/pull/29084) - Less - - 💄 增加 less 变量 `@progress-info-text-color`。 [#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan) + - 💄 增加 less 变量 `@progress-info-text-color`。[#28981](https://github.com/ant-design/ant-design/pull/28981) [@yuxuan](https://github.com/yuxuan) ## 4.11.3 @@ -1023,7 +1056,7 @@ timeline: true - 🆕 多选模式下 `maxTagCount` 支持 `responsive`。[#28520](https://github.com/ant-design/ant-design/pull/28520) - 🆕 Slider 新增 range.draggableTrack 以支持范围刻度整体可拖拽。[#28592](https://github.com/ant-design/ant-design/pull/28592) - 🆕 `message` 新增 `onClick` 回调,会在消息被点击时触发。[#28148](https://github.com/ant-design/ant-design/pull/28148) [@ZeroTo0ne](https://github.com/ant-design/ant-design/pull/28148) -- 🆕 Descriptions 上可以统一设置 `labelStyle` 和 `contentStyle`。 [#28613](https://github.com/ant-design/ant-design/pull/28613) +- 🆕 Descriptions 上可以统一设置 `labelStyle` 和 `contentStyle`。[#28613](https://github.com/ant-design/ant-design/pull/28613) - 🆕 Form 的 `scrollToFirstError` 属性支持设置滚动的位置参数。[#28272](https://github.com/ant-design/ant-design/pull/28272) [@vouis](https://github.com/vouis) - 🆕 Steps 新增 reponsive 属性用于关闭响应式样式。[#28459](https://github.com/ant-design/ant-design/pull/28459) - 🌐 国际化 @@ -1414,7 +1447,7 @@ timeline: true - 🐞 修复 Form 使用 `help` 时出现的同构问题。[#26542](https://github.com/ant-design/ant-design/pull/26542) - 🐞 修复 Avatar 在 `display: none` 时不会正确缩放 fallback 文字的问题。[#26522](https://github.com/ant-design/ant-design/pull/26522) [@zhangyu1818](https://github.com/zhangyu1818) - TypeScript - - 🤖 Col 增加 `ColSize` 增加 `flex` 的定义。 [#26578](https://github.com/ant-design/ant-design/pull/26578) [@blaiz](https://github.com/blaiz) + - 🤖 Col 增加 `ColSize` 增加 `flex` 的定义。[#26578](https://github.com/ant-design/ant-design/pull/26578) [@blaiz](https://github.com/blaiz) - 🤖 修复 Tooltip/Popover `children` 定义不接受 ReactNode 的问题。[#26534](https://github.com/ant-design/ant-design/pull/26534) ## 4.6.2 diff --git a/components/_util/ActionButton.tsx b/components/_util/ActionButton.tsx index 50540b3c55..45f209602c 100644 --- a/components/_util/ActionButton.tsx +++ b/components/_util/ActionButton.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; +import useState from 'rc-util/lib/hooks/useState'; import Button from '../button'; import { LegacyButtonType, ButtonProps, convertLegacyProps } from '../button/button'; -import useDestroyed from './hooks/useDestroyed'; export interface ActionButtonProps { type?: LegacyButtonType; @@ -21,8 +21,7 @@ function isThenable(thing?: PromiseLike): boolean { const ActionButton: React.FC = props => { const clickedRef = React.useRef(false); const ref = React.useRef(); - const isDestroyed = useDestroyed(); - const [loading, setLoading] = React.useState(false); + const [loading, setLoading] = useState(false); React.useEffect(() => { let timeoutId: any; @@ -45,9 +44,7 @@ const ActionButton: React.FC = props => { setLoading(true); returnValueOfOnOk!.then( (...args: any[]) => { - if (!isDestroyed()) { - setLoading(false); - } + setLoading(false, true); close(...args); clickedRef.current = false; }, @@ -56,9 +53,7 @@ const ActionButton: React.FC = props => { // eslint-disable-next-line no-console console.error(e); // See: https://github.com/ant-design/ant-design/issues/6183 - if (!isDestroyed()) { - setLoading(false); - } + setLoading(false, true); clickedRef.current = false; }, ); diff --git a/components/_util/__tests__/useDestroyed.test.js b/components/_util/__tests__/useDestroyed.test.js deleted file mode 100644 index d98979e49f..0000000000 --- a/components/_util/__tests__/useDestroyed.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { mount } from 'enzyme'; -import React from 'react'; -import useDestroyed from '../hooks/useDestroyed'; - -describe('useMounted', () => { - it('should work properly', () => { - let isDestroyed = null; - - const AutoUnmounted = () => { - isDestroyed = useDestroyed(); - - return
Mounted
; - }; - - const wrapper = mount(); - expect(isDestroyed()).toBeFalsy(); - wrapper.unmount(); - expect(isDestroyed()).toBeTruthy(); - }); -}); diff --git a/components/_util/getDataOrAriaProps.ts b/components/_util/getDataOrAriaProps.ts index ee4e271ec6..1984714db6 100644 --- a/components/_util/getDataOrAriaProps.ts +++ b/components/_util/getDataOrAriaProps.ts @@ -1,8 +1,8 @@ export default function getDataOrAriaProps(props: any) { return Object.keys(props).reduce((prev: any, key: string) => { if ( - (key.substr(0, 5) === 'data-' || key.substr(0, 5) === 'aria-' || key === 'role') && - key.substr(0, 7) !== 'data-__' + (key.startsWith('data-') || key.startsWith('aria-') || key === 'role') && + !key.startsWith('data-__') ) { prev[key] = props[key]; } diff --git a/components/_util/hooks/useDestroyed.ts b/components/_util/hooks/useDestroyed.ts deleted file mode 100644 index 4b361a78ae..0000000000 --- a/components/_util/hooks/useDestroyed.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; - -export default function useDestroyed() { - const mountedRef = React.useRef(true); - - React.useEffect( - () => () => { - mountedRef.current = false; - }, - [], - ); - - return () => !mountedRef.current; -} diff --git a/components/affix/index.tsx b/components/affix/index.tsx index 73d4ba6f48..1be9f0f545 100644 --- a/components/affix/index.tsx +++ b/components/affix/index.tsx @@ -33,6 +33,10 @@ export interface AffixProps { children: React.ReactNode; } +export interface InternalAffixProps extends AffixProps { + affixPrefixCls: string; +} + enum AffixStatus { None, Prepare, @@ -47,7 +51,7 @@ export interface AffixState { prevTarget: Window | HTMLElement | null; } -class Affix extends React.Component { +class Affix extends React.Component { static contextType = ConfigContext; state: AffixState = { @@ -250,14 +254,20 @@ class Affix extends React.Component { // =================== Render =================== render() { - const { getPrefixCls } = this.context; const { affixStyle, placeholderStyle } = this.state; - const { prefixCls, children } = this.props; + const { affixPrefixCls, children } = this.props; const className = classNames({ - [getPrefixCls('affix', prefixCls)]: !!affixStyle, + [affixPrefixCls]: !!affixStyle, }); - let props = omit(this.props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target', 'onChange']); + let props = omit(this.props, [ + 'prefixCls', + 'offsetTop', + 'offsetBottom', + 'target', + 'onChange', + 'affixPrefixCls', + ]); // Omit this since `onTestUpdatePosition` only works on test. if (process.env.NODE_ENV === 'test') { props = omit(props as typeof props & { onTestUpdatePosition: any }, ['onTestUpdatePosition']); @@ -286,7 +296,20 @@ class Affix extends React.Component { } } -const AffixFC = React.forwardRef((props, ref) => ); +const AffixFC = React.forwardRef((props, ref) => { + const { prefixCls: customizePrefixCls } = props; + const { getPrefixCls } = React.useContext(ConfigContext); + + const affixPrefixCls = getPrefixCls('affix', customizePrefixCls); + + const AffixProps: InternalAffixProps = { + ...props, + + affixPrefixCls, + }; + + return ; +}); if (process.env.NODE_ENV !== 'production') { AffixFC.displayName = 'Affix'; diff --git a/components/alert/index.en-US.md b/components/alert/index.en-US.md index d0f9bdcee0..8b8992206b 100644 --- a/components/alert/index.en-US.md +++ b/components/alert/index.en-US.md @@ -21,7 +21,7 @@ Alert component for feedback. | banner | Whether to show as banner | boolean | false | | | closable | Whether Alert can be closed | boolean | - | | | closeText | Close text to show | ReactNode | - | | -| closeIcon | Custom close icon | ReactNode | | 4.17.0 | +| closeIcon | Custom close icon | ReactNode | `` | 4.17.0 | | description | Additional content of Alert | ReactNode | - | | | icon | Custom icon, effective when `showIcon` is true | ReactNode | - | | | message | Content of Alert | ReactNode | - | | diff --git a/components/alert/index.zh-CN.md b/components/alert/index.zh-CN.md index 3f99bfbc33..8946f08330 100644 --- a/components/alert/index.zh-CN.md +++ b/components/alert/index.zh-CN.md @@ -22,7 +22,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/8emPa3fjl/Alert.svg | banner | 是否用作顶部公告 | boolean | false | | | closable | 默认不显示关闭按钮 | boolean | - | | | closeText | 自定义关闭按钮 | ReactNode | - | | -| closeIcon | 自定义关闭 Icon | ReactNode | | 4.17.0 | +| closeIcon | 自定义关闭 Icon | ReactNode | `` | 4.17.0 | | description | 警告提示的辅助性文字介绍 | ReactNode | - | | | icon | 自定义图标,`showIcon` 为 true 时有效 | ReactNode | - | | | message | 警告提示内容 | ReactNode | - | | diff --git a/components/cascader/index.en-US.md b/components/cascader/index.en-US.md index 89acf95517..4113f5dffd 100644 --- a/components/cascader/index.en-US.md +++ b/components/cascader/index.en-US.md @@ -24,6 +24,7 @@ Cascade selection box. | allowClear | Whether allow clear | boolean | true | | | autoFocus | If get focus when component mounted | boolean | false | | | bordered | Whether has border style | boolean | true | | +| clearIcon | The custom clear icon | ReactNode | - | | | changeOnSelect | (Work on single select) Change value on each selection if set to true, see above demo for details | boolean | false | | | className | The additional css class | string | - | | | defaultValue | Initial selected value | string\[] \| number\[] | \[] | | @@ -53,6 +54,7 @@ Cascade selection box. | onChange | Callback when finishing cascader select | (value, selectedOptions) => void | - | | | onDropdownVisibleChange | Callback when popup shown or hidden | (value) => void | - | 4.17.0 | | multiple | Support multiple or not | boolean | - | 4.17.0 | +| removeIcon | The custom remove icon | ReactNode | - | | | searchValue | Set search value,Need work with `showSearch` | string | - | 4.17.0 | | onSearch | The callback function triggered when input changed | (search: string) => void | - | 4.17.0 | | dropdownMenuColumnStyle | The style of the drop-down menu column | CSSProperties | - | | diff --git a/components/cascader/index.zh-CN.md b/components/cascader/index.zh-CN.md index 92988351cd..0b157bc07b 100644 --- a/components/cascader/index.zh-CN.md +++ b/components/cascader/index.zh-CN.md @@ -25,6 +25,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg | allowClear | 是否支持清除 | boolean | true | | | autoFocus | 自动获取焦点 | boolean | false | | | bordered | 是否有边框 | boolean | true | | +| clearIcon | 自定义的选择框清空图标 | ReactNode | - | | | changeOnSelect | (单选时生效)当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示 | boolean | false | | | className | 自定义类名 | string | - | | | defaultValue | 默认的选中项 | string\[] \| number\[] | \[] | | @@ -54,6 +55,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg | onChange | 选择完成后的回调 | (value, selectedOptions) => void | - | | | onDropdownVisibleChange | 显示/隐藏浮层的回调 | (value) => void | - | 4.17.0 | | multiple | 支持多选节点 | boolean | - | 4.17.0 | +| removeIcon | 自定义的多选框清除图标 | ReactNode | - | | | searchValue | 设置搜索的值,需要与 `showSearch` 配合使用 | string | - | 4.17.0 | | onSearch | 监听搜索,返回输入的值 | (search: string) => void | - | 4.17.0 | | dropdownMenuColumnStyle | 下拉菜单列的样式 | CSSProperties | - | | diff --git a/components/collapse/style/index.less b/components/collapse/style/index.less index 6b10c990b8..b92378d523 100644 --- a/components/collapse/style/index.less +++ b/components/collapse/style/index.less @@ -120,6 +120,11 @@ border-radius: 0; } + // hide the last border-bottom in borderless mode + &-borderless > &-item:last-child { + border-bottom: 0; + } + &-borderless > &-item > &-content { background-color: transparent; border-top: 0; diff --git a/components/config-provider/__tests__/__snapshots__/components.test.js.snap b/components/config-provider/__tests__/__snapshots__/components.test.js.snap index fced97b1f2..fddeb0aa1e 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.js.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.js.snap @@ -13802,7 +13802,7 @@ exports[`ConfigProvider components Input configProvider componentSize large 1`] > @@ -21055,6 +21055,7 @@ exports[`ConfigProvider components Select configProvider 1`] = ` >
grp
@@ -21182,6 +21183,7 @@ exports[`ConfigProvider components Select configProvider componentSize large 1`] >
grp
@@ -21309,6 +21311,7 @@ exports[`ConfigProvider components Select configProvider componentSize middle 1` >
grp
@@ -21436,6 +21439,7 @@ exports[`ConfigProvider components Select configProvider virtual and dropdownMat >
grp
@@ -21563,6 +21567,7 @@ exports[`ConfigProvider components Select normal 1`] = ` >
grp
@@ -21690,6 +21695,7 @@ exports[`ConfigProvider components Select prefixCls 1`] = ` >
grp
diff --git a/components/config-provider/__tests__/icon.test.js b/components/config-provider/__tests__/icon.test.js index 5cc87f5ad4..f35cf93636 100644 --- a/components/config-provider/__tests__/icon.test.js +++ b/components/config-provider/__tests__/icon.test.js @@ -16,17 +16,30 @@ describe('ConfigProvider.Icon', () => { }); }); - it('basic', () => { - const wrapper = mount( - - - , - ); + describe('csp', () => { + it('raw', () => { + mount( + + + , + ); - const styleNode = document.querySelector('style'); + const styleNode = document.querySelector('style'); + expect(styleNode.nonce).toEqual('little'); + }); - expect(wrapper.exists('.bamboo-smile')).toBeTruthy(); - expect(styleNode.nonce).toEqual('light'); + it('mix with iconPrefixCls', () => { + const wrapper = mount( + + + , + ); + + const styleNode = document.querySelector('style'); + + expect(wrapper.exists('.bamboo-smile')).toBeTruthy(); + expect(styleNode.nonce).toEqual('light'); + }); }); it('nest', () => { diff --git a/components/config-provider/cssVariables.tsx b/components/config-provider/cssVariables.tsx index e3b3c0c2cb..0ac5228f39 100644 --- a/components/config-provider/cssVariables.tsx +++ b/components/config-provider/cssVariables.tsx @@ -9,7 +9,7 @@ import devWarning from '../_util/devWarning'; const dynamicStyleMark = `-ant-${Date.now()}-${Math.random()}`; -export function registerTheme(globalPrefixCls: string, theme: Theme) { +export function getStyle(globalPrefixCls: string, theme: Theme) { const variables: Record = {}; const formatColor = ( @@ -88,15 +88,18 @@ export function registerTheme(globalPrefixCls: string, theme: Theme) { key => `--${globalPrefixCls}-${key}: ${variables[key]};`, ); - if (canUseDom()) { - updateCSS( - ` + return ` :root { ${cssList.join('\n')} } - `, - `${dynamicStyleMark}-dynamic-theme`, - ); + `.trim(); +} + +export function registerTheme(globalPrefixCls: string, theme: Theme) { + const style = getStyle(globalPrefixCls, theme); + + if (canUseDom()) { + updateCSS(style, `${dynamicStyleMark}-dynamic-theme`); } else { devWarning(false, 'ConfigProvider', 'SSR do not support dynamic theme with css variables.'); } diff --git a/components/config-provider/index.tsx b/components/config-provider/index.tsx index bb98b5164a..cabb83257c 100644 --- a/components/config-provider/index.tsx +++ b/components/config-provider/index.tsx @@ -211,7 +211,7 @@ const ProviderChildren: React.FC = props => { const memoIconContextValue = React.useMemo( () => ({ prefixCls: iconPrefixCls, csp }), - [iconPrefixCls], + [iconPrefixCls, csp], ); let childNode = children; @@ -238,7 +238,7 @@ const ProviderChildren: React.FC = props => { ); } - if (iconPrefixCls) { + if (iconPrefixCls || csp) { childNode = ( {childNode} ); diff --git a/components/date-picker/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/date-picker/__tests__/__snapshots__/demo-extend.test.ts.snap index b690f01b3e..138c12ddcc 100644 --- a/components/date-picker/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/date-picker/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -47810,6 +47810,7 @@ exports[`renders ./components/date-picker/demo/status.md extend context correctl
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+
+
+
+
+
+
+
+
`; diff --git a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap index 924d5c4b64..435ac44b15 100644 --- a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap +++ b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap @@ -3780,6 +3780,7 @@ exports[`renders ./components/date-picker/demo/status.md correctly 1`] = `
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
`; diff --git a/components/date-picker/demo/status.md b/components/date-picker/demo/status.md index cb8ebe7db3..2723908adb 100644 --- a/components/date-picker/demo/status.md +++ b/components/date-picker/demo/status.md @@ -21,6 +21,8 @@ const Status: React.FC = () => ( + + ); diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index 12d9154006..60279b949d 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -6,6 +6,7 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled'; import SwapRightOutlined from '@ant-design/icons/SwapRightOutlined'; import { RangePicker as RCRangePicker } from 'rc-picker'; import { GenerateConfig } from 'rc-picker/lib/generate/index'; +import { PickerMode } from 'rc-picker/lib/interface'; import enUS from '../locale/en_US'; import { ConfigContext, ConfigConsumerProps } from '../../config-provider'; import SizeContext from '../../config-provider/SizeContext'; @@ -13,6 +14,8 @@ import LocaleReceiver from '../../locale-provider/LocaleReceiver'; import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util'; import { RangePickerProps, PickerLocale, getTimeProps, Components } from '.'; import { PickerComponentClass } from './interface'; +import { FormItemStatusContext } from '../../form/context'; +import { getFeedbackIcon, getMergedStatus, getStatusClassNames } from '../../_util/statusUtils'; export default function generateRangePicker( generateConfig: GenerateConfig, @@ -36,6 +39,23 @@ export default function generateRangePicker( } }; + renderFeedback = (prefixCls: string) => ( + + {({ hasFeedback, status: contextStatus }) => { + const { status: customStatus } = this.props; + const status = getMergedStatus(contextStatus, customStatus); + return hasFeedback && getFeedbackIcon(prefixCls, status); + }} + + ); + + renderSuffix = (prefixCls: string, mergedPicker?: PickerMode) => ( + <> + {mergedPicker === 'time' ? : } + {this.renderFeedback(prefixCls)} + + ); + renderPicker = (contextLocale: PickerLocale) => { const locale = { ...contextLocale, ...this.props.locale }; const { getPrefixCls, direction, getPopupContainer } = this.context; @@ -47,6 +67,7 @@ export default function generateRangePicker( size: customizeSize, bordered = true, placeholder, + status: customStatus, ...restProps } = this.props; const { format, showTime, picker } = this.props as any; @@ -67,39 +88,48 @@ export default function generateRangePicker( const mergedSize = customizeSize || size; return ( - - separator={ - - - - } - ref={this.pickerRef} - dropdownAlign={transPlacement2DropdownAlign(direction, placement)} - placeholder={getRangePlaceholder(picker, locale, placeholder)} - suffixIcon={picker === 'time' ? : } - clearIcon={} - prevIcon={} - nextIcon={} - superPrevIcon={} - superNextIcon={} - allowClear - transitionName={`${rootPrefixCls}-slide-up`} - {...restProps} - {...additionalOverrideProps} - className={classNames( - { - [`${prefixCls}-${mergedSize}`]: mergedSize, - [`${prefixCls}-borderless`]: !bordered, - }, - className, + + {({ hasFeedback, status: contextStatus }) => ( + + separator={ + + + + } + ref={this.pickerRef} + dropdownAlign={transPlacement2DropdownAlign(direction, placement)} + placeholder={getRangePlaceholder(picker, locale, placeholder)} + suffixIcon={this.renderSuffix(prefixCls, picker)} + clearIcon={} + prevIcon={} + nextIcon={} + superPrevIcon={} + superNextIcon={} + allowClear + transitionName={`${rootPrefixCls}-slide-up`} + {...restProps} + {...additionalOverrideProps} + className={classNames( + { + [`${prefixCls}-${mergedSize}`]: mergedSize, + [`${prefixCls}-borderless`]: !bordered, + }, + getStatusClassNames( + prefixCls, + getMergedStatus(contextStatus, customStatus), + hasFeedback, + ), + className, + )} + locale={locale!.lang} + prefixCls={prefixCls} + getPopupContainer={customGetPopupContainer || getPopupContainer} + generateConfig={generateConfig} + components={Components} + direction={direction} + /> )} - locale={locale!.lang} - prefixCls={prefixCls} - getPopupContainer={customGetPopupContainer || getPopupContainer} - generateConfig={generateConfig} - components={Components} - direction={direction} - /> + ); }} diff --git a/components/date-picker/generatePicker/index.tsx b/components/date-picker/generatePicker/index.tsx index 643a848f61..d675613fd7 100644 --- a/components/date-picker/generatePicker/index.tsx +++ b/components/date-picker/generatePicker/index.tsx @@ -18,6 +18,7 @@ import { TimePickerLocale } from '../../time-picker'; import generateSinglePicker from './generateSinglePicker'; import generateRangePicker from './generateRangePicker'; import { tuple } from '../../_util/type'; +import { InputStatus } from '../../_util/statusUtils'; export const Components = { button: PickerButton, rangeItem: PickerTag }; @@ -81,6 +82,7 @@ type InjectDefaultProps = Omit< size?: SizeType; placement?: DataPickerPlacement; bordered?: boolean; + status?: InputStatus; }; export type PickerLocale = { diff --git a/components/dropdown/__tests__/index.test.js b/components/dropdown/__tests__/index.test.js index dc97a9bb8f..a4009c40ae 100644 --- a/components/dropdown/__tests__/index.test.js +++ b/components/dropdown/__tests__/index.test.js @@ -79,4 +79,24 @@ describe('Dropdown', () => { expect.stringContaining("[antd: Dropdown] You are using 'topCenter'"), ); }); + + // zombieJ: when replaced with react test lib, it may be mock fully content + it('dropdown should support auto adjust placement', () => { + const wrapper = mount( + menu
} visible> + + , + ); + + expect(wrapper.find('Trigger').prop('builtinPlacements')).toEqual( + expect.objectContaining({ + bottomLeft: expect.objectContaining({ + overflow: { + adjustX: 1, + adjustY: 1, + }, + }), + }), + ); + }); }); diff --git a/components/dropdown/dropdown.tsx b/components/dropdown/dropdown.tsx index fd4e096893..20cf3a9356 100644 --- a/components/dropdown/dropdown.tsx +++ b/components/dropdown/dropdown.tsx @@ -189,6 +189,7 @@ const Dropdown: DropdownInterface = props => { const builtinPlacements = getPlacements({ arrowPointAtCenter: typeof arrow === 'object' && arrow.pointAtCenter, + autoAdjustOverflow: true, }); return ( diff --git a/components/form/FormItem.tsx b/components/form/FormItem.tsx index d8395ba358..2e64434ece 100644 --- a/components/form/FormItem.tsx +++ b/components/form/FormItem.tsx @@ -5,6 +5,7 @@ import { Field, FormInstance, FieldContext, ListContext } from 'rc-field-form'; import { FieldProps } from 'rc-field-form/lib/Field'; import { Meta, NamePath } from 'rc-field-form/lib/interface'; import { supportRef } from 'rc-util/lib/ref'; +import useState from 'rc-util/lib/hooks/useState'; import omit from 'rc-util/lib/omit'; import Row from '../grid/row'; import { ConfigContext } from '../config-provider'; @@ -132,7 +133,7 @@ function FormItem(props: FormItemProps): React.ReactElemen const [subFieldErrors, setSubFieldErrors] = useFrameState>({}); // >>>>> Current field errors - const [meta, setMeta] = React.useState(() => genEmptyMeta()); + const [meta, setMeta] = useState(() => genEmptyMeta()); const onMetaChange = (nextMeta: Meta & { destroy?: boolean }) => { // This keyInfo is not correct when field is removed @@ -141,7 +142,7 @@ function FormItem(props: FormItemProps): React.ReactElemen const keyInfo = listContext?.getKey(nextMeta.name); // Destroy will reset all the meta - setMeta(nextMeta.destroy ? genEmptyMeta() : nextMeta); + setMeta(nextMeta.destroy ? genEmptyMeta() : nextMeta, true); // Bump to parent since noStyle if (noStyle && notifyParentMetaChange) { diff --git a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap index 716c00ce29..260c24f505 100644 --- a/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/form/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -18730,6 +18730,1234 @@ exports[`renders ./components/form/demo/validate-static.md extend context correc
+
+
+ +
+
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+
+
+
+
+
+ + +
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+ 8 +
+
+
+ 9 +
+
+
+ 10 +
+
+
+ 11 +
+
+
+ 12 +
+
+
+ 13 +
+
+
+ 14 +
+
+
+ 15 +
+
+
+ 16 +
+
+
+ 17 +
+
+
+ 18 +
+
+
+ 19 +
+
+
+ 20 +
+
+
+ 21 +
+
+
+ 22 +
+
+
+ 23 +
+
+
+ 24 +
+
+
+ 25 +
+
+
+ 26 +
+
+
+ 27 +
+
+
+ 28 +
+
+
+ 29 +
+
+
+ 30 +
+
+
+ 31 +
+
+
+ 1 +
+
+
+ 2 +
+
+
+ 3 +
+
+
+ 4 +
+
+
+ 5 +
+
+
+ 6 +
+
+
+ 7 +
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/form/__tests__/__snapshots__/demo.test.js.snap b/components/form/__tests__/__snapshots__/demo.test.js.snap index 7f0aeb06b7..68b60453d2 100644 --- a/components/form/__tests__/__snapshots__/demo.test.js.snap +++ b/components/form/__tests__/__snapshots__/demo.test.js.snap @@ -7872,6 +7872,137 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
+
+
+ +
+
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + + + + + + +
+
+
+
+
diff --git a/components/form/__tests__/list.test.js b/components/form/__tests__/list.test.js index bcb3ad0006..8f7778b0c6 100644 --- a/components/form/__tests__/list.test.js +++ b/components/form/__tests__/list.test.js @@ -1,6 +1,8 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; +import { render, fireEvent } from '@testing-library/react'; +import '@testing-library/jest-dom'; import Form from '..'; import Input from '../../input'; import Button from '../../button'; @@ -204,4 +206,52 @@ describe('Form.List', () => { const wrapper = mount(); expect(wrapper.render()).toMatchSnapshot(); }); + + it('no warning when reset in validate', async () => { + const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + + const Demo = () => { + const [form] = Form.useForm(); + + React.useEffect(() => { + form.setFieldsValue({ + list: [1], + }); + }, []); + + return ( +
+ + {fields => + fields.map(field => ( + + + + )) + } + + +
+ ); + }; + + const { container } = render(); + fireEvent.click(container.querySelector('button')); + + await sleep(); + + expect(errorSpy).not.toHaveBeenCalled(); + + errorSpy.mockRestore(); + }); }); diff --git a/components/form/context.tsx b/components/form/context.tsx index 8ba6d2ac6b..6ce2ac970d 100644 --- a/components/form/context.tsx +++ b/components/form/context.tsx @@ -3,6 +3,7 @@ import omit from 'rc-util/lib/omit'; import { Meta } from 'rc-field-form/lib/interface'; import { FormProvider as RcFormProvider } from 'rc-field-form'; import { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext'; +import { FC, PropsWithChildren, useMemo } from 'react'; import { ColProps } from '../grid/col'; import { FormLabelAlign } from './interface'; import { RequiredMark } from './Form'; @@ -57,3 +58,11 @@ export interface FormItemStatusContextProps { } export const FormItemStatusContext = React.createContext({}); + +export const NoFormStatus: FC> = ({ children }: PropsWithChildren<{}>) => { + const emptyContext = useMemo(() => ({}), []); + + return ( + {children} + ); +}; diff --git a/components/form/demo/validate-static.md b/components/form/demo/validate-static.md index 286960f9eb..b0efda9da6 100644 --- a/components/form/demo/validate-static.md +++ b/components/form/demo/validate-static.md @@ -96,6 +96,10 @@ ReactDOM.render( + + + + @@ -163,7 +163,7 @@ exports[`Input.Password should support size 1`] = ` > diff --git a/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap index 4e11e49cdf..308b8d76d7 100644 --- a/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/input/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -5009,7 +5009,7 @@ exports[`renders ./components/input/demo/borderless-debug.md extend context corr class="ant-input-affix-wrapper ant-input-affix-wrapper-borderless" > @@ -5072,7 +5072,7 @@ exports[`renders ./components/input/demo/borderless-debug.md extend context corr ¥ @@ -1289,7 +1289,7 @@ exports[`renders ./components/input/demo/borderless-debug.md correctly 1`] = ` ¥ { }); it('select()', () => { - const ref = React.createRef(); + const ref = React.createRef(); mount(); ref.current?.select(); }); @@ -55,7 +55,7 @@ describe('Input', () => { describe('focus trigger warning', () => { it('not trigger', () => { const wrapper = mount(); - wrapper.find('input').instance().focus(); + (wrapper.find('input').instance() as any).focus(); wrapper.setProps({ suffix: 'light', }); @@ -63,7 +63,7 @@ describe('Input', () => { }); it('trigger warning', () => { const wrapper = mount(); - wrapper.find('input').first().getDOMNode().focus(); + wrapper.find('input').first().getDOMNode().focus(); wrapper.setProps({ suffix: 'light', }); @@ -77,11 +77,11 @@ describe('Input', () => { it('set mouse cursor position', () => { const defaultValue = '11111'; const valLength = defaultValue.length; - const ref = React.createRef(); + const ref = React.createRef(); const wrapper = mount(); ref.current?.setSelectionRange(valLength, valLength); - expect(wrapper.find('input').first().getDOMNode().selectionStart).toEqual(5); - expect(wrapper.find('input').first().getDOMNode().selectionEnd).toEqual(5); + expect(wrapper.find('input').first().getDOMNode().selectionStart).toEqual(5); + expect(wrapper.find('input').first().getDOMNode().selectionEnd).toEqual(5); }); }); @@ -106,8 +106,12 @@ describe('prefix and suffix', () => { , ); - expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode().hidden).toBe(true); - expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode().hidden).toBe(true); + expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode().hidden).toBe( + true, + ); + expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode().hidden).toBe( + true, + ); }); }); @@ -143,6 +147,7 @@ describe('Input setting hidden', () => { showCount allowClear prefix="11" + // @ts-ignore suffix="22" addonBefore="http://" addonAfter=".com" @@ -162,10 +167,10 @@ describe('Input setting hidden', () => { , ); - expect(wrapper.find('.input').at(0).getDOMNode().hidden).toBe(true); - expect(wrapper.find('.input-search').at(0).getDOMNode().hidden).toBe(true); - expect(wrapper.find('.input-textarea').at(0).getDOMNode().hidden).toBe(true); - expect(wrapper.find('.input-password').at(0).getDOMNode().hidden).toBe(true); + expect(wrapper.find('.input').at(0).getDOMNode().hidden).toBe(true); + expect(wrapper.find('.input-search').at(0).getDOMNode().hidden).toBe(true); + expect(wrapper.find('.input-textarea').at(0).getDOMNode().hidden).toBe(true); + expect(wrapper.find('.input-password').at(0).getDOMNode().hidden).toBe(true); }); }); @@ -250,17 +255,18 @@ describe('Input allowClear', () => { it('should change type when click', () => { const wrapper = mount(); wrapper.find('input').simulate('change', { target: { value: '111' } }); - expect(wrapper.find('input').getDOMNode().value).toEqual('111'); + expect(wrapper.find('input').getDOMNode().value).toEqual('111'); expect(wrapper.render()).toMatchSnapshot(); wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); expect(wrapper.render()).toMatchSnapshot(); - expect(wrapper.find('input').getDOMNode().value).toEqual(''); + expect(wrapper.find('input').getDOMNode().value).toEqual(''); }); it('should not show icon if value is undefined, null or empty string', () => { + // @ts-ignore const wrappers = [null, undefined, ''].map(val => mount()); wrappers.forEach(wrapper => { - expect(wrapper.find('input').getDOMNode().value).toEqual(''); + expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy(); expect(wrapper.render()).toMatchSnapshot(); }); @@ -268,41 +274,43 @@ describe('Input allowClear', () => { it('should not show icon if defaultValue is undefined, null or empty string', () => { const wrappers = [null, undefined, ''].map(val => + // @ts-ignore mount(), ); wrappers.forEach(wrapper => { - expect(wrapper.find('input').getDOMNode().value).toEqual(''); + expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy(); expect(wrapper.render()).toMatchSnapshot(); }); }); it('should trigger event correctly', () => { - let argumentEventObject; + let argumentEventObject: React.ChangeEvent | undefined; + let argumentEventObjectValue; - const onChange = e => { + const onChange: InputProps['onChange'] = e => { argumentEventObject = e; argumentEventObjectValue = e.target.value; }; const wrapper = mount(); wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); - expect(argumentEventObject.type).toBe('click'); + expect(argumentEventObject?.type).toBe('click'); expect(argumentEventObjectValue).toBe(''); - expect(wrapper.find('input').at(0).getDOMNode().value).toBe(''); + expect(wrapper.find('input').at(0).getDOMNode().value).toBe(''); }); it('should trigger event correctly on controlled mode', () => { - let argumentEventObject; + let argumentEventObject: React.ChangeEvent | undefined; let argumentEventObjectValue; - const onChange = e => { + const onChange: InputProps['onChange'] = e => { argumentEventObject = e; argumentEventObjectValue = e.target.value; }; const wrapper = mount(); wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); - expect(argumentEventObject.type).toBe('click'); + expect(argumentEventObject?.type).toBe('click'); expect(argumentEventObjectValue).toBe(''); - expect(wrapper.find('input').at(0).getDOMNode().value).toBe('111'); + expect(wrapper.find('input').at(0).getDOMNode().value).toBe('111'); }); it('should focus input after clear', () => { @@ -332,12 +340,12 @@ describe('Input allowClear', () => { const wrapper = mount(, { attachTo: document.body, }); - wrapper.find('input').getDOMNode().focus(); + wrapper.find('input').getDOMNode().focus(); wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseDown'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseUp'); wrapper.find('.ant-input-clear-icon').at(0).simulate('focus'); - wrapper.find('.ant-input-clear-icon').at(0).getDOMNode().click(); + wrapper.find('.ant-input-clear-icon').at(0).getDOMNode().click(); expect(onBlur).not.toBeCalled(); wrapper.unmount(); }); @@ -359,12 +367,12 @@ describe('Input allowClear', () => { const wrapper = mount(); - wrapper.find('input').getDOMNode().focus(); + wrapper.find('input').getDOMNode().focus(); wrapper.find('input').simulate('change', { target: { value: '111' } }); - expect(wrapper.find('input').getDOMNode().value).toEqual('111'); + expect(wrapper.find('input').getDOMNode().value).toEqual('111'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); - expect(wrapper.find('input').getDOMNode().value).toEqual(''); + expect(wrapper.find('input').getDOMNode().value).toEqual(''); wrapper.unmount(); }); @@ -375,10 +383,11 @@ describe('Input allowClear', () => { }); it('should display boolean value as string', () => { + // @ts-ignore const wrapper = mount(); - expect(wrapper.find('input').first().getDOMNode().value).toBe('true'); + expect(wrapper.find('input').first().getDOMNode().value).toBe('true'); wrapper.setProps({ value: false }); - expect(wrapper.find('input').first().getDOMNode().value).toBe('false'); + expect(wrapper.find('input').first().getDOMNode().value).toBe('false'); }); it('should support custom clearIcon', () => { @@ -386,3 +395,19 @@ describe('Input allowClear', () => { expect(wrapper.find('.ant-input-clear-icon').text()).toBe('clear'); }); }); + +describe('typescript types ', () => { + it('InputProps type should support data-* attributes', () => { + const props: InputProps = { + value: 123, + + // expect no ts error here + 'data-testid': 'test-id', + 'data-id': '12345', + }; + const wrapper = mount(); + const input = wrapper.find('input').first().getDOMNode(); + expect(input.getAttribute('data-testid')).toBe('test-id'); + expect(input.getAttribute('data-id')).toBe('12345'); + }); +}); diff --git a/components/input/style/index.less b/components/input/style/index.less index d01262ccb3..9058d32a19 100644 --- a/components/input/style/index.less +++ b/components/input/style/index.less @@ -25,7 +25,7 @@ } } - &-password-icon { + &-password-icon.@{iconfont-css-prefix} { color: @text-color-secondary; cursor: pointer; transition: all 0.3s; diff --git a/components/list/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/list/__tests__/__snapshots__/demo-extend.test.ts.snap index aa3ca01c87..50ee5b75aa 100644 --- a/components/list/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/list/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1164,7 +1164,7 @@ exports[`renders ./components/list/demo/loadmore.md extend context correctly 1`]
`; -exports[`renders ./components/list/demo/resposive.md extend context correctly 1`] = ` +exports[`renders ./components/list/demo/responsive.md extend context correctly 1`] = `
diff --git a/components/list/__tests__/__snapshots__/demo.test.js.snap b/components/list/__tests__/__snapshots__/demo.test.js.snap index a5bf1614ec..f0c8174f2c 100644 --- a/components/list/__tests__/__snapshots__/demo.test.js.snap +++ b/components/list/__tests__/__snapshots__/demo.test.js.snap @@ -1164,7 +1164,7 @@ exports[`renders ./components/list/demo/loadmore.md correctly 1`] = `
`; -exports[`renders ./components/list/demo/resposive.md correctly 1`] = ` +exports[`renders ./components/list/demo/responsive.md correctly 1`] = `
diff --git a/components/list/demo/resposive.md b/components/list/demo/responsive.md similarity index 100% rename from components/list/demo/resposive.md rename to components/list/demo/responsive.md diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 1b436d79df..f02197a7ef 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -3,15 +3,14 @@ import RcMenu, { ItemGroup, MenuProps as RcMenuProps } from 'rc-menu'; import classNames from 'classnames'; import omit from 'rc-util/lib/omit'; import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined'; -import memoize from 'memoize-one'; import SubMenu, { SubMenuProps } from './SubMenu'; import Item, { MenuItemProps } from './MenuItem'; -import { ConfigConsumer, ConfigConsumerProps, DirectionType } from '../config-provider'; +import { ConfigContext } from '../config-provider'; import devWarning from '../_util/devWarning'; import { SiderContext, SiderContextProps } from '../layout/Sider'; import collapseMotion from '../_util/motion'; import { cloneElement } from '../_util/reactNode'; -import MenuContext, { MenuTheme, MenuContextProps } from './MenuContext'; +import MenuContext, { MenuTheme } from './MenuContext'; import MenuDivider from './MenuDivider'; export { MenuDividerProps } from './MenuDivider'; @@ -37,108 +36,87 @@ type InternalMenuProps = MenuProps & collapsedWidth?: string | number; }; -class InternalMenu extends React.Component { - static defaultProps: Partial = { - theme: 'light', // or dark - }; +function InternalMenu(props: InternalMenuProps) { + const { getPrefixCls, getPopupContainer, direction } = React.useContext(ConfigContext); - constructor(props: InternalMenuProps) { - super(props); + const rootPrefixCls = getPrefixCls(); - devWarning( - !('inlineCollapsed' in props && props.mode !== 'inline'), - 'Menu', - '`inlineCollapsed` should only be used when `mode` is inline.', - ); + const { + prefixCls: customizePrefixCls, + className, + theme = 'light', + expandIcon, + _internalDisableMenuItemTitleTooltip, + inlineCollapsed, + siderCollapsed, + ...restProps + } = props; - devWarning( - !(props.siderCollapsed !== undefined && 'inlineCollapsed' in props), - 'Menu', - '`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.', - ); - } + const passedProps = omit(restProps, ['collapsedWidth']); - getInlineCollapsed() { - const { inlineCollapsed, siderCollapsed } = this.props; + // ======================== Warning ========================== + devWarning( + !('inlineCollapsed' in props && props.mode !== 'inline'), + 'Menu', + '`inlineCollapsed` should only be used when `mode` is inline.', + ); + + devWarning( + !(props.siderCollapsed !== undefined && 'inlineCollapsed' in props), + 'Menu', + '`inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.', + ); + + // ======================== Collapsed ======================== + // Inline Collapsed + const mergedInlineCollapsed = React.useMemo(() => { if (siderCollapsed !== undefined) { return siderCollapsed; } return inlineCollapsed; - } + }, [inlineCollapsed, siderCollapsed]); - getMemoizedContextValue = memoize( - ( - cls: string, - collapsed: boolean | undefined, - the: MenuTheme | undefined, - dir: DirectionType, - disableMenuItemTitleTooltip: boolean | undefined, - ): MenuContextProps => ({ - prefixCls: cls, - inlineCollapsed: collapsed || false, - antdMenuTheme: the, - direction: dir, - firstLevel: true, - disableMenuItemTitleTooltip, - }), - ); - - renderMenu = ({ getPopupContainer, getPrefixCls, direction }: ConfigConsumerProps) => { - const rootPrefixCls = getPrefixCls(); - - const { - prefixCls: customizePrefixCls, - className, - theme, - expandIcon, - _internalDisableMenuItemTitleTooltip, - ...restProps - } = this.props; - - const passedProps = omit(restProps, ['siderCollapsed', 'collapsedWidth']); - const inlineCollapsed = this.getInlineCollapsed(); - - const defaultMotions = { - horizontal: { motionName: `${rootPrefixCls}-slide-up` }, - inline: collapseMotion, - other: { motionName: `${rootPrefixCls}-zoom-big` }, - }; - - const prefixCls = getPrefixCls('menu', customizePrefixCls); - const menuClassName = classNames(`${prefixCls}-${theme}`, className); - - // TODO: refactor menu with function component - const contextValue = this.getMemoizedContextValue( - prefixCls, - inlineCollapsed, - theme, - direction, - _internalDisableMenuItemTitleTooltip, - ); - - return ( - - } - overflowedIndicatorPopupClassName={`${prefixCls}-${theme}`} - {...passedProps} - inlineCollapsed={inlineCollapsed} - className={menuClassName} - prefixCls={prefixCls} - direction={direction} - defaultMotions={defaultMotions} - expandIcon={cloneElement(expandIcon, { - className: `${prefixCls}-submenu-expand-icon`, - })} - /> - - ); + const defaultMotions = { + horizontal: { motionName: `${rootPrefixCls}-slide-up` }, + inline: collapseMotion, + other: { motionName: `${rootPrefixCls}-zoom-big` }, }; - render() { - return {this.renderMenu}; - } + const prefixCls = getPrefixCls('menu', customizePrefixCls); + const menuClassName = classNames(`${prefixCls}-${theme}`, className); + + // ======================== Context ========================== + const contextValue = React.useMemo( + () => ({ + prefixCls, + inlineCollapsed: mergedInlineCollapsed || false, + antdMenuTheme: theme, + direction, + firstLevel: true, + disableMenuItemTitleTooltip: _internalDisableMenuItemTitleTooltip, + }), + [prefixCls, mergedInlineCollapsed, theme, direction, _internalDisableMenuItemTitleTooltip], + ); + + // ========================= Render ========================== + return ( + + } + overflowedIndicatorPopupClassName={`${prefixCls}-${theme}`} + {...passedProps} + inlineCollapsed={mergedInlineCollapsed} + className={menuClassName} + prefixCls={prefixCls} + direction={direction} + defaultMotions={defaultMotions} + expandIcon={cloneElement(expandIcon, { + className: `${prefixCls}-submenu-expand-icon`, + })} + /> + + ); } // We should keep this as ref-able diff --git a/components/page-header/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/page-header/__tests__/__snapshots__/demo-extend.test.ts.snap index c0ea115d5a..9b2dcf810a 100644 --- a/components/page-header/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/page-header/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -58,30 +58,48 @@ Array [ - - - +
+ +
+
+ +
+
+ +
+
- - - +
+ +
+
+ +
+
+ +
+
- - - - -
- - +
+ +
+
+ +
+
+ +
+
+
-
-
- -
-
-
- - - +
+ +
+
+ +
+
+ +
+
- - - - + + Operation + + +
+
+ +
+
+ +
+
+ +
+
- - - +
+ +
+
+ +
+
+ +
+
- - - +
+ +
+
+ +
+
+ +
+
( - - + +
)} - {extra && {extra}} + {extra && ( + + {extra} + + )}
); }; @@ -121,12 +126,9 @@ const renderChildren = (prefixCls: string, children: React.ReactNode) => ( ); const PageHeader: React.FC = props => { - const [compact, updateCompact] = React.useState(false); - const isDestroyed = useDestroyed(); + const [compact, updateCompact] = useState(false); const onResize = ({ width }: { width: number }) => { - if (!isDestroyed()) { - updateCompact(width < 768); - } + updateCompact(width < 768, true); }; return ( diff --git a/components/page-header/style/index.less b/components/page-header/style/index.less index 6eeedec96f..074145756c 100644 --- a/components/page-header/style/index.less +++ b/components/page-header/style/index.less @@ -87,13 +87,8 @@ white-space: nowrap; > * { - margin-left: @margin-sm; white-space: unset; } - - > *:first-child { - margin-left: 0; - } } } diff --git a/components/page-header/style/index.tsx b/components/page-header/style/index.tsx index 8ca5d47ad6..cd4e5ba32d 100644 --- a/components/page-header/style/index.tsx +++ b/components/page-header/style/index.tsx @@ -3,3 +3,4 @@ import './index.less'; // style dependencies import '../../breadcrumb/style'; import '../../avatar/style'; +import '../../space/style'; diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 24cffb7940..afc2ecc050 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -13,7 +13,6 @@ import { getRenderPropValue, RenderFunction } from '../_util/getRenderPropValue' import { cloneElement } from '../_util/reactNode'; import { getTransitionName } from '../_util/motion'; import ActionButton from '../_util/ActionButton'; -import useDestroyed from '../_util/hooks/useDestroyed'; export interface PopconfirmProps extends AbstractTooltipProps { title: React.ReactNode | RenderFunction; @@ -49,15 +48,13 @@ const Popconfirm = React.forwardRef((props, ref) => { defaultValue: props.defaultVisible, }); - const isDestroyed = useDestroyed(); + // const isDestroyed = useDestroyed(); const settingVisible = ( value: boolean, e?: React.MouseEvent | React.KeyboardEvent, ) => { - if (!isDestroyed()) { - setVisible(value); - } + setVisible(value, true); props.onVisibleChange?.(value, e); }; diff --git a/components/select/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/select/__tests__/__snapshots__/demo-extend.test.ts.snap index 466c0ddbb7..828b8fa6b0 100644 --- a/components/select/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/select/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -3815,6 +3815,7 @@ exports[`renders ./components/select/demo/optgroup.md extend context correctly 1 >
Manager
@@ -3854,6 +3855,7 @@ exports[`renders ./components/select/demo/optgroup.md extend context correctly 1
Engineer
diff --git a/components/select/demo/custom-dropdown-menu.md b/components/select/demo/custom-dropdown-menu.md index e0ed7a91be..3b8e6e9ea8 100644 --- a/components/select/demo/custom-dropdown-menu.md +++ b/components/select/demo/custom-dropdown-menu.md @@ -7,11 +7,11 @@ title: ## zh-CN -使用 `dropdownRender` 对下拉菜单进行自由扩展。 +使用 `dropdownRender` 对下拉菜单进行自由扩展。自定义内容点击时会关闭浮层,如果不喜欢关闭,可以添加 `onMouseDown={e => e.preventDefault()}` 进行阻止(更多详情见 [#13448](https://github.com/ant-design/ant-design/issues/13448))。 ## en-US -Customize the dropdown menu via `dropdownRender`. +Customize the dropdown menu via `dropdownRender`. Dropdown menu will be closed if click `dropdownRender` area, you can prevent it by wrapping `onMouseDown={e => e.preventDefault()}` (see more at [#13448](https://github.com/ant-design/ant-design/issues/13448)). ```jsx import React, { useState } from 'react'; diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md index 90c686ed49..5638cf67d0 100644 --- a/components/select/index.en-US.md +++ b/components/select/index.en-US.md @@ -37,7 +37,7 @@ Select component to select value from options. | dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | | | dropdownRender | Customize dropdown content | (originNode: ReactNode) => ReactNode | - | | | dropdownStyle | The style of dropdown menu | CSSProperties | - | | -| fieldNames | Customize node title, key, options field name | object | { label: `label`, key: `key`, options: `options` } | 4.17.0 | +| fieldNames | Customize node label, value, options field name | object | { label: `label`, value: `value`, options: `options` } | 4.17.0 | | filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| function(inputValue, option) | true | | | filterSort | Sort function for search options sorting, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction | (optionA: Option, optionB: Option) => number | - | 4.9.0 | | getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [Example](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | | @@ -113,7 +113,7 @@ It's caused by option with different `label` and `value`. You can use `optionFil ### The dropdown is closed when click `dropdownRender` area? -See the instruction in [dropdownRender example](#components-select-demo-custom-dropdown-menu). +Dropdown menu will be closed if click `dropdownRender` area, you can prevent it by wrapping `onMouseDown={e => e.preventDefault()}` (see more at [#13448](https://github.com/ant-design/ant-design/issues/13448)). ### Why sometime customize Option cause scroll break? diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md index 280c7c5fd6..91cb942bf1 100644 --- a/components/select/index.zh-CN.md +++ b/components/select/index.zh-CN.md @@ -38,7 +38,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg | dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | | | dropdownRender | 自定义下拉框内容 | (originNode: ReactNode) => ReactNode | - | | | dropdownStyle | 下拉菜单的 style 属性 | CSSProperties | - | | -| fieldNames | 自定义节点 label、key、options 的字段 | object | { label: `label`, key: `key`, options: `options` } | 4.17.0 | +| fieldNames | 自定义节点 label、value、options 的字段 | object | { label: `label`, value: `value`, options: `options` } | 4.17.0 | | filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true,反之则返回 false | boolean \| function(inputValue, option) | true | | | filterSort | 搜索时对筛选结果项的排序函数, 类似[Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)里的 compareFunction | (optionA: Option, optionB: Option) => number | - | 4.9.0 | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | | @@ -114,7 +114,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_0XzgOis7/Select.svg ### 点击 `dropdownRender` 里的内容浮层关闭怎么办? -看下 [dropdownRender 例子](#components-select-demo-custom-dropdown-menu) 里的说明。 +自定义内容点击时会关闭浮层,如果不喜欢关闭,可以添加 `onMouseDown={e => e.preventDefault()}` 进行阻止(更多详情见 [#13448](https://github.com/ant-design/ant-design/issues/13448))。 ### 自定义 Option 样式导致滚动异常怎么办? diff --git a/components/select/style/status.less b/components/select/style/status.less index cf528508d6..728b3e7acb 100644 --- a/components/select/style/status.less +++ b/components/select/style/status.less @@ -25,56 +25,52 @@ } } -.select-status-base(@prefix-cls) { - .@{prefix-cls} { - &-status-error { - .select-status-color(@error-color, @error-color, @select-background, @error-color-hover, @error-color-outline); - } +.@{select-prefix-cls} { + &-status-error { + .select-status-color(@error-color, @error-color, @select-background, @error-color-hover, @error-color-outline); + } - &-status-warning { - .select-status-color(@warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline); - } + &-status-warning { + .select-status-color(@warning-color, @warning-color, @input-bg, @warning-color-hover, @warning-color-outline); + } - &-status-success { - .@{prefix-cls}-feedback-icon { - color: @success-color; + &-status-success { + .@{select-prefix-cls}-feedback-icon { + color: @success-color; + } + } + + &-status-validating { + .@{select-prefix-cls}-feedback-icon { + color: @primary-color; + } + } + + &-status-error, + &-status-warning, + &-status-success, + &-status-validating { + &.@{select-prefix-cls}-has-feedback { + //.@{prefix-cls}-arrow, + .@{select-prefix-cls}-clear { + right: 32px; } - } - &-status-validating { - .@{prefix-cls}-feedback-icon { - color: @primary-color; - } - } - - &-status-error, - &-status-warning, - &-status-success, - &-status-validating { - &.@{prefix-cls}-has-feedback { - //.@{prefix-cls}-arrow, - .@{prefix-cls}-clear { - right: 32px; - } - - .@{prefix-cls}-selection-selected-value { - padding-right: 42px; - } - } - } - - &-feedback-icon { - font-size: @font-size-base; - text-align: center; - visibility: visible; - animation: zoomIn 0.3s @ease-out-back; - pointer-events: none; - - &:not(:first-child) { - margin-left: 8px; + .@{select-prefix-cls}-selection-selected-value { + padding-right: 42px; } } } -} -.select-status-base(@select-prefix-cls); + &-feedback-icon { + font-size: @font-size-base; + text-align: center; + visibility: visible; + animation: zoomIn 0.3s @ease-out-back; + pointer-events: none; + + &:not(:first-child) { + margin-left: 8px; + } + } +} diff --git a/components/spin/index.en-US.md b/components/spin/index.en-US.md index 30b1bc069b..5e54162d9c 100644 --- a/components/spin/index.en-US.md +++ b/components/spin/index.en-US.md @@ -18,7 +18,7 @@ When part of the page is waiting for asynchronous data or during a rendering pro | delay | Specifies a delay in milliseconds for loading state (prevent flush) | number (milliseconds) | - | | indicator | React node of the spinning indicator | ReactNode | - | | size | The size of Spin, options: `small`, `default` and `large` | string | `default` | -| spinning | Whether Spin is spinning | boolean | true | +| spinning | Whether Spin is visible | boolean | true | | tip | Customize description content when Spin has children | ReactNode | - | | wrapperClassName | The className of wrapper when Spin has children | string | - | diff --git a/components/style/themes/default.less b/components/style/themes/default.less index fce17ec46d..8f6dbfd01c 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -516,7 +516,7 @@ // Tooltip background color @tooltip-bg: rgba(0, 0, 0, 0.75); // Tooltip arrow width -@tooltip-arrow-width: 5px; +@tooltip-arrow-width: 8px * sqrt(2); // Tooltip distance with trigger @tooltip-distance: @tooltip-arrow-width - 1px + 4px; // Tooltip arrow color @@ -532,7 +532,7 @@ @popover-min-width: 177px; @popover-min-height: 32px; // Popover arrow width -@popover-arrow-width: 6px; +@popover-arrow-width: @tooltip-arrow-width; // Popover arrow color @popover-arrow-color: @popover-bg; // Popover outer arrow width diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index c19fce6262..0858b4bc07 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -62,7 +62,7 @@ const columns = [ | --- | --- | --- | --- | --- | | bordered | Whether to show all table borders | boolean | false | | | columns | Columns of table | [ColumnsType](#Column)\[] | - | | -| components | Override default table elements | [TableComponents](https://git.io/fANxz) | - | | +| components | Override default table elements | [TableComponents](https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129) | - | | | dataSource | Data record array to be displayed | object\[] | - | | | expandable | Config expandable content | [expandable](#expandable) | - | | | footer | Table footer renderer | function(currentPageData) | - | | diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 6db807b71f..71489d98cf 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -69,7 +69,7 @@ const columns = [ | --- | --- | --- | --- | --- | | bordered | 是否展示外边框和列边框 | boolean | false | | | columns | 表格列的配置描述,具体项见下表 | [ColumnsType](#Column)\[] | - | | -| components | 覆盖默认的 table 元素 | [TableComponents](https://git.io/fANxz) | - | | +| components | 覆盖默认的 table 元素 | [TableComponents](https://github.com/react-component/table/blob/75ee0064e54a4b3215694505870c9d6c817e9e4a/src/interface.ts#L129) | - | | | dataSource | 数据数组 | object\[] | - | | | expandable | 配置展开属性 | [expandable](#expandable) | - | | | footer | 表格尾部 | function(currentPageData) | - | | diff --git a/components/time-picker/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/time-picker/__tests__/__snapshots__/demo-extend.test.ts.snap index 7f17ef1b79..0801851dc8 100644 --- a/components/time-picker/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/time-picker/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -20435,6 +20435,7 @@ exports[`renders ./components/time-picker/demo/status.md extend context correctl
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
  • +
    + 24 +
    +
  • +
  • +
    + 25 +
    +
  • +
  • +
    + 26 +
    +
  • +
  • +
    + 27 +
    +
  • +
  • +
    + 28 +
    +
  • +
  • +
    + 29 +
    +
  • +
  • +
    + 30 +
    +
  • +
  • +
    + 31 +
    +
  • +
  • +
    + 32 +
    +
  • +
  • +
    + 33 +
    +
  • +
  • +
    + 34 +
    +
  • +
  • +
    + 35 +
    +
  • +
  • +
    + 36 +
    +
  • +
  • +
    + 37 +
    +
  • +
  • +
    + 38 +
    +
  • +
  • +
    + 39 +
    +
  • +
  • +
    + 40 +
    +
  • +
  • +
    + 41 +
    +
  • +
  • +
    + 42 +
    +
  • +
  • +
    + 43 +
    +
  • +
  • +
    + 44 +
    +
  • +
  • +
    + 45 +
    +
  • +
  • +
    + 46 +
    +
  • +
  • +
    + 47 +
    +
  • +
  • +
    + 48 +
    +
  • +
  • +
    + 49 +
    +
  • +
  • +
    + 50 +
    +
  • +
  • +
    + 51 +
    +
  • +
  • +
    + 52 +
    +
  • +
  • +
    + 53 +
    +
  • +
  • +
    + 54 +
    +
  • +
  • +
    + 55 +
    +
  • +
  • +
    + 56 +
    +
  • +
  • +
    + 57 +
    +
  • +
  • +
    + 58 +
    +
  • +
  • +
    + 59 +
    +
  • +
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
  • +
    + 24 +
    +
  • +
  • +
    + 25 +
    +
  • +
  • +
    + 26 +
    +
  • +
  • +
    + 27 +
    +
  • +
  • +
    + 28 +
    +
  • +
  • +
    + 29 +
    +
  • +
  • +
    + 30 +
    +
  • +
  • +
    + 31 +
    +
  • +
  • +
    + 32 +
    +
  • +
  • +
    + 33 +
    +
  • +
  • +
    + 34 +
    +
  • +
  • +
    + 35 +
    +
  • +
  • +
    + 36 +
    +
  • +
  • +
    + 37 +
    +
  • +
  • +
    + 38 +
    +
  • +
  • +
    + 39 +
    +
  • +
  • +
    + 40 +
    +
  • +
  • +
    + 41 +
    +
  • +
  • +
    + 42 +
    +
  • +
  • +
    + 43 +
    +
  • +
  • +
    + 44 +
    +
  • +
  • +
    + 45 +
    +
  • +
  • +
    + 46 +
    +
  • +
  • +
    + 47 +
    +
  • +
  • +
    + 48 +
    +
  • +
  • +
    + 49 +
    +
  • +
  • +
    + 50 +
    +
  • +
  • +
    + 51 +
    +
  • +
  • +
    + 52 +
    +
  • +
  • +
    + 53 +
    +
  • +
  • +
    + 54 +
    +
  • +
  • +
    + 55 +
    +
  • +
  • +
    + 56 +
    +
  • +
  • +
    + 57 +
    +
  • +
  • +
    + 58 +
    +
  • +
  • +
    + 59 +
    +
  • +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
  • +
    + 24 +
    +
  • +
  • +
    + 25 +
    +
  • +
  • +
    + 26 +
    +
  • +
  • +
    + 27 +
    +
  • +
  • +
    + 28 +
    +
  • +
  • +
    + 29 +
    +
  • +
  • +
    + 30 +
    +
  • +
  • +
    + 31 +
    +
  • +
  • +
    + 32 +
    +
  • +
  • +
    + 33 +
    +
  • +
  • +
    + 34 +
    +
  • +
  • +
    + 35 +
    +
  • +
  • +
    + 36 +
    +
  • +
  • +
    + 37 +
    +
  • +
  • +
    + 38 +
    +
  • +
  • +
    + 39 +
    +
  • +
  • +
    + 40 +
    +
  • +
  • +
    + 41 +
    +
  • +
  • +
    + 42 +
    +
  • +
  • +
    + 43 +
    +
  • +
  • +
    + 44 +
    +
  • +
  • +
    + 45 +
    +
  • +
  • +
    + 46 +
    +
  • +
  • +
    + 47 +
    +
  • +
  • +
    + 48 +
    +
  • +
  • +
    + 49 +
    +
  • +
  • +
    + 50 +
    +
  • +
  • +
    + 51 +
    +
  • +
  • +
    + 52 +
    +
  • +
  • +
    + 53 +
    +
  • +
  • +
    + 54 +
    +
  • +
  • +
    + 55 +
    +
  • +
  • +
    + 56 +
    +
  • +
  • +
    + 57 +
    +
  • +
  • +
    + 58 +
    +
  • +
  • +
    + 59 +
    +
  • +
+
    +
  • +
    + 00 +
    +
  • +
  • +
    + 01 +
    +
  • +
  • +
    + 02 +
    +
  • +
  • +
    + 03 +
    +
  • +
  • +
    + 04 +
    +
  • +
  • +
    + 05 +
    +
  • +
  • +
    + 06 +
    +
  • +
  • +
    + 07 +
    +
  • +
  • +
    + 08 +
    +
  • +
  • +
    + 09 +
    +
  • +
  • +
    + 10 +
    +
  • +
  • +
    + 11 +
    +
  • +
  • +
    + 12 +
    +
  • +
  • +
    + 13 +
    +
  • +
  • +
    + 14 +
    +
  • +
  • +
    + 15 +
    +
  • +
  • +
    + 16 +
    +
  • +
  • +
    + 17 +
    +
  • +
  • +
    + 18 +
    +
  • +
  • +
    + 19 +
    +
  • +
  • +
    + 20 +
    +
  • +
  • +
    + 21 +
    +
  • +
  • +
    + 22 +
    +
  • +
  • +
    + 23 +
    +
  • +
  • +
    + 24 +
    +
  • +
  • +
    + 25 +
    +
  • +
  • +
    + 26 +
    +
  • +
  • +
    + 27 +
    +
  • +
  • +
    + 28 +
    +
  • +
  • +
    + 29 +
    +
  • +
  • +
    + 30 +
    +
  • +
  • +
    + 31 +
    +
  • +
  • +
    + 32 +
    +
  • +
  • +
    + 33 +
    +
  • +
  • +
    + 34 +
    +
  • +
  • +
    + 35 +
    +
  • +
  • +
    + 36 +
    +
  • +
  • +
    + 37 +
    +
  • +
  • +
    + 38 +
    +
  • +
  • +
    + 39 +
    +
  • +
  • +
    + 40 +
    +
  • +
  • +
    + 41 +
    +
  • +
  • +
    + 42 +
    +
  • +
  • +
    + 43 +
    +
  • +
  • +
    + 44 +
    +
  • +
  • +
    + 45 +
    +
  • +
  • +
    + 46 +
    +
  • +
  • +
    + 47 +
    +
  • +
  • +
    + 48 +
    +
  • +
  • +
    + 49 +
    +
  • +
  • +
    + 50 +
    +
  • +
  • +
    + 51 +
    +
  • +
  • +
    + 52 +
    +
  • +
  • +
    + 53 +
    +
  • +
  • +
    + 54 +
    +
  • +
  • +
    + 55 +
    +
  • +
  • +
    + 56 +
    +
  • +
  • +
    + 57 +
    +
  • +
  • +
    + 58 +
    +
  • +
  • +
    + 59 +
    +
  • +
+
+
+
+
+ +
+
+
+
+
`; diff --git a/components/time-picker/__tests__/__snapshots__/demo.test.js.snap b/components/time-picker/__tests__/__snapshots__/demo.test.js.snap index aa127eadd4..2ff537499d 100644 --- a/components/time-picker/__tests__/__snapshots__/demo.test.js.snap +++ b/components/time-picker/__tests__/__snapshots__/demo.test.js.snap @@ -901,6 +901,7 @@ exports[`renders ./components/time-picker/demo/status.md correctly 1`] = `
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
`; diff --git a/components/time-picker/demo/status.md b/components/time-picker/demo/status.md index 12572e798f..ca6dd09e57 100644 --- a/components/time-picker/demo/status.md +++ b/components/time-picker/demo/status.md @@ -21,6 +21,8 @@ const Status: React.FC = () => ( + + ); diff --git a/components/timeline/index.zh-CN.md b/components/timeline/index.zh-CN.md index 40ca1eb592..05acb976a7 100644 --- a/components/timeline/index.zh-CN.md +++ b/components/timeline/index.zh-CN.md @@ -41,7 +41,7 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/vJmo00mmgR/Timeline.svg | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| color | 指定圆圈颜色 `blue`, `red`, `green`, `gray`,或自定义的色值 | string | `blue` | +| color | 指定圆圈颜色 `blue`、`red`、`green`、`gray`,或自定义的色值 | string | `blue` | | dot | 自定义时间轴点 | ReactNode | - | | label | 设置标签 | ReactNode | - | | position | 自定义节点位置 | `left` \| `right` | - | diff --git a/components/tooltip/style/index.less b/components/tooltip/style/index.less index 7b00fdea44..697f685574 100644 --- a/components/tooltip/style/index.less +++ b/components/tooltip/style/index.less @@ -19,6 +19,7 @@ z-index: @zindex-tooltip; display: block; width: max-content; + width: intrinsic; max-width: @tooltip-max-width; visibility: visible; diff --git a/components/transfer/index.tsx b/components/transfer/index.tsx index 27764b2fbc..009d18fd50 100644 --- a/components/transfer/index.tsx +++ b/components/transfer/index.tsx @@ -79,7 +79,9 @@ export interface TransferProps { showSearch?: boolean; filterOption?: (inputValue: string, item: RecordType) => boolean; locale?: Partial; - footer?: (props: TransferListProps) => React.ReactNode; + footer?: (props: TransferListProps, info?: { + direction: TransferDirection; + }) => React.ReactNode; rowKey?: (record: RecordType) => string; onSearch?: (direction: TransferDirection, value: string) => void; onScroll?: (direction: TransferDirection, e: React.SyntheticEvent) => void; diff --git a/components/transfer/style/status.less b/components/transfer/style/status.less index 5eab3bb94e..a861223174 100644 --- a/components/transfer/style/status.less +++ b/components/transfer/style/status.less @@ -2,7 +2,7 @@ @transfer-prefix-cls: ~'@{ant-prefix}-transfer'; -.status-color(@color) { +.transfer-status-color(@color) { .@{transfer-prefix-cls}-list { border-color: @color; @@ -22,10 +22,10 @@ .@{transfer-prefix-cls} { &-status-error { - .status-color(@error-color); + .transfer-status-color(@error-color); } &-status-warning { - .status-color(@warning-color); + .transfer-status-color(@warning-color); } } diff --git a/components/tree/demo/search.md b/components/tree/demo/search.md index df8151d567..180e8cc483 100644 --- a/components/tree/demo/search.md +++ b/components/tree/demo/search.md @@ -110,8 +110,8 @@ class SearchTree extends React.Component { const loop = data => data.map(item => { const index = item.title.indexOf(searchValue); - const beforeStr = item.title.substr(0, index); - const afterStr = item.title.substr(index + searchValue.length); + const beforeStr = item.title.substring(0, index); + const afterStr = item.title.slice(index + searchValue.length); const title = index > -1 ? ( diff --git a/components/typography/Typography.tsx b/components/typography/Typography.tsx index 0aa7ce5c9c..f64f82f239 100644 --- a/components/typography/Typography.tsx +++ b/components/typography/Typography.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import classNames from 'classnames'; import { composeRef } from 'rc-util/lib/ref'; -import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; +import { ConfigContext } from '../config-provider'; import devWarning from '../_util/devWarning'; export interface TypographyProps { @@ -31,37 +31,27 @@ const Typography: React.ForwardRefRenderFunction<{}, InternalTypographyProps> = }, ref, ) => { - let mergedRef = ref; + const { getPrefixCls, direction } = React.useContext(ConfigContext); + let mergedRef = ref; if (setContentRef) { devWarning(false, 'Typography', '`setContentRef` is deprecated. Please use `ref` instead.'); mergedRef = composeRef(ref, setContentRef); } + const Component = component as any; + const prefixCls = getPrefixCls('typography', customizePrefixCls); + const componentClassName = classNames( + prefixCls, + { + [`${prefixCls}-rtl`]: direction === 'rtl', + }, + className, + ); return ( - - {({ getPrefixCls, direction }: ConfigConsumerProps) => { - const Component = component as any; - const prefixCls = getPrefixCls('typography', customizePrefixCls); - const componentClassName = classNames( - prefixCls, - { - [`${prefixCls}-rtl`]: direction === 'rtl', - }, - className, - ); - return ( - - {children} - - ); - }} - + + {children} + ); }; @@ -70,6 +60,6 @@ const RefTypography = React.forwardRef(Typography); RefTypography.displayName = 'Typography'; // es default export should use const instead of let -const ExportTypography = (RefTypography as unknown) as React.FC; +const ExportTypography = RefTypography as unknown as React.FC; export default ExportTypography; diff --git a/components/typography/style/index.less b/components/typography/style/index.less index 9036a259ab..a9cd963663 100644 --- a/components/typography/style/index.less +++ b/components/typography/style/index.less @@ -217,6 +217,9 @@ // Fix Editable Textarea flash in Firefox textarea { + // https://stackoverflow.com/a/7695964/3040605 + height: 1em; + margin: 0 !important; /* stylelint-disable-next-line property-no-vendor-prefix */ -moz-transition: none; } diff --git a/components/upload/demo/file-type.md b/components/upload/demo/file-type.md index 5ec7214cf1..4cae73ee9e 100644 --- a/components/upload/demo/file-type.md +++ b/components/upload/demo/file-type.md @@ -102,7 +102,7 @@ class PicturesWall extends React.Component { icon = ; // or icon = 'uploading...'; } else { fileSufIconList.forEach(item => { - if (item.suf.includes(file.name.substr(file.name.lastIndexOf('.')))) { + if (item.suf.includes(file.name.slice(file.name.lastIndexOf('.')))) { icon = item.type; } }); diff --git a/package.json b/package.json index c9520caa15..b920a229b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "4.19.0", + "version": "4.19.2", "description": "An enterprise-class UI design language and React components implementation", "title": "Ant Design", "keywords": [ @@ -127,12 +127,12 @@ "rc-dialog": "~8.6.0", "rc-drawer": "~4.4.2", "rc-dropdown": "~3.3.2", - "rc-field-form": "~1.23.0", + "rc-field-form": "~1.24.0", "rc-image": "~5.2.5", - "rc-input": "^0.0.1-alpha.5", + "rc-input": "~0.0.1-alpha.5", "rc-input-number": "~7.3.0", "rc-mentions": "~1.6.1", - "rc-menu": "~9.2.1", + "rc-menu": "~9.3.2", "rc-motion": "^2.4.4", "rc-notification": "~4.5.7", "rc-pagination": "~3.1.9", @@ -140,7 +140,7 @@ "rc-progress": "~3.2.1", "rc-rate": "~2.9.0", "rc-resize-observer": "^1.2.0", - "rc-select": "~14.0.0-alpha.15", + "rc-select": "~14.0.2", "rc-slider": "~10.0.0-alpha.4", "rc-steps": "~4.1.0", "rc-switch": "~3.2.0", @@ -152,7 +152,7 @@ "rc-tree-select": "~5.1.1", "rc-trigger": "^5.2.10", "rc-upload": "~4.3.0", - "rc-util": "^5.14.0", + "rc-util": "^5.19.3", "scroll-into-view-if-needed": "^2.2.25" }, "devDependencies": { @@ -164,7 +164,7 @@ "@qixian.cs/github-contributors-list": "^1.0.3", "@stackblitz/sdk": "^1.3.0", "@testing-library/jest-dom": "^5.16.2", - "@testing-library/react": "^12.1.3", + "@testing-library/react": "^12.1.4", "@types/enzyme": "^3.10.5", "@types/gtag.js": "^0.0.8", "@types/jest": "^27.0.0", @@ -228,7 +228,7 @@ "intersection-observer": "^0.12.0", "isomorphic-fetch": "^3.0.0", "jest": "^27.0.3", - "jest-axe": "^5.0.1", + "jest-axe": "^6.0.0", "jest-environment-node": "^27.4.4", "jest-image-snapshot": "^4.5.1", "jest-puppeteer": "^6.0.0", diff --git a/scripts/check-commit.js b/scripts/check-commit.js index 5511234855..7e2a4911ad 100755 --- a/scripts/check-commit.js +++ b/scripts/check-commit.js @@ -2,7 +2,7 @@ const chalk = require('chalk'); const path = require('path'); const fetch = require('isomorphic-fetch'); -const simpleGit = require('simple-git/promise'); +const simpleGit = require('simple-git'); const cwd = process.cwd(); const git = simpleGit(cwd); diff --git a/scripts/generate-authors.js b/scripts/generate-authors.js index 548921f10d..02ede750bd 100644 --- a/scripts/generate-authors.js +++ b/scripts/generate-authors.js @@ -1,6 +1,6 @@ const path = require('path'); const fs = require('fs'); -const simpleGit = require('simple-git/promise'); +const simpleGit = require('simple-git'); const _ = require('lodash'); const cwd = process.cwd(); diff --git a/scripts/print-changelog.js b/scripts/print-changelog.js index 58177b00e7..8fc0dfedf9 100644 --- a/scripts/print-changelog.js +++ b/scripts/print-changelog.js @@ -7,7 +7,7 @@ const fetch = require('isomorphic-fetch'); const open = require('open'); const fs = require('fs-extra'); const path = require('path'); -const simpleGit = require('simple-git/promise'); +const simpleGit = require('simple-git'); const inquirer = require('inquirer'); const { JSDOM } = jsdom; diff --git a/site/theme/template/Layout/Header/index.tsx b/site/theme/template/Layout/Header/index.tsx index 05942539a4..6b7fe8a183 100644 --- a/site/theme/template/Layout/Header/index.tsx +++ b/site/theme/template/Layout/Header/index.tsx @@ -192,7 +192,7 @@ class Header extends React.Component { location: { pathname, query }, } = this.props; const currentProtocol = `${window.location.protocol}//`; - const currentHref = window.location.href.substr(currentProtocol.length); + const currentHref = window.location.href.slice(currentProtocol.length); if (utils.isLocalStorageNameSupported()) { localStorage.setItem('locale', utils.isZhCN(pathname) ? 'en-US' : 'zh-CN');