diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e7344c83acd8..501953ee5b42 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,14 @@ [[中文版模板 / Chinese template](https://github.com/ant-design/ant-design/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)] @@ -29,7 +34,7 @@ Please makes sure that these forms are filled before submitting your pull reques ### 🔗 Related issue link ### 💡 Background and solution @@ -37,7 +42,7 @@ Please makes sure that these forms are filled before submitting your pull reques ### 📝 Changelog @@ -51,7 +56,7 @@ Describe changes from the user side, and list all potential break changes or oth | 🇺🇸 English | | | 🇨🇳 Chinese | | -### ☑️ Self Check before Merge +### ☑️ Self-Check before Merge ⚠️ Please check all items below before review. ⚠️ diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml new file mode 100644 index 000000000000..ed8009427cb0 --- /dev/null +++ b/.github/workflows/size-limit.yml @@ -0,0 +1,31 @@ +name: 📦 Compressed Size(size-limit) + +on: + pull_request: + types: [opened, synchronize] + +# Cancel prev CI if new commit come +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + compressed-size: + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: write # for preactjs/compressed-size-action to create PR comments + runs-on: ubuntu-latest + env: + CI_JOB_NUMBER: 1 + + steps: + - uses: actions/checkout@v3 + - uses: andresz1/size-limit-action@v1 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + pattern: "./dist/**/*.min.{js,css}" + build-script: "dist:esbuild-no-dup-check" + clean-script: "clean-lockfiles" diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 95421371bf56..3f3edea91f67 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -9,6 +9,7 @@ timeline: true | infrad version | antd version | update content | time | | --- | --- | --- | --- | +| 4.22.3 | 4.22.3 | 1.Synchronize the update of antd 4.22.3 version
2.Modified the title's font size and font weight of the PageHeader component | 2022-08-04 | | 4.21.7 | 4.21.7 | Synchronize the update of antd 4.21.7 version | 2022-07-25 | | 4.21.6 | 4.21.6 | Synchronize the update of antd 4.21.6 version | 2022-07-15 | | 4.21.4 | 4.21.4 | 1.Synchronize the update of antd 4.21.4 version
2.Modified some styles of the table component
3.The tooltip component has been rolled back to keep it consistent with antd
4.Fix the style problem in the small state of the progress component
5.Fixed the enter event penetration problem of the sorting cell of the table component | 2022-07-04 | @@ -38,6 +39,53 @@ if you have some problem, welcome to connect `taofeng.yang@shopee.com` or `lay.z --- +## 4.22.3 + +`2022-08-01` + +- 🐞 Fixed flickering when `fileList` updating in Uploader with React 18. [#36801](https://github.com/ant-design/ant-design/pull/36801) [@zhengjitf](https://github.com/zhengjitf) +- 🐞 Fix Form.Item with small size `labelCol` and `wrapperCol` not break line in vertical layout. [#36800](https://github.com/ant-design/ant-design/pull/36800) +- 🐞 Fix Row in flex layout takes too wide space by default. [#36770](https://github.com/ant-design/ant-design/pull/36770) + +## 4.22.2 + +`2022-07-28` + +- 💄 Adjust Collapse title click region which will be fully width when `collapsible=default` now. [#36761](https://github.com/ant-design/ant-design/pull/36761) +- Drawer + - 🐞 Fix Drawer not work in 360 browser. [#36748](https://github.com/ant-design/ant-design/pull/36748) + - 🐞 Revert back panel style into wrapper dom node in case developer use `contentWrapperStyle` for overwrite. [#36748](https://github.com/ant-design/ant-design/pull/36748) + - 🐞 Fix for the string type as `width/height` value and warning which should use number type instead. [#284](https://github.com/react-component/drawer/pull/284) + +## 4.22.1 + +`2022-07-27` + +- 🐞 Fix Drawer with percentage width display issue. [#36729](https://github.com/ant-design/ant-design/pull/36729) + +## 4.22.0 + +`2022-07-26` + +- Form + - 🔥 Form support `Form.Item.useStatus` for custom components to get Form.Item validate status. [#36486](https://github.com/ant-design/ant-design/pull/36486) + - 🆕 Form support `setFieldValue` to simplify config array index value. [#36058](https://github.com/ant-design/ant-design/pull/36058) + - 🐞 Fix Form.Item shaking when trigger validate so fast. [#36575](https://github.com/ant-design/ant-design/pull/36575) +- 🆕 Radio.Group support `onBlur` and `onFocus` props. [#36041](https://github.com/ant-design/ant-design/pull/36041) +- 🆕 Typography `ellipsis.tooltip` supports a object for Tooltip props. [#36099](https://github.com/ant-design/ant-design/pull/36099) +- 🛠 Refactor Drawer to remove directly style control which helps more React way. [#36672](https://github.com/ant-design/ant-design/pull/36672) +- 🛠 Refactor Sketelon.Button square shape style that its width is equal to height, and old become the default. [#36123](https://github.com/ant-design/ant-design/pull/36123) [@alanhaledc](https://github.com/alanhaledc) +- 🐞 Fix Modal.confirm `onCancel` argument close is not a function sometimes. [#36600](https://github.com/ant-design/ant-design/pull/36600) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 Revert [#36439](https://github.com/ant-design/ant-design/pull/36439) to fix the problem of incorrect status when uploading and deleting files, and fix the status color change when Upload removes files again change problem. [#36706](https://github.com/ant-design/ant-design/pull/36706) +- Tree + - 🛠 Tree/TreeSelect `switcherIcon` argument support more parameters from `{ expanded: boolean }` to `AntTreeNodeProps`. [#36651](https://github.com/ant-design/ant-design/pull/36651) [@alanhaledc](https://github.com/alanhaledc) + - 🐞 Fix Tree `draggable` Fn params type from AntTreeNode to DataNode. [#36648](https://github.com/ant-design/ant-design/pull/36648) [@tianyuan233](https://github.com/tianyuan233) +- Table + - 💄 Fix Table extra shadow and scrollbar when all columns are fixed. [#36606](https://github.com/ant-design/ant-design/pull/36606) [@dashaowang](https://github.com/dashaowang) + - 💄 Fix Table tree data ellipsis style problem. [#36608](https://github.com/ant-design/ant-design/pull/36608) +- 🌐 Localization + - 🇱🇰 Add Sri Lanka locale. [#36149](https://github.com/ant-design/ant-design/pull/36149) [@sayuri-gi](https://github.com/sayuri-gi) + ## 4.21.7 `2022-07-18` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 161cee006f29..2a50037f966e 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -9,6 +9,7 @@ timeline: true | infrad 版本号 | 对应 antd 版本号 | 更新内容 | 时间 | | --- | --- | --- | --- | +| 4.22.3 | 4.22.3 | 1.同步 antd 4.22.3 版本的更新
2.修改了 PageHeader 组件的 title 字重与字体大小 | 2022-08-04 | | 4.21.7 | 4.21.7 | 同步 antd 4.21.7 版本的更新 | 2022-07-25 | | 4.21.6 | 4.21.6 | 同步 antd 4.21.6 版本的更新 | 2022-07-15 | | 4.21.4 | 4.21.4 | 1.同步 antd 4.21.4 版本的更新
2.修改了 table 组件的部分样式
3.回退 tooltip 组件保持与 Antd 一致
4.修复 progress 组件在 small 状态下的样式问题
5.修复了 table 组件排序单元格 enter 事件穿透问题 | 2022-07-04 | @@ -39,6 +40,53 @@ timeline: true --- +## 4.22.3 + +`2022-08-01` + +- 🐞 修复在 React 18 版本中 Uploader 的 `fileList` 发生更新后出现闪烁的情况。[#36801](https://github.com/ant-design/ant-design/pull/36801) [@zhengjitf](https://github.com/zhengjitf) +- 🐞 修复 Form.Item 在垂直布局下使用小尺寸的 `labelCol` 和 `wrapperCol` 时不换行的问题。[#36800](https://github.com/ant-design/ant-design/pull/36800) +- 🐞 修复 Row 在 flex 布局中占据过多空间的问题。[#36770](https://github.com/ant-design/ant-design/pull/36770) + +## 4.22.2 + +`2022-07-28` + +- 💄 调整 Collapse 标题文本在 `collapsible=default` 时为完整宽度点击区域。[#36761](https://github.com/ant-design/ant-design/pull/36761) +- Drawer + - 🐞 修复 Drawer 在 360 浏览器不生效的问题。[#36748](https://github.com/ant-design/ant-design/pull/36748) + - 🐞 回滚将样式恢复至包裹层以防止原本通过 `contentWrapperStyle` 覆盖样式的用法。[#36748](https://github.com/ant-design/ant-design/pull/36748) + - 🐞 修复兼容以 string 类型作为 `width/height` 的用法,并且警告用户应当使用 number 类型。[#284](https://github.com/react-component/drawer/pull/284) + +## 4.22.1 + +`2022-07-27` + +- 🐞 修复 Drawer 使用百分比宽度时的展示问题。[#36729](https://github.com/ant-design/ant-design/pull/36729) + +## 4.22.0 + +`2022-07-26` + +- Form + - 🔥 Form 新增 `Form.Item.useStatus` 用于获取 Form.Item 的校验状态。[#36486](https://github.com/ant-design/ant-design/pull/36486) + - 🆕 Form 支持 `setFieldValue` 以简化设置数字单个值的操作流程。[#36058](https://github.com/ant-design/ant-design/pull/36058) + - 🐞 修复 Form.Item 在快速切换校验状态时高度抖动的问题。[#36575](https://github.com/ant-design/ant-design/pull/36575) +- 🆕 Radio.Group 支持 `onBlur` 和 `onFocus` 属性。[#36041](https://github.com/ant-design/ant-design/pull/36041) +- 🆕 Typography `ellipsis.tooltip` 属性支持传入一个对象。[#36099](https://github.com/ant-design/ant-design/pull/36099) +- 🛠 重构 Drawer 移除直接的 dom 操作以使其更符合 React 运作方式。[#36672](https://github.com/ant-design/ant-design/pull/36672) +- 🛠 重构 Sketelon.Button square shape 样式为宽高相等,之前的 square 改为默认样式。[#36123](https://github.com/ant-design/ant-design/pull/36123) [@alanhaledc](https://github.com/alanhaledc) +- 🐞 修复 Modal.confirm 中 `onCancel(close)` 参数有时候不是 function 的问题。[#36600](https://github.com/ant-design/ant-design/pull/36600) [@Wxh16144](https://github.com/Wxh16144) +- 🐞 回滚 [#36439](https://github.com/ant-design/ant-design/pull/36439) 以修复上传和删除文件时状态不对的问题,并再次修复 Upload 移除文件时状态色会变化的问题。[#36706](https://github.com/ant-design/ant-design/pull/36706) +- Tree + - 🛠 Tree/TreeSelect `switcherIcon` 参数现在支持完整 TreeNode 属性,从 `{ expanded: boolean }` 变为 `AntTreeNodeProps`。[#36651](https://github.com/ant-design/ant-design/pull/36651) [@alanhaledc](https://github.com/alanhaledc) + - 🐞 修改 Tree `draggable` 函数的参数类型由 AntTreeNode 改为 DataNode。[#36648](https://github.com/ant-design/ant-design/pull/36648) [@tianyuan233](https://github.com/tianyuan233) +- Table + - 💄 修复 Table 固定列额外阴影和滚动条样式的问题。[#36606](https://github.com/ant-design/ant-design/pull/36606) [@dashaowang](https://github.com/dashaowang) + - 💄 修复 Table 树形数据固定列的省略样式错位的问题。[#36608](https://github.com/ant-design/ant-design/pull/36608) +- 🌐 国际化 + - 🇱🇰 添加斯里兰卡语言。[#36149](https://github.com/ant-design/ant-design/pull/36149) [@sayuri-gi](https://github.com/sayuri-gi) + ## 4.21.7 `2022-07-18` diff --git a/components/_util/getScroll.tsx b/components/_util/getScroll.tsx index 70b50141d1f2..f861b3a18d56 100644 --- a/components/_util/getScroll.tsx +++ b/components/_util/getScroll.tsx @@ -1,4 +1,4 @@ -export function isWindow(obj: any) { +export function isWindow(obj: any): obj is Window { return obj !== null && obj !== undefined && obj === obj.window; } @@ -12,16 +12,22 @@ export default function getScroll( const method = top ? 'scrollTop' : 'scrollLeft'; let result = 0; if (isWindow(target)) { - result = (target as Window)[top ? 'pageYOffset' : 'pageXOffset']; + result = target[top ? 'pageYOffset' : 'pageXOffset']; } else if (target instanceof Document) { result = target.documentElement[method]; + } else if (target instanceof HTMLElement) { + result = target[method]; } else if (target) { - result = (target as HTMLElement)[method]; + // According to the type inference, the `target` is `never` type. + // Since we configured the loose mode type checking, and supports mocking the target with such shape below:: + // `{ documentElement: { scrollLeft: 200, scrollTop: 400 } }`, + // the program may falls into this branch. + // Check the corresponding tests for details. Don't sure what is the real scenario this happens. + result = target[method]; } + if (target && !isWindow(target) && typeof result !== 'number') { - result = ((target as HTMLElement).ownerDocument || (target as Document)).documentElement?.[ - method - ]; + result = (target.ownerDocument ?? target).documentElement?.[method]; } return result; } diff --git a/components/auto-complete/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/auto-complete/__tests__/__snapshots__/demo-extend.test.ts.snap index adbec93048b0..b497ab4a9dbc 100644 --- a/components/auto-complete/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/auto-complete/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -521,259 +521,103 @@ exports[`renders ./components/auto-complete/demo/form-debug.md extend context co style="margin:0 auto" >
- -
-
-
- + 单独 AutoComplete +
-
-
-
-
- -
-
- - - - -
-
-
-
+ + + + +
+
+
+
-
- - - - - - - - - -
-
- No Data -
-
+ class="ant-select-item-empty" + id="undefined_list" + role="listbox" + />
-
- -
-
+ +
-
-
- -
-
+ +
-
+
-
-
-
-
-
-
-
+
+ + + + +
+
+
+
+
+
+
+
+
+ +
+
- -
-
+ +
-
-
- - - - -
-
-
-
-
-
-
- - - - - - - - - -
-
- No Data -
-
-
-
-
-
- -
- -
+
- -
-
+ +
- -
- - - - -
-
-
-
+ + + + +
+
+
+
- - - - - - - - - -
-
- No Data + + + + + + + + + +
+
+ No Data +
-
- - -
-
- + + + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+ + + + +
+
+
+
+
- - - +
+
+ No Data +
+
+
+
+
+
+ -
-
+
- -
-
+ +
- -
- - - - -
-
-
-
+ + + + +
+
+
+
- - - - - - - - - -
-
- No Data + + + + + + + + + +
+
+ No Data +
-
- - -
-
- - - + + + + - - -
-
-
-
-
+ +
+
+
+
+
+
-
- - + + + + Search + + + +
diff --git a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap index 02c7bc1496d2..7c5cbc748d01 100644 --- a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap +++ b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap @@ -173,167 +173,89 @@ exports[`renders ./components/auto-complete/demo/form-debug.md correctly 1`] = ` style="margin:0 auto" >
- -
-
-
- -
+ 单独 AutoComplete +
-
-
-
-
- -
-
- - - - -
- + + +
+
- -
-
+ +
-
- - +
- -
-
+ +
+
+ +
- -
-
+ +
-
-
- - - - -
- -
- -
+
- -
-
+ +
- -
- - + + + - +
-
- -
-
-
- - + + + - - + +
-
- + +
- -
-
+ +
- -
- - + + + - - -
-
- -
-
- - - + + + + - - + +
-
- + + + + + - - - - Search - - - + + + + + diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index 73a368f9a2b1..428e3b396d74 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -1,4 +1,4 @@ -import { SearchOutlined } from '@ant-design/icons'; +import { SearchOutlined } from 'infra-design-icons'; import { mount } from 'enzyme'; import { resetWarned } from 'rc-util/lib/warning'; import React, { Component } from 'react'; diff --git a/components/button/demo/chinese-chars-loading.md b/components/button/demo/chinese-chars-loading.md index e72d8bc89d80..050e032d0384 100644 --- a/components/button/demo/chinese-chars-loading.md +++ b/components/button/demo/chinese-chars-loading.md @@ -15,7 +15,7 @@ https://github.com/ant-design/ant-design/issues/36165 https://github.com/ant-design/ant-design/issues/36165 ```jsx -import { PoweroffOutlined } from '@ant-design/icons'; +import { PoweroffOutlined } from 'infra-design-icons'; import { Button } from 'antd'; import React from 'react'; diff --git a/components/calendar/locale/si_LK.tsx b/components/calendar/locale/si_LK.tsx new file mode 100644 index 000000000000..15c7d248cc01 --- /dev/null +++ b/components/calendar/locale/si_LK.tsx @@ -0,0 +1,3 @@ +import siLK from '../../date-picker/locale/si_LK'; + +export default siLK; diff --git a/components/cascader/__tests__/__snapshots__/index.test.js.snap b/components/cascader/__tests__/__snapshots__/index.test.js.snap index 63a4da347ade..e84cf39e21cd 100644 --- a/components/cascader/__tests__/__snapshots__/index.test.js.snap +++ b/components/cascader/__tests__/__snapshots__/index.test.js.snap @@ -1619,130 +1619,9 @@ exports[`Cascader rtl render component should be rendered correctly in RTL direc `; -exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = ` -
-
-
- -
-
-
-`; +exports[`Cascader should highlight keyword and filter when search in Cascader 1`] = `"
"`; -exports[`Cascader should highlight keyword and filter when search in Cascader with same field name of label and value 1`] = ` -
-
-
- -
-
-
-`; +exports[`Cascader should highlight keyword and filter when search in Cascader with same field name of label and value 1`] = `"
"`; exports[`Cascader should render not found content 1`] = `
{ rtlTest(Cascader); it('popup correctly when panel is hidden', () => { - const wrapper = mount(); - expect(isOpen(wrapper)).toBeFalsy(); + const { container } = render(); + expect(isOpen(container)).toBeFalsy(); }); it('popup correctly when panel is open', () => { const onPopupVisibleChange = jest.fn(); - const wrapper = mount( + const { container } = render( , ); - toggleOpen(wrapper); - expect(isOpen(wrapper)).toBeTruthy(); + toggleOpen(container); + expect(isOpen(container)).toBeTruthy(); expect(onPopupVisibleChange).toHaveBeenCalledWith(true); }); it('support controlled mode', () => { - const wrapper = mount(); - wrapper.setProps({ - value: ['zhejiang', 'hangzhou', 'xihu'], - }); - expect(wrapper.render()).toMatchSnapshot(); + const { rerender, asFragment } = render(); + rerender(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('popup correctly with defaultValue', () => { - const wrapper = mount(); - toggleOpen(wrapper); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + const { container } = render( + , + ); + toggleOpen(container); + expect(getDropdown(container)).toMatchSnapshot(); }); it('should support popupVisible', () => { - const wrapper = mount(); - expect(isOpen(wrapper)).toBeFalsy(); - wrapper.setProps({ popupVisible: true }); - expect(isOpen(wrapper)).toBeTruthy(); + const { container, rerender } = render( + , + ); + expect(isOpen(container)).toBeFalsy(); + rerender(); + expect(isOpen(container)).toBeTruthy(); }); it('can be selected', () => { const onChange = jest.fn(); - const wrapper = mount(); + const { container } = render(); - toggleOpen(wrapper); - expect(isOpen(wrapper)).toBeTruthy(); + toggleOpen(container); + expect(isOpen(container)).toBeTruthy(); - clickOption(wrapper, 0, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + clickOption(container, 0, 0); + expect(getDropdown(container)).toMatchSnapshot(); - clickOption(wrapper, 1, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + clickOption(container, 1, 0); + expect(getDropdown(container)).toMatchSnapshot(); - clickOption(wrapper, 2, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + clickOption(container, 2, 0); + expect(getDropdown(container)).toMatchSnapshot(); expect(onChange).toHaveBeenCalledTimes(1); expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything()); }); it('backspace should work with `Cascader[showSearch]`', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: '123' } }); - expect(isOpen(wrapper)).toBeTruthy(); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: '123' } }); + expect(isOpen(container)).toBeTruthy(); - wrapper.find('input').simulate('keydown', { which: KeyCode.BACKSPACE }); - expect(isOpen(wrapper)).toBeTruthy(); + fireEvent.keyDown(container.querySelector('input'), { + key: 'Backspace', + keyCode: 8, + }); + expect(isOpen(container)).toBeTruthy(); - wrapper.find('input').simulate('change', { target: { value: '' } }); - expect(isOpen(wrapper)).toBeTruthy(); + fireEvent.change(container.querySelector('input'), { target: { value: '' } }); + expect(isOpen(container)).toBeTruthy(); - wrapper.find('input').simulate('keydown', { which: KeyCode.BACKSPACE }); - expect(isOpen(wrapper)).toBeFalsy(); + fireEvent.keyDown(container.querySelector('input'), { + key: 'Backspace', + keyCode: 8, + }); + expect(isOpen(container)).toBeFalsy(); }); it('should highlight keyword and filter when search in Cascader', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'z' } }); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: 'z' } }); + + // React 18 with testing lib will have additional space. We have to compare innerHTML. Sad. + expect(getDropdown(container).innerHTML).toMatchSnapshot(); }); it('should highlight keyword and filter when search in Cascader with same field name of label and value', () => { @@ -175,58 +183,67 @@ describe('Cascader', () => { function customFilter(inputValue, path) { return path.some(option => option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1); } - const wrapper = mount( + const { container } = render( , ); - wrapper.find('input').simulate('change', { target: { value: 'z' } }); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + fireEvent.change(container.querySelector('input'), { target: { value: 'z' } }); + + // React 18 with testing lib will have additional space. We have to compare innerHTML. Sad. + expect(getDropdown(container).innerHTML).toMatchSnapshot(); }); it('should render not found content', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: '__notfoundkeyword__' } }); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { + target: { value: '__notfoundkeyword__' }, + }); + expect(getDropdown(container)).toMatchSnapshot(); }); it('should support to clear selection', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-select-selection-item').text()).toEqual('Zhejiang / Hangzhou'); - wrapper.find('.ant-select-clear').at(0).simulate('mouseDown'); - expect(wrapper.exists('.ant-select-selection-item')).toBeFalsy(); + const { container } = render( + , + ); + expect(container.querySelector('.ant-select-selection-item').textContent).toEqual( + 'Zhejiang / Hangzhou', + ); + fireEvent.mouseDown(container.querySelector('.ant-select-clear')); + expect(container.querySelector('.ant-select-selection-item')).toBeFalsy(); }); it('should clear search input when clear selection', () => { - const wrapper = mount( + const { container } = render( , ); - wrapper.find('input').simulate('change', { target: { value: 'xxx' } }); - - wrapper.find('.ant-select-clear').at(0).simulate('mouseDown'); - expect(wrapper.find('input').props().value).toEqual(''); + fireEvent.change(container.querySelector('input'), { target: { value: 'xxx' } }); + fireEvent.mouseDown(container.querySelector('.ant-select-clear')); + expect(container.querySelector('input').value).toEqual(''); }); it('should change filtered item when options are changed', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'a' } }); - expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2); - wrapper.setProps({ options: [options[0]] }); - expect(wrapper.find('.ant-cascader-menu-item').length).toBe(1); + const { container, rerender } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: 'a' } }); + expect(container.querySelectorAll('.ant-cascader-menu-item').length).toBe(2); + + rerender(); + expect(container.querySelectorAll('.ant-cascader-menu-item').length).toBe(1); }); it('should select item immediately when searching and pressing down arrow key', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'a' } }); - expect(wrapper.find('.ant-cascader-menu-item').length).toBe(2); - expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(0); - - wrapper.find('input').simulate('keyDown', { - which: KeyCode.DOWN, + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: 'a' } }); + + expect(container.querySelectorAll('.ant-cascader-menu-item').length).toBe(2); + expect(container.querySelectorAll('.ant-cascader-menu-item-active').length).toBe(0); + fireEvent.keyDown(container.querySelector('input'), { + key: 'Down', + keyCode: 40, }); - expect(wrapper.find('.ant-cascader-menu-item-active').length).toBe(1); + expect(container.querySelectorAll('.ant-cascader-menu-item-active').length).toBe(1); }); it('can use fieldNames', () => { @@ -267,7 +284,7 @@ describe('Cascader', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( { />, ); - clickOption(wrapper, 0, 0); - clickOption(wrapper, 1, 0); - clickOption(wrapper, 2, 0); - expect(wrapper.find('.ant-select-selection-item').text()).toEqual( + clickOption(container, 0, 0); + clickOption(container, 1, 0); + clickOption(container, 2, 0); + expect(container.querySelector('.ant-select-selection-item').textContent).toEqual( 'Zhejiang / Hangzhou / West Lake', ); expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything()); @@ -291,14 +308,14 @@ describe('Cascader', () => { it('should show not found content when options.length is 0', () => { const customerOptions = []; - const wrapper = mount(); - toggleOpen(wrapper); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + const { container } = render(); + toggleOpen(container); + expect(getDropdown(container)).toMatchSnapshot(); }); it('not found content should be disabled', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-cascader-menu-item-disabled').length).toBe(1); + const { container } = render(); + expect(container.querySelectorAll('.ant-cascader-menu-item-disabled').length).toBe(1); }); describe('limit filtered item count', () => { @@ -309,22 +326,28 @@ describe('Cascader', () => { }); it('limit with positive number', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'a' } }); - expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(1); + const { container } = render( + , + ); + fireEvent.change(container.querySelector('input'), { target: { value: 'a' } }); + expect(container.querySelectorAll('.ant-cascader-menu-item')).toHaveLength(1); }); it('not limit', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'a' } }); - expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(2); + const { container } = render( + , + ); + fireEvent.change(container.querySelector('input'), { target: { value: 'a' } }); + expect(container.querySelectorAll('.ant-cascader-menu-item')).toHaveLength(2); }); it('negative limit', () => { - const wrapper = mount(); - wrapper.find('input').simulate('click'); - wrapper.find('input').simulate('change', { target: { value: 'a' } }); - expect(wrapper.find('.ant-cascader-menu-item')).toHaveLength(2); + const { container } = render( + , + ); + fireEvent.click(container.querySelector('input')); + fireEvent.change(container.querySelector('input'), { target: { value: 'a' } }); + expect(container.querySelectorAll('.ant-cascader-menu-item')).toHaveLength(2); }); }); @@ -332,7 +355,7 @@ describe('Cascader', () => { // eslint-disable-next-line jest/no-disabled-tests it.skip('should warning if not find `value` in `options`', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); - mount(); + render(); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Cascader] Not found `value` in `options`.', ); @@ -355,22 +378,22 @@ describe('Cascader', () => { }, ]; expect(() => { - mount(); + render(); }).not.toThrow(); }); it('placeholder works correctly', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-select-selection-placeholder').text()).toEqual(''); + const { container, rerender } = render(); + expect(container.querySelector('.ant-select-selection-placeholder').textContent).toEqual(''); const customPlaceholder = 'Custom placeholder'; - wrapper.setProps({ - placeholder: customPlaceholder, - }); - expect(wrapper.find('.ant-select-selection-placeholder').text()).toEqual(customPlaceholder); + rerender(); + expect(container.querySelector('.ant-select-selection-placeholder').textContent).toEqual( + customPlaceholder, + ); }); - it('placement work correctly', () => { + it('placement work correctly', async () => { const customerOptions = [ { value: 'zhejiang', @@ -383,17 +406,20 @@ describe('Cascader', () => { ], }, ]; - const wrapper = mount(); - expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('topRight'); + const { container } = render(); + toggleOpen(container); + + // Inject in tests/__mocks__/rc-trigger.js + expect(global.triggerProps.popupPlacement).toEqual('topRight'); }); it('popup correctly with defaultValue RTL', () => { - const wrapper = mount( + const { asFragment } = render( , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('can be selected in RTL direction', () => { @@ -432,7 +458,7 @@ describe('Cascader', () => { }, ]; const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( { , ); - toggleOpen(wrapper); - clickOption(wrapper, 0, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + toggleOpen(container); + clickOption(container, 0, 0); + expect(getDropdown(container)).toMatchSnapshot(); - toggleOpen(wrapper); - clickOption(wrapper, 1, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + toggleOpen(container); + clickOption(container, 1, 0); + expect(getDropdown(container)).toMatchSnapshot(); - toggleOpen(wrapper); - clickOption(wrapper, 2, 0); - expect(getDropdown(wrapper).render()).toMatchSnapshot(); + toggleOpen(container); + clickOption(container, 2, 0); + expect(getDropdown(container)).toMatchSnapshot(); expect(onChange).toHaveBeenCalledTimes(1); expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything()); }); it('defaultValue works correctly when no match options', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-select-selection-item').text()).toEqual('options1 / options2'); + const { container } = render( + , + ); + expect(container.querySelector('.ant-select-selection-item').textContent).toEqual( + 'options1 / options2', + ); }); it('can be selected when showSearch', () => { const onChange = jest.fn(); - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'Zh' } }); - expect(wrapper.find('.ant-cascader-menu').length).toBe(1); - clickOption(wrapper, 0, 0); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: 'Zh' } }); + + expect(container.querySelectorAll('.ant-cascader-menu').length).toBe(1); + clickOption(container, 0, 0); expect(onChange).toHaveBeenCalledWith(['zhejiang', 'hangzhou', 'xihu'], expect.anything()); }); it('options should open after press esc and then search', () => { - const wrapper = mount(); - wrapper.find('input').simulate('change', { target: { value: 'jin' } }); - expect(isOpen(wrapper)).toBeTruthy(); - wrapper.find('input').simulate('keydown', { which: KeyCode.ESC }); - expect(isOpen(wrapper)).toBeFalsy(); - wrapper.find('input').simulate('change', { target: { value: 'jin' } }); - expect(isOpen(wrapper)).toBeTruthy(); + const { container } = render(); + fireEvent.change(container.querySelector('input'), { target: { value: 'jin' } }); + expect(isOpen(container)).toBeTruthy(); + fireEvent.keyDown(container.querySelector('input'), { + key: 'Esc', + keyCode: 27, + }); + expect(isOpen(container)).toBeFalsy(); + fireEvent.change(container.querySelector('input'), { target: { value: 'jin' } }); + expect(isOpen(container)).toBeTruthy(); }); it('onChange works correctly when the label of fieldNames is the same as value', () => { const onChange = jest.fn(); const sameNames = { label: 'label', value: 'label' }; - const wrapper = mount( + const { container } = render( , ); - wrapper.find('input').simulate('change', { target: { value: 'est' } }); - clickOption(wrapper, 0, 0); + fireEvent.change(container.querySelector('input'), { target: { value: 'est' } }); + clickOption(container, 0, 0); expect(onChange).toHaveBeenCalledWith(['Zhejiang', 'Hangzhou', 'West Lake'], expect.anything()); }); it('rtl should work well with placement', () => { - const wrapper = mount(); + const { container } = render(); + toggleOpen(container); - expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('bottomRight'); + // Inject in tests/__mocks__/rc-trigger.js + expect(global.triggerProps.popupPlacement).toEqual('bottomRight'); }); describe('legacy props', () => { it('popupClassName', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); - const wrapper = mount( + const { container } = render( , ); - expect(wrapper.exists('.mock-cls')).toBeTruthy(); - expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('bottomLeft'); + expect(container.querySelector('.mock-cls')).toBeTruthy(); + + // Inject in tests/__mocks__/rc-trigger.js + expect(global.triggerProps.popupPlacement).toEqual('bottomLeft'); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Cascader] `popupClassName` is deprecated. Please use `dropdownClassName` instead.', @@ -562,7 +600,7 @@ describe('Cascader', () => { selectedValue = value; }; - const wrapper = mount( + const { container, asFragment } = render( { showCheckedStrategy={SHOW_CHILD} />, ); - toggleOpen(wrapper); - expect(wrapper.render()).toMatchSnapshot(); + toggleOpen(container); + expect(asFragment().firstChild).toMatchSnapshot(); - clickOption(wrapper, 0, 0); - clickOption(wrapper, 1, 0); - clickOption(wrapper, 2, 0); - clickOption(wrapper, 2, 1); + clickOption(container, 0, 0); + clickOption(container, 1, 0); + clickOption(container, 2, 0); + clickOption(container, 2, 1); expect(selectedValue[0].join(',')).toBe('zhejiang,hangzhou,xihu'); expect(selectedValue[1].join(',')).toBe('zhejiang,hangzhou,donghu'); expect(selectedValue.join(',')).toBe('zhejiang,hangzhou,xihu,zhejiang,hangzhou,donghu'); @@ -627,7 +665,7 @@ describe('Cascader', () => { selectedValue = value; }; - const wrapper = mount( + const { container, asFragment } = render( { showCheckedStrategy={SHOW_PARENT} />, ); - toggleOpen(wrapper); - expect(wrapper.render()).toMatchSnapshot(); - clickOption(wrapper, 0, 0); - clickOption(wrapper, 1, 0); - clickOption(wrapper, 2, 0); - clickOption(wrapper, 2, 1); + toggleOpen(container); + expect(asFragment().firstChild).toMatchSnapshot(); + clickOption(container, 0, 0); + clickOption(container, 1, 0); + clickOption(container, 2, 0); + clickOption(container, 2, 1); expect(selectedValue.length).toBe(1); expect(selectedValue.join(',')).toBe('zhejiang'); diff --git a/components/cascader/__tests__/type.test.tsx b/components/cascader/__tests__/type.test.tsx index 270c5122f91d..e0c9010e6578 100644 --- a/components/cascader/__tests__/type.test.tsx +++ b/components/cascader/__tests__/type.test.tsx @@ -1,7 +1,7 @@ -import { mount } from 'enzyme'; import * as React from 'react'; import type { BaseOptionType } from '..'; import Cascader from '..'; +import { render } from '../../../tests/utils'; describe('Cascader.typescript', () => { it('options value', () => { @@ -46,8 +46,10 @@ describe('Cascader.typescript', () => { }); it('suffixIcon', () => { - const wrapper = mount(} />); - expect(wrapper).toBeTruthy(); + const { container } = render(} />); + expect( + container.querySelector('.ant-select-arrow')?.querySelector('span')?.className, + ).toBeFalsy(); }); it('Generic', () => { @@ -57,7 +59,7 @@ describe('Cascader.typescript', () => { customizeChildren?: MyOptionData[]; } - const wrapper = mount( + const { container } = render( options={[ { @@ -73,20 +75,20 @@ describe('Cascader.typescript', () => { ]} />, ); - expect(wrapper).toBeTruthy(); + expect(container).toBeTruthy(); }); it('single onChange', () => { - const wrapper = mount( + const { container } = render( values} />, ); - expect(wrapper).toBeTruthy(); + expect(container).toBeTruthy(); }); it('multiple onChange', () => { - const wrapper = mount( + const { container } = render( values} />, ); - expect(wrapper).toBeTruthy(); + expect(container).toBeTruthy(); }); }); diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index 7de0b61a45f4..325019668a27 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -1,6 +1,4 @@ -import LeftOutlined from '@ant-design/icons/LeftOutlined'; -import LoadingOutlined from '@ant-design/icons/LoadingOutlined'; -import RightOutlined from '@ant-design/icons/RightOutlined'; +import { LeftOutlined, LoadingOutlined, RightOutlined } from 'infra-design-icons'; import classNames from 'classnames'; import type { BaseOptionType, diff --git a/components/collapse/style/index.less b/components/collapse/style/index.less index 5cecd1fc7e20..2cccb86fbbb8 100644 --- a/components/collapse/style/index.less +++ b/components/collapse/style/index.less @@ -43,6 +43,10 @@ } } + .@{collapse-prefix-cls}-header-text { + flex: auto; + } + .@{collapse-prefix-cls}-extra { margin-left: auto; } @@ -55,6 +59,7 @@ .@{collapse-prefix-cls}-header-collapsible-only { cursor: default; .@{collapse-prefix-cls}-header-text { + flex: none; cursor: pointer; } } diff --git a/components/comment/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/comment/__tests__/__snapshots__/demo-extend.test.ts.snap index 524768aef5a1..68d6911f90bb 100644 --- a/components/comment/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/comment/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -215,45 +215,53 @@ exports[`renders ./components/comment/demo/editor.md extend context correctly 1` class="ant-comment-content-detail" >
-