From f26ad4d28f32501fff391c7e02d59b83a57cb588 Mon Sep 17 00:00:00 2001 From: zhanglei66 <38252062+zhanglei66@users.noreply.github.com> Date: Mon, 13 Jun 2022 18:29:19 +0800 Subject: [PATCH] Zl/v4.21.0 sync (#71) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: Rewrite mountTest with testing lib (#35326) * feat: Form disabled (#35210) * feat: add form disabled * feat: add form disabled * feat: add radio disabled * feat: update snap * feat: add test case * docs: add instruction about tokenSeparators (#35329) * test: replace Empty part test with test lib (#35289) * test: replace Empty part test with test lib * test: update snapshot case * fix: Switch disabled color in dark theme (#35332) * Revert "feat: dropdown auto-focus (#35307)" (#35337) This reverts commit 1ff58d23f08d8d7f487c123f21eaf5d3a79f95e9. * docs: update Tabs component onEdit prop describe (#35271) * docs: update Tabs component onEdit prop describe * docs: update Tabs component onEdit prop describe * Apply suggestions from code review Co-authored-by: afc163 * docs: changelog for 4.20.2 (#35338) * docs: add changelog for #35336 * style: fix Select tag remove icon position (#35336) The icon is pushed down a bit * test: update test case * test: transfer part of tooltip test case to testing library (#35362) * test: refactor test cases of Space (#35372) * test: migrate part of anchor tests (#35371) * test: migrate part of checkbox tests (#35354) * fix: Carousel compatible with vertical property (#35349) * chore: fix npm start error in Gitpod close #33444 * Revert "chore: fix npm start error in Gitpod" This reverts commit 978226fb13a7ec2c4ee07bb8eeba6bb18188a622. * fix: table column filter reset is not working (#35226) (#35386) * fix: Respect user provided space item key (#35344) * Resolve Ant Design Notification component TypeScript error via adding maxCount as an ArgsProps property (#35369) * fix: use less variables for Segmented (#35387) * docs: reverse React 18 demo * feat: Dropdown support autoFocus (#35391) * feat: Dropdown support autoFocus * chore: add bundle size * test: replace textarea some test case with testing lib (#35398) * test: replace textarea some test case with testing lib * test: full process * test: mv input test to input scope * test: fix lint * refactor: Progress rebuild as function component (#35393) * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * refactor: Progress rebuild as function component * chore: rm useless console * chore: rm CODEOWNER since this block github action * test: transfer tooltip test case to testing library * ci: trigger the pr check * test: try to fix the pr check * test: remove some test case * test: foreach all placement * feat: focus menu item automaticly when focusing menu (#35407) * feat: focus menu item automaticly when focusing menu * chore: update mentions * test: fix test case * chore: decrease bundle size * chore: increase bundle size * fix(): wipe out unnecessary prop (#35409) * fix: wipe out unnecessary prop * wipe out unnecessary prop(`row-gap: 0px`) on * add test case * chore: remove unnecessary import * chore: add prop to Row and Col * chore: update snapshot (Form/Grid/Card) * chore: update snapshot * chore: move location * docs: explain Avatar fallback strategy (#35415) The original description was unclear, incomplete, and confusing, requiring a look at the code to understand it, so I revised it to a more understandable version. * fix: arrow style (#35401) * fix: arrow style * fix: raise arrow z-index * fix: fix defualt arrow color * fix: mix shadow * chore: code clean * chore: code clean * fix: use fadeout instead * test: fix style lint * test: replace some slepp with jest.runAllTimers * chore: update snapshot * Revert "test: replace some slepp with jest.runAllTimers" This reverts commit ad886d1f65d83a92bc9810d6d74c71a3dc1cc608. * fix: List.Item ref (#35321) * fix: list item ref * add test * improve * fix: List.Item typescript (#35418) * chore: eslint add consistent-type-imports (#35419) * chore: eslint add consistent-type-imports * fix avatar * Update Item.tsx * chore: change menu icon in site * docs: update mirror link (#35424) * docs: update mirror link * feat: add modal * feat: add icon * chore: code clean * feat: text * fix: cancel btn * chore: split chunks (#35222) * chore: split chunks * chore: update bisheng version * chore: split @ant-design/icon * chore: code clean * chore: test * chore: split moment * chore: code clean * fix: add missing localizations (#35430) * Add missing localizations * Update snapshot * refactor: Progress type="circle" for some issues (#35433) * refactor: Progress type="circle" for some issues close #17706 close #35009 close #35352 * test: update progress snapshot * docs: update linecap.md * Update components/progress/demo/linecap.md * test: update progress snapshot * fix: rc-progress@~3.3.1 * fix: rc-progress@~3.3.2 * docs: add 4.20.3 changelog (#35435) * docs: add 4.20.3 changelog * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 * fix typo * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 * Update CHANGELOG.en-US.md Co-authored-by: afc163 * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 * fix typo * fix typo * fix typo * fix typo Co-authored-by: afc163 * feat: edit date-picker to hook (#35425) * docs: update demo template (#35440) * docs: fix typo (#35439) * chore: fixed typo * chore: fixed typo+1 * chore(deps-dev): bump husky from 7.0.4 to 8.0.1 (#35451) Bumps [husky](https://github.com/typicode/husky) from 7.0.4 to 8.0.1. - [Release notes](https://github.com/typicode/husky/releases) - [Commits](https://github.com/typicode/husky/compare/v7.0.4...v8.0.1) --- updated-dependencies: - dependency-name: husky dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * test: update snapshot (#35452) * chore: optimze LGTM (#35443) * chore: optimze LGTM * chore: type * fix: dev broken (#35453) * chore(deps-dev): upgrade to jest 28 (#35334) https://jestjs.io/zh-Hans/docs/upgrading-to-jest28 * fix: bad List.Item type (#35454) (#35455) Co-authored-by: Ron Smeral * docs: replace class component with hooks (#35461) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * refactor: remove cascader displayRender warning (#35417) * refactor: remove useless warning (#35291) * refactor: remove useless test case * docs: remove cascader tagRender * perf: refactor devWarning for production code size (#35411) * pref: better code style for production * refactor `devWarning` * don't use `useEffect` only wrap `devWarning` * chore: add 'noop' to coverage * chore: add test cases for devWarning * chore: add test case * chore: update test cases for devWarning * chore: restore test script command * fix: remove 'throw new Error' * should not use `throw` for browser * chore: update test case for AutoComplete * perf: add prefix for `devWarning` * update RegExp for UMD * add prefix for ES and CJS * chore: better code style * perf: * upgrade antd-tools * remove `injectWarningCondition` * rename `devWarning` to `warning` * chore: better code style * chore: better code style * chore: restore hasValidName * docs: replace class component with hooks (#35472) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * chore: fix LGTM * docs: indicate that menu items require `key`s (#35474) * docs: remove editable in table documentation close https://github.com/ant-design/ant-design/pull/35471#issuecomment-1123239879 * fix: tree checkbox margin in rtl mode (#35491) * docs: Table QA about rowSelection renderCell (#35494) * Update index.zh-CN.md 之前需要在 可选列的勾选框 中增加 Tooltip,没有在文档中找到相关的文档,通过搜索 issue,以为暂时不支持,看了源码才发现已经支持了。 所以想要完善一下文档,可以方便其他用户找到此内容。 * docs: Table QA about rowSelection renderCell update US doc * docs: changelog 4.20.4 (#35495) * docs: changelog 4.20.4 * chore: emoji * docs: replace class component with hooks (#35500) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * docs(config-provider): replace class component with hooks * docs(date-picker): replace class component with hooks * test: update snapshot * fix(statistic): ignore the decimal part when the precision is negative (#35520) * test: Update snapshot * test: Update snapshot (#35529) * refactor: Card loading (#35525) * feat: card loading with skeleton * test: update snapshot * test: add style deps * chore: import * docs: update work with us part * refactor: modal confirm button style (#35530) * fix: modal rtl style * fix: cannot use logic css * chore: change css writing order * feat: update changelog * test: moving to testing-library in `Segmented` (#35538) * test(Segmented): moving to testing-library * chore: cleanup * fix: test * test: use click instead of change to fire event * Update index.test.tsx * fix: Picker focus & blur not working (#35552) * docs: replace class component with hooks (#35519) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * docs(config-provider): replace class component with hooks * docs(date-picker): replace class component with hooks * docs(drawer): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(empty): replace class component with hooks * docs(grid): replace class component with hooks * docs(input): replace class component with hooks * docs(input-number): replace class component with hooks * docs(demo): fix lint error * chore: deprecated rowSelection.onSelectNone and onSelectMultiple (#35545) * chore: del unused package && downgrade some packages which related webpack@5 (#35551) * docs: changelog 4.20.5 (#35560) * chore: Update github action release helper release title * fix: drawer close speed (#35339) * fix: drawer close speed * chroe: snap * chroe: test * chroe: test * feat: remove file * feat: 重新整理 * feat: forceRender * feat: snap * chroe: test * chroe: test * chroe: test * feat: create event * feat: diff code * feat: forceRender * chore: test (#35364) * Update components/drawer/index.tsx Co-authored-by: afc163 * feat: remove load state * feat: test * fix: destroyOnClose * feat: add load * fix: update snap * fix: update snap * feat: reset test * feat: docs * feat: test * feat: test Co-authored-by: afc163 * docs: fix 4.20.5 changelog typo (#35567) * refactor: reduce empty cycling deps (#35570) * chore: rm in root * chore: fix ts * test: Update snapshot * chore: ignore part * chore: delete extra spaces (#35582) Co-authored-by: hezhaoshun * docs: replace class component with hooks (#35580) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * docs(config-provider): replace class component with hooks * docs(date-picker): replace class component with hooks * docs(drawer): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(empty): replace class component with hooks * docs(grid): replace class component with hooks * docs(input): replace class component with hooks * docs(input-number): replace class component with hooks * docs(demo): fix lint error * docs(layout): replace class component with hooks * docs(list): replace class component with hooks * docs(mentions): replace class component with hooks * docs: fix code review issue * chore: bump tools version (#35594) * style: fix Table header border when has rowSpan (#35591) close #35577 * docs: Update CHANGELOG.zh-CN.md (#35604) * feat: add a new locale tk_TK (#35605) * feat: add a new locale tk_TK * fix: fix moment locale * feat: table rowSelection.onChange support type (#35598) * feat: table rowSelection onChange support method * docs: update * chore: rename param * test: update * test: update * Update rebase.yml * docs: Fix DatePicker throw demo * style: anchor text is overwritten (#35612) Co-authored-by: hezhaoshun * docs: replace class component with hooks (#35613) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * docs(config-provider): replace class component with hooks * docs(date-picker): replace class component with hooks * docs(drawer): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(empty): replace class component with hooks * docs(grid): replace class component with hooks * docs(input): replace class component with hooks * docs(input-number): replace class component with hooks * docs(demo): fix lint error * docs(layout): replace class component with hooks * docs(list): replace class component with hooks * docs(mentions): replace class component with hooks * docs: fix code review issue * docs(modal): replace class component with hooks * docs: feat components TS demo (#34742) * docs: add general components TS demo * docs: add layout components TS demo * docs: add navigation components TS demo * docs: add data entry components TS demo * chore(deps): add types for qs * docs: add data display TS demo * docs: add feedback components TS demo * docs: add other components TS demo * chore(deps): add types * docs: unified demo code style * docs: fix lint error * docs: add demo TS type * docs: fix demo TS type * test: update snapshot * docs: fix TS demo * feat: update Rate character type * docs: fix lint error * feat: update Rate character type * feat: update Rate character type * fix: Remove Grid row and cell aria roles (#35616) close https://github.com/ant-design/ant-design/issues/35549 * test: move test cases to `@testing/library` for Result (#35621) * fix: incorrect position of picker popup (#35620) Co-authored-by: yangpj17 close #35590 * feat: add-testing-lib (#35626) * docs: Convert part demo to ts version (#35641) * docs(badge): replace class component with hooks * docs(button): replace class component with hooks * docs(calendar): replace class component with hooks * docs(card): replace class component with hooks * docs(button): replace class component with hooks * chore(deps): remove webpack devDependencies * docs(cascader): replace class component with hooks * docs(checkbox): replace class component with hooks * docs(collapse): replace class component with hooks * docs(comment): replace class component with hooks * docs(descriptions): replace class component with hooks * docs(config-provider): replace class component with hooks * docs(date-picker): replace class component with hooks * docs(drawer): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(dropdown): replace class component with hooks * docs(empty): replace class component with hooks * docs(grid): replace class component with hooks * docs(input): replace class component with hooks * docs(input-number): replace class component with hooks * docs(demo): fix lint error * docs(layout): replace class component with hooks * docs(list): replace class component with hooks * docs(mentions): replace class component with hooks * docs: fix code review issue * docs(modal): replace class component with hooks * docs(pagination): replace class component with hooks * docs(popconfirm): replace class component with hooks * docs(popover): replace class component with hooks * docs(progress): replace class component with hooks * docs(rate): replace class component with hooks * docs(radio): replace class component with hooks * docs: jsx to TS demo * test: improve Select test case (#35633) * docs(mentions): fix debounce demo bug (#35653) * chore(deps-dev): bump @types/react-resizable from 1.7.4 to 3.0.0 (#35658) Bumps [@types/react-resizable](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-resizable) from 1.7.4 to 3.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-resizable) --- updated-dependencies: - dependency-name: "@types/react-resizable" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * test: refactor test cases of Timeline with testing library (#35654) * test: refactor test cases of TimeLine * fix: lint errors * chore(deps-dev): bump react-intl from 5.25.1 to 6.0.1 (#35659) Bumps [react-intl](https://github.com/formatjs/formatjs) from 5.25.1 to 6.0.1. - [Release notes](https://github.com/formatjs/formatjs/releases) - [Commits](https://github.com/formatjs/formatjs/compare/react-intl@5.25.1...react-intl@6.0.1) --- updated-dependencies: - dependency-name: react-intl dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: fix cheerio for enzyme fix (#35666) * docs: 4.20.6 changelog (#35671) * docs: 4.20.6 changelog * docs: fix build * test: Update snapshot * refactor: align with popover (#35676) * chore: short auto merge time * chore: update issue check mirror (#35680) * fix: division in less for Segmented (#35701) * fix: division in less for Segmented * fix: update * chore: increase bundle size (#35709) * docs: fix mistype (#35714) * docs: update demo code (#35695) * docs: update demo code * chore: increase bundle size * Revert "chore: increase bundle size" This reverts commit 1c75e5ab5a85259f4d610e33009072e3e9c9acd4. * fix: drawer can not ref form instance when open (#35706) * fix: drawer can not ref form instance when open * fix: test * feat: div ref * feat: test * feat: test * feat: test * feat: test * chore: lock stylelint (#35725) * fix: Popover arrow style (#35717) * feat: config provider support componentDisabled (#35718) * feat: config provider support componentDisable * test: update snapshot * docs: update * chore: code * docs: componentDisabled version (#35730) * test: Replace alert part test with testing lib (#35736) Co-authored-by: chenkan1 * chore(deps-dev): bump typescript from 4.6.4 to 4.7.2 (#35737) Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.4 to 4.7.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.4...v4.7.2) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs(select): fix type (#35726) * fix: demo ts type * mend * Update select-users.md * chore: move `@types/qs` from deps to devDeps (#35747) * feat: Config provider pagination showSizeChanger (#35750) * feat: support showSizeChanger * test: test case * fix: the ts wrong of card inteface (#35753) * fix: the ts wrong of card inteface * fix: add export cardproprs * feat: add card type test * docs(👍): update recommendation (#35758) * docs: update recommendation * Update recommendation.en-US.md * docs: fix skeleton demo (#35760) * refactor: Collapse replace expandIconPosition with logical position (#35770) * refactor: change collapse to logic position * test: Update snapshot * chore: force trigger CI * ci: use jest shard (#35622) * refactor: bump rc-collapse to stable dom (#35781) * chore: bump rc-collapse to stable dom * chore: clean up * test: Replace card component test with testing lib (#35751) * test: Replace card component test with testing lib * test: update the snapshot * docs: add note to custom BackTop demo (#35625) * docs: add note to custom BackTop demo * Apply suggestions from code review Co-authored-by: afc163 * test: lock eslint-plugin-jest version for false positive https://github.com/jest-community/eslint-plugin-jest/issues/1128 * test: move test cases to @testing/library for Tabs (#35796) * chore(deps): update dependency eslint-plugin-jest to ~26.4.0 (#35801) * chore(deps): update dependency eslint-plugin-jest to ~26.4.0 * Update package.json Co-authored-by: Renovate Bot Co-authored-by: afc163 * feat: change the changelog of 4.20.6 version * test: move test cases to @testing/library for Image (#35806) * docs: changelog for 4.20.7 (#35804) * docs: changelog for 4.20.7 * chore: bump version to 4.20.7 * docs: update changelog * refactor: Fix Dropdown nesting menu injection logic (#35810) * refactor: Dependency Inversion * test: update snapshot * test: Update snapshot * test: more * fix: table dropdown logic * fix: menu lint * chore: upgrade to jest-image-snapshot 5.x (#35818) * test: move test cases to @testing/library for Modal (#35785) * test: move test cases to @testing/library for Modal * update * fix: test * test: add test case for mouse position * chore: revert * fix: Progress type="line" strokeLinecap (#35822) * docs: fix typo of Menu items code example (#35832) * test: move test cases to @testing/library for Drawer (#35839) * perf: active skeleton animated with transform (#35836) * active skeleton animated with transform * properties order fixed * properties order fixed * properties order fixed Co-authored-by: afc163 * style: tweak Skeleton margin top style (#35848) * docs: update FAQ titles * test: move test cases to @testing/library for List (#35850) * chore: bump rc-dialog & update snapshot * fix: set jest shard to 2 (#35831) * fix: drawer close twice children is undefined (#35853) * fix: drawer close twice children is undefined * fix: drawer close twice children is undefined * chore: code * fix: test * test: update snapshot * fix: remove extraneous space from rc-segmented version (#35863) The extra spaces confuses third-party tooling * feat: Progress steps support custom strokeColor for each step (#35855) * feat: could accept string[] as strokeColor close #35852 close #26858 * fix: tsx demo * docs: add version column * chore: stlye patch of statistic (#35874) * chore: stlye patch of statistic * test: Udpate snapshot * test: replace Input part test with test lib (#35754) * test: replace Input part test with test lib * test: test input case * test: update textarea case Co-authored-by: z1399 Co-authored-by: afc163 * refactor: pagination mini className (#35881) * refactor: pagination mini cls * test: update snapshot * test: update snapshot * chore: code clean * chore: code clean * test: update snapshot * test: update snapshot * refactor: Wave in React 18 StrictMode (#35889) * feat: tabs support popupClassName (#35892) * feat: tabs support popupClassName * docs: update * fix:border-style for inputNumber addon when rtl (#35876) * chore(deps): update dependency @types/jest to v28 (#35907) Co-authored-by: Renovate Bot * ci: fix typo * fix: 类型“FormListFieldData”上不存在属性“fieldKey”。(#35883) (#35884) * fix: 类型“FormListFieldData”上不存在属性“fieldKey”。(#35883) * add deprecated tag to fieldKey * add changelog * Revert "add changelog" This reverts commit 2cc174f6338dbf073aa38133042f3d594a40b7b6. * chore: update changelog script (#35916) * docs: add typography format version * fix: remove important in radio style (#35920) * fix: remove important in radio style * chore: code clean * docs: correct types (#35919) * docs: correct types * ++ Co-authored-by: afc163 * test: migrate part of Button tests (#35869) * test: migrate part of Affix tests (#35860) * docs: add changelog 4.21.0 (#35915) * docs: add changelog 4.21.0 * Update CHANGELOG.en-US.md Co-authored-by: Amumu * Update CHANGELOG.zh-CN.md Co-authored-by: Amumu * docs: add * Update CHANGELOG.en-US.md * docs: fix * docs: add * docs: update * docs: fix * docs: remove 35407 Co-authored-by: Amumu * Feat: support 'treeExpandAction' prop for TreeSelect (#35618) * Feat: support 'treeExpandAction' prop for TreeSelect * chore: bump rc-tree * chore: fix lint * fix: fix directory tree duplicate expandAction * fix: fix directory tree duplicate expandAction * fix: fix directory tree duplicate expandAction * chore: add docs Co-authored-by: zombiej Co-authored-by: afc163 * chore: bump bundle size of babel runtime * docs: Update 4.21.0 changelog * docs: fix tree demo (#35927) * fix: Form.Item noStyle should not be affected by parent Form.Item (#35849) * fix: Form.Item noStyle should not be affected by parent Form.Item * test: update snapshot * fix: status * chore: code clean * fix: modal and drawer * test: fix lint * chore: code clean * refactor: noFormStyle * chore: code clean * revert: revert change in Form.Item * chore: code clean * test: replace test case with test library (#35925) * test: replace test case with test library * test: replace test case with test library * test: update snapshots * docs: clean up useless space * test: refactor tree with testing lib (#35937) * test: tree test * test: clean up * chore: bump rc-tree * test: Update snapshot * test: Update for react 18 * test: move test cases to testing lib (#35909) * test: move test cases to testing lib (#35900) * fix: menu items typings (#35790) * Fix menu items typings * add test case for menu item type checking * fix: cubic-bezier should be animation-timing-function (#35943) * chore: upgrade react-slick to 0.29.1 (#35959) * chore: upgrade react-slick to 0.29.0 * Update package.json * chore: fix code (#35949) * Fix color generation for grey colors (#35954) Co-authored-by: afc163 * fix: modify 'antd' to 'infrad' in loop-banner.md of alert * test: move test cases to @testing/library for Typography (#35955) * test: move test cases to @testing/library for Typography * fix: waitFor for tooltip test * fix: sleep to wait copy hide * test: refactor focus test * chore: Update it_IT.tsx (#35970) Fix italian translation for Table.cancelSort key * docs: Segmented API type (#35974) * Update index.en-US.md * Update index.zh-CN.md * fix: modify line-height value to @line-height-base of descriptions component * chore: fix typo * chore: bump rc-dialog version (#35969) * chore: bump rc-dialog version * chore: trigger * chore: trigger * docs: RM peer conflict demo * chore: bump deps version * chore: bump ver * chore: bump * chore: bump * chore: test * chore: rm peer * chore: clean all peer * chor: bump rc-image * fix: Button has no disabled style when link type (#35975) Co-authored-by: MadCcc <1075746765@qq.com> * fix: `DropdownProps` definition (#35990) Co-authored-by: jhonebee Co-authored-by: MadCcc <1075746765@qq.com> * chore(deps-dev): bump stylelint from 14.8.3 to 14.9.0 (#35998) Bumps [stylelint](https://github.com/stylelint/stylelint) from 14.8.3 to 14.9.0. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/14.8.3...14.9.0) --- updated-dependencies: - dependency-name: stylelint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: update ts config (#36000) * fix: Fixed the getContainer property in Image not reading the settings in ConfigProvider (#36002) * fix: 35942 * test: 添加测试用例 * fix: * fix: * fix: missing semicolon (#36008) * Update package.json * docs: fix onChange description repeated twice (#36013) * chore(deps): update dependency stylelint-config-standard to v26 (#36017) * chore(deps): update dependency stylelint-config-standard to v26 * chore: ignore selector-not-notation rule Co-authored-by: Renovate Bot Co-authored-by: afc163 * test: move test cases to testing lib for Statistic (#36019) Co-authored-by: afc163 * fix: remove the last tr's border-bottom of table component * test: replace Table part test with test lib (#35989) * test: replace Table part test with test lib * test: replace table test with test library * test: update snapshot * test: replace last mount * test: fix 18 testing Co-authored-by: zombiej * fix: roll back style changes of table component and fix some test case * fix: roll back style changes of table component and fix some test case * feat: pull new content from Antd * fix: remove style change of table component Co-authored-by: Zack Chang <73225408+jrr997@users.noreply.github.com> Co-authored-by: 黑雨 Co-authored-by: afc163 Co-authored-by: lalalazero Co-authored-by: Dreamcreative Co-authored-by: Walid Cherhane <56094829+walidcherhane@users.noreply.github.com> Co-authored-by: zombiej Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: PCCCCCCC Co-authored-by: linqiqi077 <865530219@qq.com> Co-authored-by: TrickyPi <33021497+TrickyPi@users.noreply.github.com> Co-authored-by: haipeng Co-authored-by: Yanlin Jiang Co-authored-by: Cooper Veysey Co-authored-by: vagusX Co-authored-by: MadCcc <1075746765@qq.com> Co-authored-by: shuaijiumei <63175611+shuaijiumei@users.noreply.github.com> Co-authored-by: Karott Schu Co-authored-by: parabolazz Co-authored-by: Tom Xu Co-authored-by: zhang lay Co-authored-by: Mykyta Velykanov Co-authored-by: 陈帅 Co-authored-by: Yanming Deng Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ron Šmeral Co-authored-by: Ron Smeral Co-authored-by: dingkang Co-authored-by: Tony Wu <93302820+tonywu6@users.noreply.github.com> Co-authored-by: miracles1919 <516571350@qq.com> Co-authored-by: limingxin <906529775@qq.com> Co-authored-by: ty888 <1506125048@qq.com> Co-authored-by: Yuki Zhang Co-authored-by: 叶枫 <7971419+crazyair@users.noreply.github.com> Co-authored-by: joson <373693643@qq.com> Co-authored-by: hezhaoshun Co-authored-by: 周晨阳 <59002875+ZZZCNY@users.noreply.github.com> Co-authored-by: Amumu Co-authored-by: 章鱼 Co-authored-by: Bart Piotrowski <31428082+bartpio@users.noreply.github.com> Co-authored-by: yykoypj <601924094@qq.com> Co-authored-by: Niyaz Akhmetov Co-authored-by: 社长长 Co-authored-by: chenkan1 Co-authored-by: zhao-huo-long Co-authored-by: Cong Zhang Co-authored-by: Long Hao (龙濠) <45565100+LongHaoo@users.noreply.github.com> Co-authored-by: Gabriel Haruki Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renovate Bot Co-authored-by: Peach Co-authored-by: MrHadEnough Co-authored-by: slotDumpling <67586451+slotDumpling@users.noreply.github.com> Co-authored-by: Mehdi Salem Naraghi Co-authored-by: 郑国庆 Co-authored-by: z1399 Co-authored-by: Luobo Zhang Co-authored-by: xrkffgg Co-authored-by: chenxiang <597219320@qq.com> Co-authored-by: 元凛 Co-authored-by: kalykun <984757534@qq.com> Co-authored-by: Shang Song <14830727+zggmd@users.noreply.github.com> Co-authored-by: Heaven <18418010+NE-SmallTown@users.noreply.github.com> Co-authored-by: MasaoBlue <16271994+MasaoBlue@users.noreply.github.com> Co-authored-by: 龙风 <455947455@qq.com> Co-authored-by: Christian Lechner <6638938+christian-lechner@users.noreply.github.com> Co-authored-by: Umberto Gariggio Co-authored-by: XIN HU Co-authored-by: muxin Co-authored-by: 苯苯 <91561865+robothot@users.noreply.github.com> Co-authored-by: jhonebee Co-authored-by: Taisuke Hinata --- .github/workflows/preview-build.yml | 2 +- .github/workflows/site-deploy.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/ui.yml | 2 +- .stylelintrc.json | 3 +- .../__snapshots__/demo-extend.test.ts.snap | 107 +-- .../__tests__/__snapshots__/demo.test.ts.snap | 107 +-- components/alert/demo/loop-banner.md | 30 +- .../auto-complete/__tests__/focus.test.js | 1 + .../auto-complete/__tests__/index.test.js | 1 + components/auto-complete/index.en-US.md | 2 +- components/back-top/__tests__/index.test.js | 1 + .../button/__tests__/delay-timer.test.tsx | 2 +- components/button/__tests__/index.test.tsx | 9 + components/button/__tests__/wave.test.tsx | 1 + components/button/button.tsx | 4 +- components/button/style/index.less | 4 + components/button/style/mixin.less | 18 + .../__tests__/components.test.js | 1 + .../__tests__/pagination.test.tsx | 1 + components/dropdown/dropdown.tsx | 1 + components/grid/__tests__/gap.test.js | 1 + components/image/__tests__/index.test.js | 15 + components/image/index.tsx | 21 +- components/input/__tests__/type.test.tsx | 1 + components/list/__tests__/empty.test.js | 1 + components/list/__tests__/index.test.js | 1 + components/list/__tests__/loading.test.js | 1 + components/list/__tests__/pagination.test.js | 1 + components/locale/it_IT.tsx | 8 +- components/menu/__tests__/type.test.tsx | 1 + components/pagination/__tests__/index.test.js | 1 + components/result/__tests__/index.test.tsx | 1 + components/segmented/index.en-US.md | 2 +- components/segmented/index.zh-CN.md | 2 +- .../{demo.test.js.snap => demo.test.ts.snap} | 0 ...index.test.js.snap => index.test.tsx.snap} | 0 .../__tests__/{demo.test.js => demo.test.ts} | 0 .../{index.test.js => index.test.tsx} | 115 ++- components/style/color/colorPalette.less | 4 + .../table/__tests__/Table.expand.test.js | 1 + .../table/__tests__/Table.order.test.js | 1 + .../__tests__/Table.rowSelection.test.js | 886 ++++++++++-------- .../Table.rowSelection.test.js.snap | 55 +- components/table/__tests__/empty.test.js | 1 + components/table/style/index.less | 18 +- components/tabs/__tests__/index.test.js | 1 + .../time-picker/__tests__/index.test.js | 1 + components/tree/__tests__/index.test.js | 1 + components/tree/__tests__/type.test.tsx | 1 + components/typography/__tests__/copy.test.tsx | 69 +- .../typography/__tests__/ellipsis.test.js | 227 +++-- .../__tests__/enter-key-callback.test.tsx | 10 +- components/typography/__tests__/index.test.js | 201 ++-- package.json | 18 +- tsconfig.json | 4 +- 56 files changed, 1090 insertions(+), 882 deletions(-) rename components/statistic/__tests__/__snapshots__/{demo.test.js.snap => demo.test.ts.snap} (100%) rename components/statistic/__tests__/__snapshots__/{index.test.js.snap => index.test.tsx.snap} (100%) rename components/statistic/__tests__/{demo.test.js => demo.test.ts} (100%) rename components/statistic/__tests__/{index.test.js => index.test.tsx} (52%) diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index 19a3a7397cce..0af77d36c4ec 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -30,7 +30,7 @@ jobs: key: lock-${{ github.sha }} - name: create package-lock.json - run: npm i --package-lock-only --ignore-scripts --legacy-peer-deps + run: npm i --package-lock-only --ignore-scripts - name: hack for single file run: | diff --git a/.github/workflows/site-deploy.yml b/.github/workflows/site-deploy.yml index 030faa4bda98..f358c151719a 100644 --- a/.github/workflows/site-deploy.yml +++ b/.github/workflows/site-deploy.yml @@ -22,7 +22,7 @@ jobs: key: lock-${{ github.sha }} - name: create package-lock.json - run: npm i --package-lock-only --ignore-scripts --legacy-peer-deps + run: npm i --package-lock-only --ignore-scripts - name: hack for single file run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85a76bb0f2dd..48f90107d35f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: key: lock-${{ github.sha }} - name: create package-lock.json - run: npm i --package-lock-only --ignore-scripts --legacy-peer-deps + run: npm i --package-lock-only --ignore-scripts - name: hack for single file run: | diff --git a/.github/workflows/ui.yml b/.github/workflows/ui.yml index 1bd7251ea6ea..be7cdf6d2425 100644 --- a/.github/workflows/ui.yml +++ b/.github/workflows/ui.yml @@ -28,7 +28,7 @@ jobs: node-version: '16' - name: create package-lock.json - run: npm i --package-lock-only --ignore-scripts --legacy-peer-deps + run: npm i --package-lock-only --ignore-scripts - name: hack for single file run: | diff --git a/.stylelintrc.json b/.stylelintrc.json index 3ee014415a18..89e5943dab20 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -37,7 +37,8 @@ "alpha-value-notation": "number", "color-function-notation": "legacy", "selector-class-pattern": null, - "selector-id-pattern": null + "selector-id-pattern": null, + "selector-not-notation": null }, "ignoreFiles": ["components/style/color/{bezierEasing,colorPalette,tinyColor}.less"] } diff --git a/components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap index 2b7d13fa4a44..640251439315 100644 --- a/components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/alert/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1323,89 +1323,38 @@ Array [ `; exports[`renders ./components/alert/demo/loop-banner.md extend context correctly 1`] = ` -Array [ - , + + + `; exports[`renders ./components/alert/demo/smooth-closed.md extend context correctly 1`] = ` diff --git a/components/alert/__tests__/__snapshots__/demo.test.ts.snap b/components/alert/__tests__/__snapshots__/demo.test.ts.snap index 754f073f05dc..0c633f8a9d8e 100644 --- a/components/alert/__tests__/__snapshots__/demo.test.ts.snap +++ b/components/alert/__tests__/__snapshots__/demo.test.ts.snap @@ -1323,89 +1323,38 @@ Array [ `; exports[`renders ./components/alert/demo/loop-banner.md correctly 1`] = ` -Array [ - , + + + `; exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = ` diff --git a/components/alert/demo/loop-banner.md b/components/alert/demo/loop-banner.md index dcb0375b8747..db9b3a2204d2 100644 --- a/components/alert/demo/loop-banner.md +++ b/components/alert/demo/loop-banner.md @@ -17,30 +17,16 @@ Show a loop banner by using with [react-text-loop-next](https://npmjs.com/packag import { Alert } from 'infrad'; import React from 'react'; import Marquee from 'react-fast-marquee'; -import { TextLoop } from 'react-text-loop-next'; const App: React.FC = () => ( - <> - -
Notice message one
-
Notice message two
-
Notice message three
-
Notice message four
- - } - /> - - I can be a React component, multiple React components, or just some text. - - } - /> - + + I can be a React component, multiple React components, or just some text. + + } + /> ); export default App; diff --git a/components/auto-complete/__tests__/focus.test.js b/components/auto-complete/__tests__/focus.test.js index 0a931765e727..4303b0f94daf 100644 --- a/components/auto-complete/__tests__/focus.test.js +++ b/components/auto-complete/__tests__/focus.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import { act } from 'react-dom/test-utils'; import AutoComplete from '..'; import { render } from '../../../tests/utils'; diff --git a/components/auto-complete/__tests__/index.test.js b/components/auto-complete/__tests__/index.test.js index 7c239bd800aa..7686e70722ab 100644 --- a/components/auto-complete/__tests__/index.test.js +++ b/components/auto-complete/__tests__/index.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import AutoComplete from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/auto-complete/index.en-US.md b/components/auto-complete/index.en-US.md index ada53bfa105f..b8963850b0b3 100644 --- a/components/auto-complete/index.en-US.md +++ b/components/auto-complete/index.en-US.md @@ -41,7 +41,7 @@ The differences with Select are: | status | Set validation status | 'error' \| 'warning' | - | 4.19.0 | | value | Selected option | string | - | | | onBlur | Called when leaving the component | function() | - | | -| onChange | Called when select an option or input value change, or value of input is changed | function(value) | - | | +| onChange | Called when selecting an option or changing an input value | function(value) | - | | | onDropdownVisibleChange | Call when dropdown open | function(open) | - | | | onFocus | Called when entering the component | function() | - | | | onSearch | Called when searching items | function(value) | - | | diff --git a/components/back-top/__tests__/index.test.js b/components/back-top/__tests__/index.test.js index 605ded5dadbd..2a0422c279e9 100644 --- a/components/back-top/__tests__/index.test.js +++ b/components/back-top/__tests__/index.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import BackTop from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/button/__tests__/delay-timer.test.tsx b/components/button/__tests__/delay-timer.test.tsx index 43c993df6fcf..4f4f724f21d9 100644 --- a/components/button/__tests__/delay-timer.test.tsx +++ b/components/button/__tests__/delay-timer.test.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import React, { useState } from 'react'; import { act } from 'react-dom/test-utils'; import { fireEvent, render } from '../../../tests/utils'; import Button from '../button'; diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index 3536e993bd6c..da758c29ea22 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -328,6 +328,15 @@ describe('Button', () => { expect(onClick).not.toHaveBeenCalled(); }); + it('should match class .ant-btn-disabled when button is disabled and href is not undefined', () => { + const wrapper = render( + , + ); + expect(wrapper.container.querySelector('.ant-btn')).toHaveClass('ant-btn-disabled'); + }); + // https://github.com/ant-design/ant-design/issues/30953 it('should handle fragment as children', () => { const wrapper = render( diff --git a/components/button/__tests__/wave.test.tsx b/components/button/__tests__/wave.test.tsx index 0921ba68d698..bcda6baf6364 100644 --- a/components/button/__tests__/wave.test.tsx +++ b/components/button/__tests__/wave.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Button from '..'; import { fireEvent, render, sleep } from '../../../tests/utils'; diff --git a/components/button/button.tsx b/components/button/button.tsx index 05667c65f432..538fe0a157fb 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -247,6 +247,8 @@ const InternalButton: React.ForwardRefRenderFunction = (pr const iconType = innerLoading ? 'loading' : icon; + const linkButtonRestProps = omit(rest as AnchorButtonProps & { navigate: any }, ['navigate']); + const classes = classNames( prefixCls, { @@ -260,6 +262,7 @@ const InternalButton: React.ForwardRefRenderFunction = (pr [`${prefixCls}-block`]: block, [`${prefixCls}-dangerous`]: !!danger, [`${prefixCls}-rtl`]: direction === 'rtl', + [`${prefixCls}-disabled`]: linkButtonRestProps.href !== undefined && mergedDisabled, }, className, ); @@ -276,7 +279,6 @@ const InternalButton: React.ForwardRefRenderFunction = (pr ? spaceChildren(children, isNeedInserted() && autoInsertSpace) : null; - const linkButtonRestProps = omit(rest as AnchorButtonProps & { navigate: any }, ['navigate']); if (linkButtonRestProps.href !== undefined) { return ( diff --git a/components/button/style/index.less b/components/button/style/index.less index 90d32a396471..a0f124cc53ba 100644 --- a/components/button/style/index.less +++ b/components/button/style/index.less @@ -284,6 +284,10 @@ a.@{btn-prefix-cls} { padding-top: 0.01px !important; line-height: @btn-height-base - 2px; + &-disabled { + .btn-href-disabled(); + } + &-lg { line-height: @btn-height-lg - 2px; } diff --git a/components/button/style/mixin.less b/components/button/style/mixin.less index ec50719495ba..dd6af48bc358 100644 --- a/components/button/style/mixin.less +++ b/components/button/style/mixin.less @@ -386,6 +386,24 @@ } .button-disabled(@disabled-color; transparent; transparent); } +// link button disabled style +.btn-href-disabled() { + cursor: not-allowed; + + > * { + pointer-events: none; + } + + &, + &:hover, + &:focus, + &:active { + .button-color(@btn-disable-color,transparent, transparent); + + text-shadow: none; + box-shadow: none; + } +} // text button style .btn-text() { .button-variant-other(@text-color, transparent, transparent); diff --git a/components/config-provider/__tests__/components.test.js b/components/config-provider/__tests__/components.test.js index 8b37ded3dc11..c14454dea831 100644 --- a/components/config-provider/__tests__/components.test.js +++ b/components/config-provider/__tests__/components.test.js @@ -1,5 +1,6 @@ import { render } from 'enzyme'; import moment from 'moment'; +import React from 'react'; import ConfigProvider from '..'; import Alert from '../../alert'; import Anchor from '../../anchor'; diff --git a/components/config-provider/__tests__/pagination.test.tsx b/components/config-provider/__tests__/pagination.test.tsx index fc8bf00d3f9e..4ccfc03193a6 100644 --- a/components/config-provider/__tests__/pagination.test.tsx +++ b/components/config-provider/__tests__/pagination.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import ConfigProvider from '..'; import { render } from '../../../tests/utils'; import Pagination from '../../pagination'; diff --git a/components/dropdown/dropdown.tsx b/components/dropdown/dropdown.tsx index 377210ab3ec8..a0b15174ada4 100644 --- a/components/dropdown/dropdown.tsx +++ b/components/dropdown/dropdown.tsx @@ -44,6 +44,7 @@ export type DropdownArrowOptions = { }; export interface DropdownProps { + autoFocus?: boolean; arrow?: boolean | DropdownArrowOptions; trigger?: ('click' | 'hover' | 'contextMenu')[]; overlay: React.ReactElement | OverlayFunc; diff --git a/components/grid/__tests__/gap.test.js b/components/grid/__tests__/gap.test.js index d8d6381ccacc..faab99d8994a 100644 --- a/components/grid/__tests__/gap.test.js +++ b/components/grid/__tests__/gap.test.js @@ -1,4 +1,5 @@ import { mount } from 'enzyme'; +import React from 'react'; import ReactDOMServer from 'react-dom/server'; import { Col, Row } from '..'; import { render, screen } from '../../../tests/utils'; diff --git a/components/image/__tests__/index.test.js b/components/image/__tests__/index.test.js index 181980e76f6e..873be7e01bae 100644 --- a/components/image/__tests__/index.test.js +++ b/components/image/__tests__/index.test.js @@ -1,7 +1,9 @@ +import React from 'react'; import Image from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render } from '../../../tests/utils'; +import ConfigProvider from '../../config-provider'; const src = 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'; @@ -75,4 +77,17 @@ describe('Image', () => { expect(baseElement.querySelector('.ant-image-preview')).toHaveClass('abc'); expect(baseElement.querySelector('.ant-image-preview-mask')).toHaveClass('def'); }); + it('ConfigProvider getPopupContainer', () => { + const { container: wrapper, baseElement } = render( + <> +
+ document.querySelector('.container')}> + + + , + ); + fireEvent.click(wrapper.querySelector('.ant-image')); + const containerElement = baseElement.querySelector('.container'); + expect(containerElement.children.length).not.toBe(0); + }); }); diff --git a/components/image/index.tsx b/components/image/index.tsx index ddd6435524c0..2bd536b4b9f7 100644 --- a/components/image/index.tsx +++ b/components/image/index.tsx @@ -1,11 +1,11 @@ -import * as React from 'react'; -import { useContext } from 'react'; import { EyeOutlined } from 'infra-design-icons'; import RcImage, { ImageProps } from 'rc-image'; -import defaultLocale from '../locale/en_US'; -import PreviewGroup, { icons } from './PreviewGroup'; +import * as React from 'react'; +import { useContext } from 'react'; import { ConfigContext } from '../config-provider'; +import defaultLocale from '../locale/en_US'; import { getTransitionName } from '../_util/motion'; +import PreviewGroup, { icons } from './PreviewGroup'; export interface CompositionImage

extends React.FC

{ PreviewGroup: typeof PreviewGroup; @@ -16,11 +16,15 @@ const Image: CompositionImage = ({ preview, ...otherProps }) => { - const { getPrefixCls } = useContext(ConfigContext); + const { + getPrefixCls, + locale: contextLocale = defaultLocale, + getPopupContainer: getContextPopupContainer, + } = useContext(ConfigContext); + const prefixCls = getPrefixCls('image', customizePrefixCls); const rootPrefixCls = getPrefixCls(); - const { locale: contextLocale = defaultLocale } = useContext(ConfigContext); const imageLocale = contextLocale.Image || defaultLocale.Image; const mergedPreview = React.useMemo(() => { @@ -28,7 +32,7 @@ const Image: CompositionImage = ({ return preview; } const _preview = typeof preview === 'object' ? preview : {}; - + const { getContainer, ...restPreviewProps } = _preview; return { mask: (

@@ -37,7 +41,8 @@ const Image: CompositionImage = ({
), icons, - ..._preview, + ...restPreviewProps, + getContainer: getContainer || getContextPopupContainer, transitionName: getTransitionName(rootPrefixCls, 'zoom', _preview.transitionName), maskTransitionName: getTransitionName(rootPrefixCls, 'fade', _preview.maskTransitionName), }; diff --git a/components/input/__tests__/type.test.tsx b/components/input/__tests__/type.test.tsx index 83ea0dd049fd..8f509b0a2549 100644 --- a/components/input/__tests__/type.test.tsx +++ b/components/input/__tests__/type.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Input from '..'; import { render } from '../../../tests/utils'; import type { InputProps } from '../Input'; diff --git a/components/list/__tests__/empty.test.js b/components/list/__tests__/empty.test.js index d7d710d64bc9..333d4e618313 100644 --- a/components/list/__tests__/empty.test.js +++ b/components/list/__tests__/empty.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import List from '..'; import { render } from '../../../tests/utils'; diff --git a/components/list/__tests__/index.test.js b/components/list/__tests__/index.test.js index 8b088b57d1b6..e1ee6944f1ba 100644 --- a/components/list/__tests__/index.test.js +++ b/components/list/__tests__/index.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import List from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/list/__tests__/loading.test.js b/components/list/__tests__/loading.test.js index f1371c65e00a..771242759ed2 100644 --- a/components/list/__tests__/loading.test.js +++ b/components/list/__tests__/loading.test.js @@ -1,4 +1,5 @@ import { LoadingOutlined } from 'infra-design-icons'; +import React from 'react'; import { render } from '../../../tests/utils'; import List from '..'; diff --git a/components/list/__tests__/pagination.test.js b/components/list/__tests__/pagination.test.js index f7b775681062..98a59b53f8f3 100644 --- a/components/list/__tests__/pagination.test.js +++ b/components/list/__tests__/pagination.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import List from '..'; import { fireEvent, render } from '../../../tests/utils'; import { noop } from '../../_util/warning'; diff --git a/components/locale/it_IT.tsx b/components/locale/it_IT.tsx index a47666a06e6d..a93b4cf47bb5 100644 --- a/components/locale/it_IT.tsx +++ b/components/locale/it_IT.tsx @@ -1,8 +1,8 @@ import Pagination from 'rc-pagination/lib/locale/it_IT'; -import DatePicker from '../date-picker/locale/it_IT'; -import TimePicker from '../time-picker/locale/it_IT'; import Calendar from '../calendar/locale/it_IT'; +import DatePicker from '../date-picker/locale/it_IT'; import type { Locale } from '../locale-provider'; +import TimePicker from '../time-picker/locale/it_IT'; const localeValues: Locale = { locale: 'it', @@ -23,8 +23,8 @@ const localeValues: Locale = { selectInvert: 'Inverti selezione nella pagina corrente', sortTitle: 'Ordina', triggerDesc: 'Clicca per ordinare in modo discendente', - triggerAsc: 'Clicca per ordinare in modo ascendente', - cancelSort: 'Clicca per eliminare i filtri', + triggerAsc: 'Clicca per ordinare in modo ascendente', + cancelSort: "Clicca per eliminare l'ordinamento", }, Modal: { okText: 'OK', diff --git a/components/menu/__tests__/type.test.tsx b/components/menu/__tests__/type.test.tsx index 85f178c9e428..0d5b0b494fbb 100644 --- a/components/menu/__tests__/type.test.tsx +++ b/components/menu/__tests__/type.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Menu from '..'; describe('Menu.typescript', () => { diff --git a/components/pagination/__tests__/index.test.js b/components/pagination/__tests__/index.test.js index 3953298695f7..7aa32e9e1cc2 100644 --- a/components/pagination/__tests__/index.test.js +++ b/components/pagination/__tests__/index.test.js @@ -1,4 +1,5 @@ import { mount } from 'enzyme'; +import React from 'react'; import Pagination from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/result/__tests__/index.test.tsx b/components/result/__tests__/index.test.tsx index 69aa2cb1e3ae..8ea775d70df5 100644 --- a/components/result/__tests__/index.test.tsx +++ b/components/result/__tests__/index.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Result from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/segmented/index.en-US.md b/components/segmented/index.en-US.md index 3c2969afca51..d9bb97bfc306 100644 --- a/components/segmented/index.en-US.md +++ b/components/segmented/index.en-US.md @@ -22,6 +22,6 @@ Segmented Controls. This component is available since `antd@4.20.0`. | defaultValue | Default selected value | string \| number | | | | disabled | Disable all segments | boolean | false | | | onChange | The callback function that is triggered when the state changes | function(value: string \| number) | | | -| options | Set children optional | string\[] \| number\[] \| Array<{ label: string value: string icon? ReactNode disabled?: boolean className?: string }> | [] | | +| options | Set children optional | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | | | size | The size of the Segmented. | `large` \| `middle` \| `small` | - | | | value | Currently selected value | string \| number | | | diff --git a/components/segmented/index.zh-CN.md b/components/segmented/index.zh-CN.md index 057926f57c97..df42c9969db2 100644 --- a/components/segmented/index.zh-CN.md +++ b/components/segmented/index.zh-CN.md @@ -25,6 +25,6 @@ cover: https://gw.alipayobjects.com/zos/bmw-prod/a3ff040f-24ba-43e0-92e9-c845df1 | defaultValue | 默认选中的值 | string \| number | | | | disabled | 是否禁用 | boolean | false | | | onChange | 选项变化时的回调函数 | function(value: string \| number) | | | -| options | 数据化配置选项内容 | string\[] \| number\[] \| Array<{ label: string value: string icon? ReactNode disabled?: boolean className?: string }> | [] | | +| options | 数据化配置选项内容 | string\[] \| number\[] \| Array<{ label: ReactNode value: string icon? ReactNode disabled?: boolean className?: string }> | [] | | | size | 控件尺寸 | `large` \| `middle` \| `small` | - | | | value | 当前选中的值 | string \| number | | | diff --git a/components/statistic/__tests__/__snapshots__/demo.test.js.snap b/components/statistic/__tests__/__snapshots__/demo.test.ts.snap similarity index 100% rename from components/statistic/__tests__/__snapshots__/demo.test.js.snap rename to components/statistic/__tests__/__snapshots__/demo.test.ts.snap diff --git a/components/statistic/__tests__/__snapshots__/index.test.js.snap b/components/statistic/__tests__/__snapshots__/index.test.tsx.snap similarity index 100% rename from components/statistic/__tests__/__snapshots__/index.test.js.snap rename to components/statistic/__tests__/__snapshots__/index.test.tsx.snap diff --git a/components/statistic/__tests__/demo.test.js b/components/statistic/__tests__/demo.test.ts similarity index 100% rename from components/statistic/__tests__/demo.test.js rename to components/statistic/__tests__/demo.test.ts diff --git a/components/statistic/__tests__/index.test.js b/components/statistic/__tests__/index.test.tsx similarity index 52% rename from components/statistic/__tests__/index.test.js rename to components/statistic/__tests__/index.test.tsx index 111c4d7f88f3..270e0410f315 100644 --- a/components/statistic/__tests__/index.test.js +++ b/components/statistic/__tests__/index.test.tsx @@ -1,13 +1,12 @@ -import React from 'react'; import MockDate from 'mockdate'; import moment from 'moment'; -import { mount } from 'enzyme'; -import { fireEvent, render } from '@testing-library/react'; +import React from 'react'; import Statistic from '..'; -import { formatTimeStr } from '../utils'; -import { sleep } from '../../../tests/utils'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { fireEvent, render, sleep } from '../../../tests/utils'; +import type Countdown from '../Countdown'; +import { formatTimeStr } from '../utils'; describe('Statistic', () => { mountTest(Statistic); @@ -23,32 +22,34 @@ describe('Statistic', () => { }); it('`-` is not a number', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-statistic-content').text()).toEqual('-'); + const { container } = render(); + expect(container.querySelector('.ant-statistic-content')!.textContent).toEqual('-'); }); it('customize formatter', () => { const formatter = jest.fn(() => 93); - const wrapper = mount(); + const { container } = render(); expect(formatter).toHaveBeenCalledWith(1128); - expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('93'); + expect(container.querySelector('.ant-statistic-content-value')!.textContent).toEqual('93'); }); it('groupSeparator', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('1__TEST__128'); + const { container } = render(); + expect(container.querySelector('.ant-statistic-content-value')!.textContent).toEqual( + '1__TEST__128', + ); }); it('not a number', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-statistic-content-value').text()).toEqual('bamboo'); + const { container } = render(); + expect(container.querySelector('.ant-statistic-content-value')!.textContent).toEqual('bamboo'); }); it('support negetive number', () => { - const wrapper = mount( + const { asFragment } = render( , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('allow negetive precision', () => { @@ -58,28 +59,32 @@ describe('Statistic', () => { [-3, -1112893.1212, '-1,112,893'], [-1, -1112893, '-1,112,893'], [-1, 1112893, '1,112,893'], - ].forEach(([precision, value, expectValue]) => { - const wrapper = mount(); - expect(wrapper.find('.ant-statistic-content-value-int').text()).toEqual(expectValue); - expect(wrapper.find('.ant-statistic-content-value-decimal').length).toBe(0); + ].forEach(([precision, value, expectValue]: [number, number, string]) => { + const { container } = render(); + expect(container.querySelector('.ant-statistic-content-value-int')!.textContent).toEqual( + expectValue, + ); + expect(container.querySelectorAll('.ant-statistic-content-value-decimal').length).toBe(0); }); }); it('loading with skeleton', async () => { let loading = false; - const wrapper = mount(); - expect(wrapper.find('.ant-skeleton')).toHaveLength(0); - expect(wrapper.find('.ant-statistic-content')).toHaveLength(1); + const { container, rerender } = render( + , + ); + expect(container.querySelectorAll('.ant-skeleton')).toHaveLength(0); + expect(container.querySelectorAll('.ant-statistic-content')).toHaveLength(1); loading = true; - wrapper.setProps({ loading }); - expect(wrapper.find('.ant-skeleton')).toHaveLength(1); - expect(wrapper.find('.ant-statistic-content')).toHaveLength(0); + rerender(); + expect(container.querySelectorAll('.ant-skeleton')).toHaveLength(1); + expect(container.querySelectorAll('.ant-statistic-content')).toHaveLength(0); }); describe('Countdown', () => { it('render correctly', () => { - const now = moment().add(2, 'd').add(11, 'h').add(28, 'm').add(9, 's').add(3, 'ms'); + const now = moment().add(2, 'd').add(11, 'h').add(28, 'm').add(9, 's').add(3, 'ms').valueOf(); [ ['H:m:s', '59:28:9'], @@ -87,25 +92,31 @@ describe('Statistic', () => { ['HH:mm:ss:SSS', '59:28:09:003'], ['DD-HH:mm:ss', '02-11:28:09'], ].forEach(([format, value]) => { - const wrapper = mount(); - expect(wrapper.find('.ant-statistic-content-value').text()).toEqual(value); + const { container } = render(); + expect(container.querySelector('.ant-statistic-content-value')!.textContent).toEqual(value); }); }); it('time going', async () => { const now = Date.now() + 1000; const onFinish = jest.fn(); - const wrapper = mount(); - wrapper.update(); + let instance: Countdown | null; + const { unmount } = render( + { + instance = n; + }} + value={now} + onFinish={onFinish} + />, + ); // setInterval should work - const instance = wrapper.find('Countdown').instance(); - expect(instance.countdownId).not.toBe(undefined); + expect(instance!.countdownId).not.toBe(undefined); await sleep(10); - wrapper.unmount(); - expect(instance.countdownId).toBe(undefined); + unmount(); expect(onFinish).not.toHaveBeenCalled(); }); @@ -115,21 +126,21 @@ describe('Statistic', () => { const { container } = render( , ); - fireEvent.mouseEnter(container.firstChild); + fireEvent.mouseEnter(container.firstChild!); expect(onMouseEnter).toHaveBeenCalled(); - fireEvent.mouseLeave(container.firstChild); + fireEvent.mouseLeave(container.firstChild!); expect(onMouseLeave).toHaveBeenCalled(); }); it('responses hover events for Countdown', () => { const onMouseEnter = jest.fn(); const onMouseLeave = jest.fn(); - const wrapper = mount( + const { container } = render( , ); - wrapper.simulate('mouseenter'); + fireEvent.mouseEnter(container.firstChild!); expect(onMouseEnter).toHaveBeenCalled(); - wrapper.simulate('mouseleave'); + fireEvent.mouseLeave(container.firstChild!); expect(onMouseLeave).toHaveBeenCalled(); }); @@ -138,11 +149,11 @@ describe('Statistic', () => { const deadline = Date.now() + 10 * 1000; let remainingTime; - const onChange = value => { + const onChange = (value: number) => { remainingTime = value; }; - const wrapper = mount(); - wrapper.update(); + render(); + // container.update(); await sleep(100); expect(remainingTime).toBeGreaterThan(0); }); @@ -151,20 +162,26 @@ describe('Statistic', () => { describe('time finished', () => { it('not call if time already passed', () => { const now = Date.now() - 1000; - + let instance: Countdown | null; const onFinish = jest.fn(); - const wrapper = mount(); - wrapper.update(); - - expect(wrapper.find('Countdown').instance().countdownId).toBe(undefined); + render( + { + instance = n; + }} + value={now} + onFinish={onFinish} + />, + ); + + expect(instance!.countdownId).toBe(undefined); expect(onFinish).not.toHaveBeenCalled(); }); it('called if finished', async () => { const now = Date.now() + 10; const onFinish = jest.fn(); - const wrapper = mount(); - wrapper.update(); + render(); MockDate.set(moment('2019-11-28 00:00:00').valueOf()); await sleep(100); expect(onFinish).toHaveBeenCalled(); diff --git a/components/style/color/colorPalette.less b/components/style/color/colorPalette.less index f3e175d825f3..e662c072a133 100644 --- a/components/style/color/colorPalette.less +++ b/components/style/color/colorPalette.less @@ -31,6 +31,10 @@ return Math.round(hue); }; var getSaturation = function(hsv, i, isLight) { + // grey color don't change saturation + if (hsv.h === 0 && hsv.s === 0) { + return hsv.s; + } var saturation; if (isLight) { saturation = hsv.s - saturationStep * i; diff --git a/components/table/__tests__/Table.expand.test.js b/components/table/__tests__/Table.expand.test.js index 9dcf8a7ed90b..57cf4a74dc5a 100644 --- a/components/table/__tests__/Table.expand.test.js +++ b/components/table/__tests__/Table.expand.test.js @@ -1,4 +1,5 @@ /* eslint-disable react/no-multi-comp */ +import React from 'react'; import Table from '..'; import { fireEvent, render } from '../../../tests/utils'; diff --git a/components/table/__tests__/Table.order.test.js b/components/table/__tests__/Table.order.test.js index d669ac07b8a6..db3ed54aa605 100644 --- a/components/table/__tests__/Table.order.test.js +++ b/components/table/__tests__/Table.order.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import Table from '..'; import { render } from '../../../tests/utils'; import { resetWarned } from '../../_util/warning'; diff --git a/components/table/__tests__/Table.rowSelection.test.js b/components/table/__tests__/Table.rowSelection.test.js index e7c4e6fe29f3..7877ffd26d63 100644 --- a/components/table/__tests__/Table.rowSelection.test.js +++ b/components/table/__tests__/Table.rowSelection.test.js @@ -1,8 +1,7 @@ -import { mount } from 'enzyme'; +import React from 'react'; import { act } from 'react-dom/test-utils'; import Table from '..'; -import { render } from '../../../tests/utils'; -import Checkbox from '../../checkbox'; +import { fireEvent, render } from '../../../tests/utils'; import ConfigProvider from '../../config-provider'; import { resetWarned } from '../../_util/warning'; @@ -38,80 +37,88 @@ describe('Table.rowSelection', () => { return ; } - function renderedNames(wrapper) { - return wrapper.find('BodyRow').map(row => row.props().record.name); + function renderedNames(contain) { + const namesList = []; + contain + .querySelector('.ant-table-tbody') + .querySelectorAll('tr') + .forEach(tr => { + namesList.push(tr.querySelectorAll('td')[1].textContent); + }); + return namesList; } - function getSelections(wrapper) { - return wrapper - .find('BodyRow') - .map(row => { - const { key } = row.props().record; - if (!row.find('input').at(0).props().checked) { - return null; + function getSelections(container) { + const keys = []; + container.querySelectorAll('.ant-table-tbody tr').forEach(row => { + const key = row.getAttribute('data-row-key'); + if (row.querySelector('input').checked) { + if (isNaN(Number(key))) { + // rowKey + keys.push(key); + } else { + keys.push(Number(key)); } - - return key; - }) - .filter(key => key !== null); + } + }); + return keys; } - function getIndeterminateSelection(wrapper) { - return wrapper - .find('BodyRow') - .map(row => { - const { key } = row.props().record; - if (!row.find('Checkbox').at(0).props().indeterminate) { - return null; + function getIndeterminateSelection(container) { + const keys = []; + container.querySelectorAll('.ant-table-tbody tr').forEach(row => { + const key = row.getAttribute('data-row-key'); + if (row.querySelector('.ant-checkbox-indeterminate')) { + if (isNaN(Number(key))) { + // rowKey + keys.push(key); + } else { + keys.push(Number(key)); } - - return key; - }) - .filter(key => key !== null); + } + }); + return keys; } it('select default row', () => { - const wrapper = mount(createTable({ rowSelection: { defaultSelectedRowKeys: [0] } })); - const checkboxes = wrapper.find('input'); - - expect(getSelections(wrapper)).toEqual([0]); + const { container } = render(createTable({ rowSelection: { defaultSelectedRowKeys: [0] } })); + const checkboxes = container.querySelectorAll('input[type="checkbox"]'); + expect(getSelections(container)).toEqual([0]); - checkboxes.at(1).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([]); + fireEvent.click(checkboxes[1]); + expect(getSelections(container)).toEqual([]); - checkboxes.at(0).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([0, 1, 2, 3]); + fireEvent.click(checkboxes[0]); + expect(getSelections(container)).toEqual([0, 1, 2, 3]); - checkboxes.at(0).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([]); + fireEvent.click(checkboxes[0]); + expect(getSelections(container)).toEqual([]); }); it('select by checkbox', () => { - const wrapper = mount(createTable()); - const checkboxes = wrapper.find('input'); - const checkboxAll = checkboxes.first(); + const { container } = render(createTable()); + const checkboxes = container.querySelectorAll('input[type="checkbox"]'); - checkboxAll.simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([0, 1, 2, 3]); + fireEvent.click(checkboxes[0]); + expect(getSelections(container)).toEqual([0, 1, 2, 3]); - checkboxes.at(1).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([1, 2, 3]); + fireEvent.click(checkboxes[1]); + expect(getSelections(container)).toEqual([1, 2, 3]); - checkboxes.at(1).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([0, 1, 2, 3]); + fireEvent.click(checkboxes[1]); + expect(getSelections(container)).toEqual([0, 1, 2, 3]); }); it('select by radio', () => { - const wrapper = mount(createTable({ rowSelection: { type: 'radio' } })); - const radios = wrapper.find('input'); + const { container } = render(createTable({ rowSelection: { type: 'radio' } })); + const radios = container.querySelectorAll('input[type="radio"]'); expect(radios.length).toBe(4); - radios.first().simulate('click'); - radios.first().simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([0]); + fireEvent.click(radios[0]); + expect(getSelections(container)).toEqual([0]); - radios.last().simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([3]); + fireEvent.click(radios[radios.length - 1]); + expect(getSelections(container)).toEqual([3]); }); it('pass getCheckboxProps to checkbox', () => { @@ -123,15 +130,15 @@ describe('Table.rowSelection', () => { }), }; - const wrapper = mount(createTable({ rowSelection })); - const checkboxes = wrapper.find('input'); + const { container } = render(createTable({ rowSelection })); + const checkboxes = container.querySelectorAll('input[type="checkbox"]'); - expect(checkboxes.at(1).props().disabled).toBe(false); - expect(checkboxes.at(1).props().name).toEqual(data[0].name); - expect(checkboxes.at(2).props().disabled).toBe(true); - expect(checkboxes.at(2).props().name).toEqual(data[1].name); + expect(checkboxes[1].disabled).toBe(false); + expect(checkboxes[1].name).toEqual(data[0].name); + expect(checkboxes[2].disabled).toBe(true); + expect(checkboxes[2].name).toEqual(data[1].name); - expect(getIndeterminateSelection(wrapper)).toEqual([2]); + expect(getIndeterminateSelection(container)).toEqual([2]); }); it("make getCheckboxProps's `indeterminate` override selectedRowKeys' effect", () => { @@ -144,31 +151,31 @@ describe('Table.rowSelection', () => { selectedRowKeys: [2], }; - const wrapper = mount(createTable({ rowSelection })); - expect(getIndeterminateSelection(wrapper)).toEqual([2]); + const { container } = render(createTable({ rowSelection })); + expect(getIndeterminateSelection(container)).toEqual([2]); }); it('works with pagination', () => { - const wrapper = mount(createTable({ pagination: { pageSize: 2 } })); - const pagers = wrapper.find('Pager'); - - wrapper - .find('input') - .first() - .simulate('change', { target: { checked: true } }); - expect(wrapper.find('Checkbox').first().props()).toEqual( - expect.objectContaining({ checked: true, indeterminate: false }), - ); - - pagers.at(1).simulate('click'); - expect(wrapper.find('Checkbox').first().props()).toEqual( - expect.objectContaining({ checked: false, indeterminate: false }), - ); - - pagers.at(0).simulate('click'); - expect(wrapper.find('Checkbox').first().props()).toEqual( - expect.objectContaining({ checked: true, indeterminate: false }), - ); + const { container } = render(createTable({ pagination: { pageSize: 2 } })); + + const pagers = container.querySelectorAll('.ant-pagination-item'); + const checkboxAll = container.querySelector('input[type="checkbox"]'); + + const objectContaining = {}; + fireEvent.click(checkboxAll); + objectContaining.checked = checkboxAll.checked; // true + objectContaining.indeterminate = getIndeterminateSelection(container).length > 0; // false + expect.objectContaining(objectContaining); + + fireEvent.click(pagers[1]); + objectContaining.checked = checkboxAll.checked; // false + objectContaining.indeterminate = getIndeterminateSelection(container).length > 0; // false + expect.objectContaining(objectContaining); + + fireEvent.click(pagers[0]); + objectContaining.checked = checkboxAll.checked; // true + objectContaining.indeterminate = getIndeterminateSelection(container).length > 0; // false + expect.objectContaining(objectContaining); }); // https://github.com/ant-design/ant-design/issues/4020 @@ -180,7 +187,7 @@ describe('Table.rowSelection', () => { }), }; - mount(createTable({ rowSelection })); + render(createTable({ rowSelection })); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Table] Do not set `checked` or `defaultChecked` in `getCheckboxProps`. Please use `selectedRowKeys` instead.', @@ -188,13 +195,13 @@ describe('Table.rowSelection', () => { }); it('can be controlled', () => { - const wrapper = mount(createTable({ rowSelection: { selectedRowKeys: [0] } })); + const { container, rerender } = render(createTable({ rowSelection: { selectedRowKeys: [0] } })); - expect(getSelections(wrapper)).toEqual([0]); + expect(getSelections(container)).toEqual([0]); - wrapper.setProps({ rowSelection: { selectedRowKeys: [1] } }); + rerender(createTable({ rowSelection: { selectedRowKeys: [1] } })); - expect(getSelections(wrapper)).toEqual([1]); + expect(getSelections(container)).toEqual([1]); }); it('fires change & select events', () => { @@ -209,12 +216,9 @@ describe('Table.rowSelection', () => { onChange: handleChange, onSelect: handleSelect, }; - const wrapper = mount(createTable({ rowSelection })); + const { container } = render(createTable({ rowSelection })); - wrapper - .find('input') - .last() - .simulate('change', { target: { checked: true } }); + fireEvent.click(container.querySelectorAll('input[type="checkbox"]')[4]); expect(handleChange).toHaveBeenCalledWith([3], [{ key: 3, name: 'Jerry' }], { type: 'single', @@ -223,7 +227,7 @@ describe('Table.rowSelection', () => { expect(handleSelect.mock.calls[0][0]).toEqual({ key: 3, name: 'Jerry' }); expect(handleSelect.mock.calls[0][1]).toEqual(true); expect(handleSelect.mock.calls[0][2]).toEqual([{ key: 3, name: 'Jerry' }]); - expect(handleSelect.mock.calls[0][3].type).toBe('change'); + expect(handleSelect.mock.calls[0][3].type).toBe('click'); expect(order).toEqual(['onSelect', 'onChange']); }); @@ -243,27 +247,20 @@ describe('Table.rowSelection', () => { onSelect: handleSelect, onSelectMultiple: handleSelectMulti, }; - const wrapper = mount(createTable({ rowSelection })); - - wrapper - .find('input') - .at(1) - .simulate('change', { - target: { checked: true }, - nativeEvent: { shiftKey: true }, - }); + const { container } = render(createTable({ rowSelection })); + fireEvent.click(container.querySelectorAll('tbody input[type="checkbox"]')[0], { + shiftKey: true, + }); + expect(handleSelect).toHaveBeenCalled(); expect(handleChange).toHaveBeenLastCalledWith([0], [{ key: 0, name: 'Jack' }], { type: 'single', }); - wrapper - .find('input') - .at(3) - .simulate('change', { - target: { checked: true }, - nativeEvent: { shiftKey: true }, - }); + fireEvent.click(container.querySelectorAll('tbody input[type="checkbox"]')[2], { + shiftKey: true, + }); + expect(handleSelectMulti).toHaveBeenCalledWith( true, [data[0], data[1], data[2]], @@ -279,13 +276,9 @@ describe('Table.rowSelection', () => { { type: 'multiple' }, ); - wrapper - .find('input') - .at(1) - .simulate('change', { - target: { checked: false }, - nativeEvent: { shiftKey: true }, - }); + fireEvent.click(container.querySelectorAll('tbody input[type="checkbox"]')[0], { + shiftKey: true, + }); expect(handleSelectMulti).toHaveBeenCalledWith(false, [], [data[0], data[1], data[2]]); expect(handleChange).toHaveBeenLastCalledWith([], [], { type: 'multiple' }); @@ -311,46 +304,51 @@ describe('Table.rowSelection', () => { onChange: handleChange, onSelectAll: handleSelectAll, }; - const wrapper = mount(createTable({ rowSelection })); + const { container } = render(createTable({ rowSelection })); + + const checkAll = container.querySelector('input[type="checkbox"]'); - wrapper - .find('input') - .first() - .simulate('change', { target: { checked: true } }); + fireEvent.click(checkAll); expect(handleSelectAll).toHaveBeenCalledWith(true, data, data); expect(order).toEqual(['onSelectAll', 'onChange']); - wrapper - .find('input') - .first() - .simulate('change', { target: { checked: false } }); + fireEvent.click(checkAll); expect(handleSelectAll).toHaveBeenCalledWith(false, [], data); }); it('works with selectAll option inside selection menu', () => { + jest.useFakeTimers(); const handleChange = jest.fn(); const rowSelection = { onChange: handleChange, selections: true, }; - const wrapper = mount(createTable({ rowSelection })); + const { container } = render(createTable({ rowSelection })); // Open - wrapper.find('Trigger').setState({ popupVisible: true }); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + + fireEvent.click(container.querySelectorAll('.ant-dropdown-menu-item')[0]); - const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent()); - dropdownWrapper.find('.ant-dropdown-menu-item').first().simulate('click'); expect(handleChange.mock.calls[0][0]).toEqual([0, 1, 2, 3]); }); it('render with default selection correctly', () => { + jest.useFakeTimers(); const rowSelection = { selections: true, }; - const wrapper = mount(createTable({ rowSelection })); - const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent()); - expect(dropdownWrapper.render()).toMatchSnapshot(); + const { container } = render(createTable({ rowSelection })); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + + expect(container.querySelector('.ant-dropdown')).toMatchSnapshot(); }); it('fires selectInvert event', () => { @@ -368,33 +366,26 @@ describe('Table.rowSelection', () => { onSelectInvert: handleSelectInvert, selections: true, }; - const wrapper = mount(createTable({ rowSelection })); - const checkboxes = wrapper.find('input'); - - checkboxes.at(1).simulate('change', { target: { checked: true } }); + const { container } = render(createTable({ rowSelection })); + fireEvent.click(container.querySelectorAll('.ant-checkbox')[1]); // Open - wrapper.find('span.ant-dropdown-trigger').simulate('mouseEnter'); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); - // enzyme has bug for state sync. - // Let fresh multiple times to force sync back. - for (let i = 0; i < 3; i += 1) { - act(() => { - jest.runAllTimers(); - wrapper.update(); - }); - } + act(() => { + jest.runAllTimers(); + }); - wrapper.find('li.ant-dropdown-menu-item').at(1).simulate('click'); + fireEvent.click(container.querySelectorAll('li.ant-dropdown-menu-item')[1]); expect(handleSelectInvert).toHaveBeenCalledWith([1, 2, 3]); - expect(order).toEqual(['onChange', 'onSelectInvert', 'onChange']); jest.useRealTimers(); }); it('fires selectNone event', () => { + jest.useFakeTimers(); const order = []; const handleChange = jest.fn().mockImplementation(() => { order.push('onChange'); @@ -407,22 +398,23 @@ describe('Table.rowSelection', () => { onSelectNone: handleSelectNone, selections: true, }; - const wrapper = mount(createTable({ rowSelection })); - const checkboxes = wrapper.find('input'); - - checkboxes.at(1).simulate('change', { target: { checked: true } }); + const { container } = render(createTable({ rowSelection })); + fireEvent.click(container.querySelectorAll('.ant-checkbox')[1]); // Open - wrapper.find('Trigger').setState({ popupVisible: true }); - - const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent()); - dropdownWrapper.find('.ant-dropdown-menu-item').last().simulate('click'); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + const dropdownMenuItems = container.querySelectorAll('.ant-dropdown-menu-item'); + fireEvent.click(dropdownMenuItems[dropdownMenuItems.length - 1]); expect(handleSelectNone).toHaveBeenCalled(); expect(order).toEqual(['onChange', 'onSelectNone', 'onChange']); }); it('fires selection event', () => { + jest.useFakeTimers(); const handleSelectOdd = jest.fn(); const handleSelectEven = jest.fn(); const rowSelection = { @@ -441,18 +433,22 @@ describe('Table.rowSelection', () => { }, ], }; - const wrapper = mount(createTable({ rowSelection })); + const { container } = render(createTable({ rowSelection })); // Open - wrapper.find('Trigger').setState({ popupVisible: true }); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + + const dropdownMenuItems = container.querySelectorAll('.ant-dropdown-menu-item'); - const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent()); - expect(dropdownWrapper.find('li.ant-dropdown-menu-item').length).toBe(4); + expect(dropdownMenuItems.length).toBe(4); - dropdownWrapper.find('li.ant-dropdown-menu-item').at(2).simulate('click'); + fireEvent.click(dropdownMenuItems[2]); expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]); - dropdownWrapper.find('li.ant-dropdown-menu-item').at(3).simulate('click'); + fireEvent.click(dropdownMenuItems[3]); expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]); }); @@ -466,8 +462,9 @@ describe('Table.rowSelection', () => { const getCheckboxProps = record => record; it('SELECTION_ALL', () => { + jest.useFakeTimers(); const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( createTable({ dataSource: presetData, rowSelection: { @@ -479,15 +476,20 @@ describe('Table.rowSelection', () => { }), ); - wrapper.find('Trigger').setState({ popupVisible: true }); - wrapper.find('li.ant-dropdown-menu-item').first().simulate('click'); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + + act(() => { + jest.runAllTimers(); + }); + fireEvent.click(container.querySelector('li.ant-dropdown-menu-item')); expect(onChange).toHaveBeenCalledWith([0, 2], expect.anything(), { type: 'all' }); }); it('SELECTION_INVERT', () => { + jest.useFakeTimers(); const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( createTable({ dataSource: presetData, rowSelection: { @@ -499,15 +501,21 @@ describe('Table.rowSelection', () => { }), ); - wrapper.find('Trigger').setState({ popupVisible: true }); - wrapper.find('li.ant-dropdown-menu-item').first().simulate('click'); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + + act(() => { + jest.runAllTimers(); + }); + + fireEvent.click(container.querySelector('li.ant-dropdown-menu-item')); expect(onChange).toHaveBeenCalledWith([0], expect.anything(), { type: 'invert' }); }); it('SELECTION_NONE', () => { + jest.useFakeTimers(); const onChange = jest.fn(); - const wrapper = mount( + const { container } = render( createTable({ dataSource: presetData, rowSelection: { @@ -519,8 +527,13 @@ describe('Table.rowSelection', () => { }), ); - wrapper.find('Trigger').setState({ popupVisible: true }); - wrapper.find('li.ant-dropdown-menu-item').first().simulate('click'); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + + act(() => { + jest.runAllTimers(); + }); + + fireEvent.click(container.querySelector('li.ant-dropdown-menu-item')); expect(onChange).toHaveBeenCalledWith([1], expect.anything(), { type: 'none' }); }); @@ -530,11 +543,12 @@ describe('Table.rowSelection', () => { const rowSelection = { hideSelectAll: true, }; - const wrapper = mount(createTable({ rowSelection })); - expect(wrapper.find('.ant-selection').exists()).toBeFalsy(); + const { container } = render(createTable({ rowSelection })); + expect(container.querySelector('.ant-selection')).toBeFalsy(); }); it('handle custom selection onSelect correctly when hide default selection options', () => { + jest.useFakeTimers(); const handleSelectOdd = jest.fn(); const handleSelectEven = jest.fn(); const rowSelection = { @@ -551,18 +565,21 @@ describe('Table.rowSelection', () => { }, ], }; - const wrapper = mount(createTable({ rowSelection })); + const { container } = render(createTable({ rowSelection })); // Open - wrapper.find('Trigger').setState({ popupVisible: true }); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); - const dropdownWrapper = mount(wrapper.find('Trigger').first().instance().getComponent()); - expect(dropdownWrapper.find('li.ant-dropdown-menu-item').length).toBe(2); + const dropdownMenuItems = container.querySelectorAll('li.ant-dropdown-menu-item'); + expect(dropdownMenuItems.length).toBe(2); - dropdownWrapper.find('li.ant-dropdown-menu-item').at(0).simulate('click'); + fireEvent.click(dropdownMenuItems[0]); expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]); - dropdownWrapper.find('li.ant-dropdown-menu-item').at(1).simulate('click'); + fireEvent.click(dropdownMenuItems[1]); expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]); }); @@ -571,14 +588,15 @@ describe('Table.rowSelection', () => { const rowSelection = { getCheckboxProps: record => ({ disabled: record.disabled }), }; - const wrapper = mount(createTable({ rowSelection })); + const { container, rerender } = render(createTable({ rowSelection })); const newData = [ { key: 0, name: 'Jack', disabled: true }, { key: 1, name: 'Lucy', disabled: true }, ]; - wrapper.setProps({ dataSource: newData }); - wrapper.find('input').forEach(checkbox => { - expect(checkbox.props().disabled).toBe(true); + + rerender(createTable({ rowSelection, dataSource: newData })); + container.querySelectorAll('input').forEach(checkbox => { + expect(checkbox.disabled).toBe(true); }); }); @@ -621,20 +639,16 @@ describe('Table.rowSelection', () => { name: i.toString(), }); } - const wrapper = mount( + const { container } = render( createTable({ rowSelection: {}, dataSource: newData, }), ); - wrapper.find('Pager').last().simulate('click'); // switch to second page - wrapper.update(); - wrapper - .find('input') - .first() - .simulate('change', { target: { checked: true } }); - wrapper.update(); - expect(renderedNames(wrapper)).toEqual([ + fireEvent.click(container.querySelectorAll('.ant-pagination-item')[1]); // switch to second page + fireEvent.click(container.querySelector('.ant-checkbox')); + + expect(renderedNames(container)).toEqual([ '10', '11', '12', @@ -649,27 +663,27 @@ describe('Table.rowSelection', () => { }); it('highlight selected row', () => { - const wrapper = mount(createTable()); - wrapper - .find('input') - .at(1) - .simulate('change', { target: { checked: true } }); - expect(wrapper.find('tbody tr').at(0).hasClass('ant-table-row-selected')).toBe(true); + const { container } = render(createTable()); + + fireEvent.click(container.querySelectorAll('input')[1]); + expect( + container.querySelectorAll('tbody tr')[0].className.includes('ant-table-row-selected'), + ).toBe(true); }); it('fix selection column on the left', () => { - const wrapper = mount( + const { asFragment } = render( createTable({ rowSelection: { fixed: true }, scroll: { x: 903 }, }), ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('fix expand on th left when selection column fixed on the left', () => { - const wrapper = mount( + const { asFragment } = render( createTable({ expandable: { expandedRowRender() { @@ -681,11 +695,11 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('fix selection column on the left when any other column is fixed', () => { - const wrapper = mount( + const { asFragment } = render( createTable({ rowSelection: {}, columns: [ @@ -699,11 +713,11 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); it('use column as selection column when key is `selection-column`', () => { - const wrapper = mount( + const { asFragment } = render( createTable({ rowSelection: {}, columns: [ @@ -716,12 +730,12 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.render()).toMatchSnapshot(); + expect(asFragment().firstChild).toMatchSnapshot(); }); // https://github.com/ant-design/ant-design/issues/10629 it('should keep all checked state when remove item from dataSource', () => { - const wrapper = mount( + const { container, rerender } = render(
{ dataSource={data} />, ); - expect(wrapper.find(Checkbox).length).toBe(5); - wrapper.find(Checkbox).forEach(checkbox => { - expect(checkbox.props().checked).toBe(true); - expect(checkbox.props().indeterminate).toBe(false); - }); - wrapper.setProps({ - dataSource: data.slice(1), - rowSelection: { - selectedRowKeys: [1, 2, 3], - }, + const checkboxs = container.querySelectorAll('.ant-checkbox'); + expect(checkboxs.length).toBe(5); + checkboxs.forEach(checkbox => { + expect(checkbox.querySelector('input').checked).toBe(true); + expect(checkbox.className.includes('ant-checkbox-indeterminate')).toBe(false); }); - expect(wrapper.find(Checkbox).length).toBe(4); - wrapper.find(Checkbox).forEach(checkbox => { - expect(checkbox.props().checked).toBe(true); - expect(checkbox.props().indeterminate).toBe(false); + + rerender( +
, + ); + + expect(container.querySelectorAll('.ant-checkbox').length).toBe(4); + container.querySelectorAll('.ant-checkbox').forEach(checkbox => { + expect(checkbox.querySelector('input').checked).toBe(true); + expect(checkbox.className.includes('ant-checkbox-indeterminate')).toBe(false); }); }); // https://github.com/ant-design/ant-design/issues/11042 it('add columnTitle for rowSelection', () => { - const wrapper = mount( + const { container, rerender } = render(
{ }} />, ); - expect(wrapper.find('thead tr th').at(0).text()).toBe('多选'); - wrapper.setProps({ - rowSelection: { - type: 'radio', - columnTitle: '单选', - }, - }); - expect(wrapper.find('thead tr th').at(0).text()).toBe('单选'); + expect(container.querySelector('thead tr th').textContent).toBe('多选'); + rerender( +
, + ); + expect(container.querySelector('thead tr th').textContent).toBe('单选'); }); // https://github.com/ant-design/ant-design/issues/11384 @@ -795,36 +819,43 @@ describe('Table.rowSelection', () => { onChange, }; - const wrapper = mount( + const { container } = render(
, ); function clickFilter(indexList) { indexList.forEach(index => { - wrapper.find('.ant-dropdown-menu-item .ant-checkbox-wrapper').at(index).simulate('click'); + // wrapper.find('.ant-dropdown-menu-item .ant-checkbox-wrapper').at(index).simulate('click'); + fireEvent.click( + container.querySelectorAll('.ant-dropdown-menu-item .ant-checkbox-wrapper')[index], + ); }); - wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click'); + // wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click'); + fireEvent.click(container.querySelector('.ant-table-filter-dropdown-btns .ant-btn-primary')); } function clickItem() { - wrapper - .find('tbody .ant-table-selection-column .ant-checkbox-input') - .at(0) - .simulate('change', { - target: { checked: true }, - }); + fireEvent.click( + container.querySelectorAll('tbody .ant-table-selection-column .ant-checkbox-input')[0], + ); + // wrapper + // .find('tbody .ant-table-selection-column .ant-checkbox-input') + // .at(0) + // .simulate('change', { + // target: { checked: true }, + // }); } // Check Jack clickFilter([0]); - expect(wrapper.find('tbody tr').length).toBe(1); + expect(container.querySelectorAll('tbody tr').length).toBe(1); clickItem(); expect(onChange.mock.calls[0][0].length).toBe(1); expect(onChange.mock.calls[0][1].length).toBe(1); // Check Lucy clickFilter([0, 1]); - expect(wrapper.find('tbody tr').length).toBe(1); + expect(container.querySelectorAll('tbody tr').length).toBe(1); clickItem(); expect(onChange.mock.calls[1][0].length).toBe(2); expect(onChange.mock.calls[1][1].length).toBe(2); @@ -853,20 +884,20 @@ describe('Table.rowSelection', () => { ], }, ]; - const wrapper = mount( + const { container } = render(
, ); - const checkboxes = wrapper.find('input'); - - checkboxes.at(1).simulate('change', { target: { checked: true } }); - expect(wrapper.find('Checkbox').first().props()).toEqual( - expect.objectContaining({ indeterminate: true, checked: false }), - ); - - checkboxes.at(2).simulate('change', { target: { checked: true } }); - expect(wrapper.find('Checkbox').first().props()).toEqual( - expect.objectContaining({ indeterminate: false, checked: true }), - ); + const checkboxes = container.querySelectorAll('input'); + const objectContaining = {}; + fireEvent.click(checkboxes[1]); + objectContaining.checked = checkboxes[0].checked; // false + objectContaining.indeterminate = getIndeterminateSelection(container).length > 0; // true + expect.objectContaining(objectContaining); + + fireEvent.click(checkboxes[2]); + objectContaining.checked = checkboxes[0].checked; // true + objectContaining.indeterminate = getIndeterminateSelection(container).length > 0; // false + expect.objectContaining(objectContaining); }); // https://github.com/ant-design/ant-design/issues/16614 @@ -884,7 +915,7 @@ describe('Table.rowSelection', () => { ], }, ]; - const wrapper = mount( + const { container } = render(
{ expandedRowKeys={[1]} />, ); - const checkboxes = wrapper.find('input'); - checkboxes.at(2).simulate('change', { target: { checked: true } }); + const checkboxes = container.querySelectorAll('input'); + + fireEvent.click(checkboxes[2]); + expect(onChange).toHaveBeenLastCalledWith([11], [newDatas[0].list[0]], { type: 'single' }); onChange.mockReset(); - checkboxes.at(1).simulate('change', { target: { checked: true } }); + fireEvent.click(checkboxes[1]); const item0 = newDatas[0]; expect(onChange).toHaveBeenLastCalledWith([11, 1], [newDatas[0].list[0], item0], { type: 'single', @@ -911,7 +944,7 @@ describe('Table.rowSelection', () => { { id: 2, name: 'World', age: 30 }, ]; - const wrapper = mount( + const { container, rerender } = render(
{ rowKey="id" />, ); - const checkboxes = wrapper.find('input'); - checkboxes.at(1).simulate('change', { target: { checked: true } }); + const checkboxes = container.querySelectorAll('input'); + fireEvent.click(checkboxes[1]); - expect(wrapper.find('tr.ant-table-row-selected').length).toBe(1); + expect(container.querySelectorAll('tr.ant-table-row-selected').length).toBe(1); + + rerender( +
null} + rowKey="id" + />, + ); - wrapper.setProps({ rowSelection: null }); - wrapper.update(); - expect(wrapper.find('tr.ant-table-row-selected').length).toBe(0); + expect(container.querySelectorAll('tr.ant-table-row-selected').length).toBe(0); }); it('select by checkbox to trigger stopPropagation', () => { - const wrapper = mount(createTable()); + const { container } = render(createTable()); expect(() => { - wrapper.find('span').at(10).simulate('click'); + fireEvent.click(container.querySelectorAll('span')[10]); }).not.toThrow(); }); it('all disabled should not make select all checked', () => { - const wrapper = mount( + const { container } = render( createTable({ rowSelection: { getCheckboxProps: () => ({ @@ -948,12 +989,12 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeTruthy(); - expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy(); + expect(container.querySelector('thead .ant-checkbox-input').disabled).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').checked).toBeFalsy(); }); it('should make select all checked when each item is checked and disabled', () => { - const wrapper = mount( + const { container } = render( createTable({ rowSelection: { selectedRowKeys: [0, 1, 2, 3], @@ -964,12 +1005,12 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeTruthy(); - expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').disabled).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').checked).toBeTruthy(); }); it('should make select all indeterminated when each item is disabled and some item is checked', () => { - const wrapper = mount( + const { container } = render( createTable({ rowSelection: { selectedRowKeys: [0], @@ -980,15 +1021,15 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeTruthy(); - expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy(); + expect(container.querySelector('thead .ant-checkbox-input').disabled).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').checked).toBeFalsy(); expect( - wrapper.find('thead .ant-checkbox-indeterminate.ant-checkbox-disabled').exists(), + container.querySelector('thead .ant-checkbox-indeterminate.ant-checkbox-disabled'), ).toBeTruthy(); }); it('should make select all checked when each item is checked and some item is disabled', () => { - const wrapper = mount( + const { container } = render( createTable({ rowSelection: { selectedRowKeys: [0, 1, 2, 3], @@ -999,12 +1040,12 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeFalsy(); - expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').disabled).toBeFalsy(); + expect(container.querySelector('thead .ant-checkbox-input').checked).toBeTruthy(); }); it('should not make select all checked when some item is checked and disabled', () => { - const wrapper = mount( + const { container } = render( createTable({ rowSelection: { selectedRowKeys: [1], @@ -1015,23 +1056,23 @@ describe('Table.rowSelection', () => { }), ); - expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeFalsy(); - expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy(); - expect(wrapper.find('thead .ant-checkbox-indeterminate').exists()).toBeTruthy(); + expect(container.querySelector('thead .ant-checkbox-input').disabled).toBeFalsy(); + expect(container.querySelector('thead .ant-checkbox-input').checked).toBeFalsy(); + expect(container.querySelector('thead .ant-checkbox-indeterminate')).toBeTruthy(); }); it('should onRowClick not called when checkbox clicked', () => { const onRowClick = jest.fn(); - const wrapper = mount( + const { container } = render( createTable({ onRow: () => ({ onClick: onRowClick, }), }), ); - - wrapper.find('input').last().simulate('click'); + const checkboxes = container.querySelectorAll('input'); + fireEvent.click(checkboxes[checkboxes.length - 1]); expect(onRowClick).not.toHaveBeenCalled(); }); @@ -1041,16 +1082,18 @@ describe('Table.rowSelection', () => { selections: true, }; const getPopupContainer = jest.fn(node => node); - const wrapper = mount( + const { container } = render( createTable({ rowSelection, getPopupContainer, }), ); jest.useFakeTimers(); - wrapper.find('.ant-dropdown-trigger').simulate('mouseenter'); - jest.runAllTimers(); - expect(wrapper.render()).toMatchSnapshot(); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + expect(container.firstChild).toMatchSnapshot(); expect(getPopupContainer).toHaveBeenCalled(); }); @@ -1058,7 +1101,7 @@ describe('Table.rowSelection', () => { const rowSelection = { selections: true, }; - const wrapper = mount( + const { container } = render( node.parentNode}> {createTable({ rowSelection, @@ -1066,14 +1109,16 @@ describe('Table.rowSelection', () => { , ); jest.useFakeTimers(); - wrapper.find('.ant-dropdown-trigger').simulate('mouseenter'); - jest.runAllTimers(); - expect(wrapper.render()).toMatchSnapshot(); + fireEvent.mouseEnter(container.querySelector('.ant-dropdown-trigger')); + act(() => { + jest.runAllTimers(); + }); + expect(container.firstChild).toMatchSnapshot(); }); it('Table selection should check', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container } = render(
{ />, ); - wrapper - .find('input') - .last() - .simulate('change', { target: { checked: true } }); + const checkboxs = container.querySelectorAll('input'); + fireEvent.click(checkboxs[checkboxs.length - 1]); + expect(onChange.mock.calls[0][1]).toEqual([expect.objectContaining({ name: 'bamboo' })]); }); @@ -1139,16 +1183,19 @@ describe('Table.rowSelection', () => { onChange, }, }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); + + fireEvent.click(checkboxes[4]); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + expect(getSelections(container)).toEqual([3, 4, 5, 6, 7, 8, 9]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[0][0]).toEqual([3, 4, 5, 6, 7, 8, 9]); - checkboxes.at(7).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([4, 5]); - expect(getIndeterminateSelection(wrapper)).toEqual([3]); + + fireEvent.click(checkboxes[7]); + + expect(getSelections(container)).toEqual([4, 5]); + expect(getIndeterminateSelection(container)).toEqual([3]); expect(onChange.mock.calls[1][0]).toEqual([4, 5]); }); it('use function rowkey', () => { @@ -1162,12 +1209,20 @@ describe('Table.rowSelection', () => { }, rowKey: entity => entity.name, }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual([ + 'Jerry', + 'Jerry Jack', + 'Jerry Lucy', + 'Jerry Tom', + 'Jerry Tom Jack', + 'Jerry Tom Lucy', + 'Jerry Tom Tom', + ]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[0][0]).toEqual([ 'Jerry', 'Jerry Jack', @@ -1177,9 +1232,10 @@ describe('Table.rowSelection', () => { 'Jerry Tom Lucy', 'Jerry Tom Tom', ]); - checkboxes.at(7).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([4, 5]); - expect(getIndeterminateSelection(wrapper)).toEqual([3]); + + fireEvent.click(checkboxes[7]); + expect(getSelections(container)).toEqual(['Jerry Jack', 'Jerry Lucy']); + expect(getIndeterminateSelection(container)).toEqual(['Jerry']); expect(onChange.mock.calls[1][0]).toEqual(['Jerry Jack', 'Jerry Lucy']); }); it('use string rowkey', () => { @@ -1193,12 +1249,20 @@ describe('Table.rowSelection', () => { }, rowKey: 'name', }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual([ + 'Jerry', + 'Jerry Jack', + 'Jerry Lucy', + 'Jerry Tom', + 'Jerry Tom Jack', + 'Jerry Tom Lucy', + 'Jerry Tom Tom', + ]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[0][0]).toEqual([ 'Jerry', 'Jerry Jack', @@ -1208,9 +1272,10 @@ describe('Table.rowSelection', () => { 'Jerry Tom Lucy', 'Jerry Tom Tom', ]); - checkboxes.at(7).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([4, 5]); - expect(getIndeterminateSelection(wrapper)).toEqual([3]); + + fireEvent.click(checkboxes[7]); + expect(getSelections(container)).toEqual(['Jerry Jack', 'Jerry Lucy']); + expect(getIndeterminateSelection(container)).toEqual(['Jerry']); expect(onChange.mock.calls[1][0]).toEqual(['Jerry Jack', 'Jerry Lucy']); }); it('initialized correctly', () => { @@ -1223,9 +1288,9 @@ describe('Table.rowSelection', () => { }, rowKey: 'key', }); - const wrapper = mount(table); - expect(getSelections(wrapper)).toEqual([6, 7, 8, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([3]); + const { container } = render(table); + expect(getSelections(container)).toEqual([6, 7, 8, 9]); + expect(getIndeterminateSelection(container)).toEqual([3]); }); it('works with disabled checkbox', () => { const onChange = jest.fn(); @@ -1243,17 +1308,20 @@ describe('Table.rowSelection', () => { }, }, }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + + const checkboxes = container.querySelectorAll('input'); - checkboxes.at(10).simulate('change', { target: { checked: true } }); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + fireEvent.click(checkboxes[10]); + fireEvent.click(checkboxes[4]); + + expect(getSelections(container).sort()).toEqual([3, 4, 5, 9]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([3, 4, 5, 9]); - checkboxes.at(4).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual([9]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[2][0]).toEqual([9]); }); it('works with disabled checkbox and function rowkey', () => { @@ -1273,22 +1341,28 @@ describe('Table.rowSelection', () => { }, rowKey: entity => entity.name, }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); - checkboxes.at(10).simulate('change', { target: { checked: true } }); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + fireEvent.click(checkboxes[10]); + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual([ + 'Jerry', + 'Jerry Jack', + 'Jerry Lucy', + 'Jerry Tom Tom', + ]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([ 'Jerry', 'Jerry Jack', 'Jerry Lucy', 'Jerry Tom Tom', ]); - checkboxes.at(4).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual(['Jerry Tom Tom']); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[2][0]).toEqual(['Jerry Tom Tom']); }); it('works with disabled checkbox and string rowkey', () => { @@ -1308,22 +1382,28 @@ describe('Table.rowSelection', () => { }, rowKey: 'name', }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); - checkboxes.at(10).simulate('change', { target: { checked: true } }); - checkboxes.at(4).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + fireEvent.click(checkboxes[10]); + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual([ + 'Jerry', + 'Jerry Jack', + 'Jerry Lucy', + 'Jerry Tom Tom', + ]); + expect(getIndeterminateSelection(container)).toEqual([]); expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([ 'Jerry', 'Jerry Jack', 'Jerry Lucy', 'Jerry Tom Tom', ]); - checkboxes.at(4).simulate('change', { target: { checked: false } }); - expect(getSelections(wrapper)).toEqual([9]); - expect(getIndeterminateSelection(wrapper)).toEqual([]); + + fireEvent.click(checkboxes[4]); + expect(getSelections(container)).toEqual(['Jerry Tom Tom']); + expect(getIndeterminateSelection(container)).toEqual([]); expect(onChange.mock.calls[2][0]).toEqual(['Jerry Tom Tom']); }); @@ -1350,17 +1430,17 @@ describe('Table.rowSelection', () => { onChange, }, }); - const wrapper = mount(table); - const checkboxes = wrapper.find('input'); + const { container } = render(table); + const checkboxes = container.querySelectorAll('input'); expect(checkboxes).toHaveLength(1 + 3); - checkboxes.at(1).simulate('change', { target: { checked: true } }); - expect(getSelections(wrapper)).toEqual([0, 1, 2]); + fireEvent.click(checkboxes[1]); + expect(getSelections(container)).toEqual([0, 1, 2]); }); }); it('warns when set `indeterminate` using `rowSelection.getCheckboxProps` is not allowed with tree structured data.', () => { resetWarned(); - mount( + render( createTable({ dataSource: dataWithChildren, defaultExpandAllRows: true, @@ -1383,7 +1463,7 @@ describe('Table.rowSelection', () => { describe('cache with selected keys', () => { it('default not cache', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container, rerender } = render(
{ />, ); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith(['light'], [{ name: 'light' }], { type: 'single' }); - - wrapper.setProps({ dataSource: [{ name: 'bamboo' }] }); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + rerender( +
, + ); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith(['bamboo'], [{ name: 'bamboo' }], { type: 'single' }); }); it('cache with preserveSelectedRowKeys', () => { const onChange = jest.fn(); - const wrapper = mount( + const { container, rerender } = render(
{ />, ); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith(['light'], [{ name: 'light' }], { type: 'single' }); - wrapper.setProps({ dataSource: [{ name: 'bamboo' }] }); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + rerender( +
, + ); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith( ['light', 'bamboo'], [{ name: 'light' }, { name: 'bamboo' }], @@ -1436,7 +1511,7 @@ describe('Table.rowSelection', () => { it('works with receive selectedRowKeys fron [] to undefined', () => { const onChange = jest.fn(); const dataSource = [{ name: 'Jack' }]; - const wrapper = mount( + const { container, rerender } = render(
{ />, ); - wrapper.setProps({ rowSelection: { onChange, selectedRowKeys: undefined } }); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + rerender( +
, + ); + + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith(['Jack'], [{ name: 'Jack' }], { type: 'single' }); }); it('works with selectionType radio receive selectedRowKeys from [] to undefined', () => { const onChange = jest.fn(); const dataSource = [{ name: 'Jack' }]; - const wrapper = mount( + const { container, rerender } = render(
, ); + rerender( +
, + ); - wrapper.setProps({ rowSelection: { onChange, selectedRowKeys: undefined, type: 'radio' } }); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith(['Jack'], [{ name: 'Jack' }], { type: 'single' }); }); @@ -1479,7 +1561,7 @@ describe('Table.rowSelection', () => { onChange, selectedRowKeys: ['Jack'], }; - const wrapper = mount( + const { container, rerender } = render(
{ />, ); - wrapper.setProps({ - dataSource: dataSource.slice(2, 4), - }); - wrapper - .find('tbody input') - .first() - .simulate('change', { target: { checked: true } }); + rerender( +
, + ); + fireEvent.click(container.querySelector('tbody input')); expect(onChange).toHaveBeenCalledWith( ['Jack', 'Lucy'], [{ name: 'Jack' }, { name: 'Lucy' }], diff --git a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap index 2fb7edc9d62a..e773204a0049 100644 --- a/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap +++ b/components/table/__tests__/__snapshots__/Table.rowSelection.test.js.snap @@ -976,7 +976,60 @@ exports[`Table.rowSelection fix selection column on the left when any other colu `; -exports[`Table.rowSelection render with default selection correctly 1`] = `
`; +exports[`Table.rowSelection render with default selection correctly 1`] = ` +
+ + +`; exports[`Table.rowSelection should support getPopupContainer 1`] = `
tr > th, tfoot > tr > td { position: relative; - padding: @table-padding-vertical-sm @table-padding-horizontal; + padding: @table-padding-vertical @table-padding-horizontal; overflow-wrap: break-word; } @@ -90,7 +89,6 @@ position: relative; color: @table-header-color; font-weight: 500; - font-size: 12px; text-align: left; background: @table-header-bg; border-bottom: @border-width-base @border-style-base @table-border-color; @@ -256,12 +254,14 @@ &-column-title { position: relative; z-index: 1; + flex: 1; } &-column-sorters { display: flex; flex: auto; align-items: center; + justify-content: space-between; &::after { position: absolute; @@ -276,12 +276,11 @@ } &-column-sorter { - display: flex; - align-items: center; margin-left: 4px; color: @table-header-icon-color; - font-size: 14px; + font-size: 0; transition: color 0.3s; + &-inner { display: inline-flex; flex-direction: column; @@ -290,7 +289,7 @@ &-up, &-down { - font-size: 14px; + font-size: 11px; &.active { color: @primary-color; @@ -309,6 +308,7 @@ // ============================ Filter ============================ &-filter-column { display: flex; + justify-content: space-between; } &-filter-trigger { @@ -318,7 +318,7 @@ margin: -4px (-@table-padding-horizontal / 2) -4px 4px; padding: 0 4px; color: @table-header-icon-color; - font-size: @font-size-base; + font-size: @font-size-sm; border-radius: @border-radius-base; cursor: pointer; transition: all 0.3s; diff --git a/components/tabs/__tests__/index.test.js b/components/tabs/__tests__/index.test.js index 93033b2beb42..1e35bf00183b 100644 --- a/components/tabs/__tests__/index.test.js +++ b/components/tabs/__tests__/index.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import Tabs from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; diff --git a/components/time-picker/__tests__/index.test.js b/components/time-picker/__tests__/index.test.js index c22ae3b3e3ee..d6ac11a0c804 100644 --- a/components/time-picker/__tests__/index.test.js +++ b/components/time-picker/__tests__/index.test.js @@ -1,5 +1,6 @@ import { mount } from 'enzyme'; import moment from 'moment'; +import React from 'react'; import TimePicker from '..'; import focusTest from '../../../tests/shared/focusTest'; import mountTest from '../../../tests/shared/mountTest'; diff --git a/components/tree/__tests__/index.test.js b/components/tree/__tests__/index.test.js index 4a18e667aa3e..c5006f9ba4a9 100644 --- a/components/tree/__tests__/index.test.js +++ b/components/tree/__tests__/index.test.js @@ -1,3 +1,4 @@ +import React from 'react'; import { render } from '../../../tests/utils'; import Tree from '../index'; diff --git a/components/tree/__tests__/type.test.tsx b/components/tree/__tests__/type.test.tsx index 4e3142c6f49e..ae5ff32b4f89 100644 --- a/components/tree/__tests__/type.test.tsx +++ b/components/tree/__tests__/type.test.tsx @@ -1,4 +1,5 @@ import type { BasicDataNode } from 'rc-tree'; +import React from 'react'; import { render } from '../../../tests/utils'; import Tree from '../index'; diff --git a/components/typography/__tests__/copy.test.tsx b/components/typography/__tests__/copy.test.tsx index c9290ab90f86..1f4cd8ca33cf 100644 --- a/components/typography/__tests__/copy.test.tsx +++ b/components/typography/__tests__/copy.test.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import { mount } from 'enzyme'; -import { SmileOutlined, LikeOutlined } from 'infra-design-icons'; import * as copyObj from 'copy-to-clipboard'; +import { LikeOutlined, SmileOutlined } from 'infra-design-icons'; +import React from 'react'; +import { fireEvent, render, waitFor } from '../../../tests/utils'; import Base from '../Base'; @@ -33,57 +33,69 @@ describe('Typography copy', () => { }) { it(name, async () => { jest.useFakeTimers(); - const wrapper = mount( + const { container: wrapper, unmount } = render( test copy , ); if (iconClassNames[0] !== undefined) { - expect(wrapper.exists(iconClassNames[0])).toBeTruthy(); + expect(wrapper.querySelector(iconClassNames[0])).not.toBeNull(); } if (iconTexts[0] !== undefined) { - expect(wrapper.find('.ant-typography-copy').at(0).text()).toBe(iconTexts[0]); + expect(wrapper.querySelectorAll('.ant-typography-copy')[0].textContent).toBe( + iconTexts[0], + ); } - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.runAllTimers(); - wrapper.update(); if (tooltipTexts[0] !== undefined) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltipTexts[0]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner')?.textContent).toBe( + tooltipTexts[0], + ); + }); } if (tooltipLength !== undefined) { - expect(wrapper.find('.ant-tooltip-inner').length).toBe(tooltipLength); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(tooltipLength); + }); } - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.useRealTimers(); if (iconClassNames[1] !== undefined) { - expect(wrapper.exists(iconClassNames[1])).toBeTruthy(); + expect(wrapper.querySelector(iconClassNames[1])).not.toBeNull(); } - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); - wrapper.update(); + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); if (tooltipTexts[1] !== undefined) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltipTexts[1]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner')?.textContent).toBe( + tooltipTexts[1], + ); + }); } if (iconTexts[1] !== undefined) { - expect(wrapper.find('.ant-typography-copy').at(0).text()).toBe(iconTexts[1]); + expect(wrapper.querySelectorAll('.ant-typography-copy')[0].textContent).toBe( + iconTexts[1], + ); } jest.useFakeTimers(); - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.runAllTimers(); - wrapper.update(); - wrapper.unmount(); + unmount(); jest.useRealTimers(); }); } + const dom = ( <> 12 @@ -197,14 +209,14 @@ describe('Typography copy', () => { it('copy click event stopPropagation', () => { const onDivClick = jest.fn(); - const wrapper = mount( + const { container: wrapper } = render(
test copy
, ); - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); expect(onDivClick).not.toBeCalled(); }); @@ -212,12 +224,13 @@ describe('Typography copy', () => { function onCopy(e: React.MouseEvent) { expect(e).not.toBeUndefined(); } - const wrapper = mount( + + const { container: wrapper } = render( test copy , ); - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); }); it('copy to clipboard', done => { @@ -237,13 +250,13 @@ describe('Typography copy', () => { ); }; - const wrapper = mount(); - const copyBtn = wrapper.find('.ant-typography-copy').first(); - copyBtn.simulate('click'); + const { container: wrapper } = render(); + const copyBtn = wrapper.querySelectorAll('.ant-typography-copy')[0]; + fireEvent.click(copyBtn); expect(spy.mock.calls[0][0]).toEqual(originText); setTimeout(() => { spy.mockReset(); - copyBtn.simulate('click'); + fireEvent.click(copyBtn); expect(spy.mock.calls[0][0]).toEqual(nextText); done(); }, 500); diff --git a/components/typography/__tests__/ellipsis.test.js b/components/typography/__tests__/ellipsis.test.js index 34173480db85..0439f2d46634 100644 --- a/components/typography/__tests__/ellipsis.test.js +++ b/components/typography/__tests__/ellipsis.test.js @@ -1,11 +1,8 @@ -import React from 'react'; -import { mount } from 'enzyme'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; +import React from 'react'; +import { fireEvent, render, sleep, triggerResize, waitFor } from '../../../tests/utils'; import Base from '../Base'; -import Typography from '../Typography'; -import { sleep } from '../../../tests/utils'; // eslint-disable-next-line no-unused-vars -import * as styleChecker from '../../_util/styleChecker'; jest.mock('copy-to-clipboard'); @@ -53,47 +50,59 @@ describe('Typography.Ellipsis', () => { 'Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light'; it('should trigger update', async () => { + const ref = React.createRef(); const onEllipsis = jest.fn(); - const wrapper = mount( - + const { + container: wrapper, + rerender, + unmount, + } = render( + {fullStr} , ); - // First resize - wrapper.triggerResize(); + triggerResize(ref.current); await sleep(20); - wrapper.update(); - expect(wrapper.text()).toEqual('Bamboo is Little ...'); + + expect(wrapper.firstChild.textContent).toEqual('Bamboo is Little ...'); expect(onEllipsis).toHaveBeenCalledWith(true); onEllipsis.mockReset(); // Second resize - wrapper.setProps({ ellipsis: { rows: 2, onEllipsis } }); - await sleep(20); - wrapper.update(); - expect(wrapper.text()).toEqual('Bamboo is Little Light Bamboo is Litt...'); + rerender( + + {fullStr} + , + ); + expect(wrapper.textContent).toEqual('Bamboo is Little Light Bamboo is Litt...'); expect(onEllipsis).not.toHaveBeenCalled(); // Third resize - wrapper.setProps({ ellipsis: { rows: 99, onEllipsis } }); - await sleep(20); - wrapper.update(); - expect(wrapper.find('p').text()).toEqual(fullStr); + rerender( + + {fullStr} + , + ); + expect(wrapper.querySelector('p').textContent).toEqual(fullStr); expect(onEllipsis).toHaveBeenCalledWith(false); - wrapper.unmount(); + unmount(); }); it('support css multiple lines', async () => { - const wrapper = mount( + const { container: wrapper } = render( {fullStr} , ); - expect(wrapper.exists('.ant-typography-ellipsis-multiple-line')).toBeTruthy(); - expect(wrapper.find(Typography).prop('style').WebkitLineClamp).toEqual(2); + expect( + wrapper.querySelectorAll('.ant-typography-ellipsis-multiple-line').length, + ).toBeGreaterThan(0); + expect( + wrapper.querySelector('.ant-typography-ellipsis-multiple-line').style.WebkitLineClamp, + ).toEqual('2'); }); it('string with parentheses', async () => { @@ -105,71 +114,87 @@ describe('Typography.Ellipsis', () => { design language for background applications, is refined by Ant UED Team. Ant Design, a design language for background applications, is refined by Ant UED Team.`; + const ref = React.createRef(); const onEllipsis = jest.fn(); - const wrapper = mount( - + const { container: wrapper, unmount } = render( + {parenthesesStr} , ); - wrapper.triggerResize(); + triggerResize(ref.current); await sleep(20); - wrapper.update(); - expect(wrapper.text()).toEqual('Ant Design, a des...'); - const ellipsisSpan = wrapper.find('span[aria-hidden]').last(); - expect(ellipsisSpan.text()).toEqual('...'); + + expect(wrapper.firstChild.textContent).toEqual('Ant Design, a des...'); + const ellipsisSpans = wrapper.querySelectorAll('span[aria-hidden]'); + expect(ellipsisSpans[ellipsisSpans.length - 1].textContent).toEqual('...'); onEllipsis.mockReset(); - wrapper.unmount(); + unmount(); }); it('should middle ellipsis', async () => { const suffix = '--suffix'; - const wrapper = mount( - + const ref = React.createRef(); + const { container: wrapper, unmount } = render( + {fullStr} , ); - wrapper.triggerResize(); + triggerResize(ref.current); await sleep(20); - wrapper.update(); - expect(wrapper.find('p').text()).toEqual('Bamboo is...--suffix'); - wrapper.unmount(); + + expect(wrapper.querySelector('p').textContent).toEqual('Bamboo is...--suffix'); + unmount(); }); it('should front or middle ellipsis', async () => { const suffix = '--The information is very important'; - const wrapper = mount( - + const ref = React.createRef(); + const { + container: wrapper, + rerender, + unmount, + } = render( + {fullStr} , ); - wrapper.triggerResize(); + triggerResize(ref.current); await sleep(20); - wrapper.update(); - expect(wrapper.find('p').text()).toEqual('...--The information is very important'); - wrapper.setProps({ ellipsis: { rows: 2, suffix } }); - await sleep(20); - wrapper.update(); - expect(wrapper.find('p').text()).toEqual('Ba...--The information is very important'); + expect(wrapper.querySelector('p').textContent).toEqual( + '...--The information is very important', + ); - wrapper.setProps({ ellipsis: { rows: 99, suffix } }); - await sleep(20); - wrapper.update(); - expect(wrapper.find('p').text()).toEqual(fullStr + suffix); + rerender( + + {fullStr} + , + ); + expect(wrapper.querySelector('p').textContent).toEqual( + 'Ba...--The information is very important', + ); - wrapper.unmount(); + rerender( + + {fullStr} + , + ); + expect(wrapper.querySelector('p').textContent).toEqual(fullStr + suffix); + + unmount(); }); it('connect children', async () => { const bamboo = 'Bamboo'; const is = ' is '; - const wrapper = mount( - + const ref = React.createRef(); + const { container: wrapper } = render( + {bamboo} {is} Little @@ -177,54 +202,49 @@ describe('Typography.Ellipsis', () => { , ); - wrapper.triggerResize(); + triggerResize(ref.current); await sleep(20); - wrapper.update(); - expect(wrapper.text()).toEqual('Bamboo is Little...'); + expect(wrapper.textContent).toEqual('Bamboo is Little...'); }); it('should expandable work', async () => { const onExpand = jest.fn(); - const wrapper = mount( + const { container: wrapper } = render( {fullStr} , ); - await sleep(20); - wrapper.update(); - - wrapper.find('.ant-typography-expand').simulate('click'); + fireEvent.click(wrapper.querySelector('.ant-typography-expand')); expect(onExpand).toHaveBeenCalled(); - await sleep(20); - wrapper.update(); - - expect(wrapper.find('p').text()).toEqual(fullStr); + expect(wrapper.querySelector('p').textContent).toEqual(fullStr); }); it('should have custom expand style', async () => { const symbol = 'more'; - const wrapper = mount( + const { container: wrapper } = render( {fullStr} , ); - await sleep(20); - wrapper.update(); - expect(wrapper.find('.ant-typography-expand').text()).toEqual('more'); + expect(wrapper.querySelector('.ant-typography-expand').textContent).toEqual('more'); }); it('can use css ellipsis', () => { - const wrapper = mount(); - expect(wrapper.find('.ant-typography-ellipsis-single-line').length).toBeTruthy(); + const { container: wrapper } = render(); + expect(wrapper.querySelectorAll('.ant-typography-ellipsis-single-line').length).toBeGreaterThan( + 0, + ); }); it('should calculate padding', () => { - const wrapper = mount( + const { container: wrapper } = render( , ); - expect(wrapper.find('.ant-typography-ellipsis-single-line').length).toBeTruthy(); + expect(wrapper.querySelectorAll('.ant-typography-ellipsis-single-line').length).toBeGreaterThan( + 0, + ); }); describe('should tooltip support', () => { @@ -245,40 +265,52 @@ describe('Typography.Ellipsis', () => { domSpy.mockRestore(); }); - function getWrapper(tooltip) { - return mount( - + async function getWrapper(tooltip) { + const ref = React.createRef(); + const wrapper = render( + {fullStr} , ); + triggerResize(ref.current); + await sleep(20); + return wrapper; } it('boolean', async () => { - const wrapper = getWrapper(true); - await sleep(20); - wrapper.update(); - - expect(wrapper.find('Tooltip').prop('title')).toEqual(fullStr); + const { container, baseElement } = await getWrapper(true); + fireEvent.mouseEnter(container.firstChild); + await waitFor(() => { + expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull(); + }); }); it('customize', async () => { - const wrapper = getWrapper('Bamboo is Light'); - await sleep(20); - wrapper.update(); - - expect(wrapper.find('Tooltip').prop('title')).toEqual('Bamboo is Light'); + const { container, baseElement } = await getWrapper('Bamboo is Light'); + fireEvent.mouseEnter(container.firstChild); + await waitFor(() => { + expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull(); + }); }); }); it('js ellipsis should show aria-label', () => { - const titleWrapper = mount(); - expect(titleWrapper.find('.ant-typography').prop('aria-label')).toEqual('bamboo'); + const { container: titleWrapper } = render( + , + ); + expect(titleWrapper.querySelector('.ant-typography').getAttribute('aria-label')).toEqual( + 'bamboo', + ); - const tooltipWrapper = mount(); - expect(tooltipWrapper.find('.ant-typography').prop('aria-label')).toEqual('little'); + const { container: tooltipWrapper } = render( + , + ); + expect(tooltipWrapper.querySelector('.ant-typography').getAttribute('aria-label')).toEqual( + 'little', + ); }); - it('should display tooltip if line clamp', () => { + it('should display tooltip if line clamp', async () => { mockRectSpy = spyElementPrototypes(HTMLElement, { scrollHeight: { get() { @@ -299,12 +331,19 @@ describe('Typography.Ellipsis', () => { }, }); - const wrapper = mount( - + const ref = React.createRef(); + const { container: wrapper, baseElement } = render( + Ant Design, a design language for background applications, is refined by Ant UED Team. , ); - expect(wrapper.find('EllipsisTooltip').prop('isEllipsis')).toBeTruthy(); + triggerResize(ref.current); + await sleep(20); + + fireEvent.mouseEnter(wrapper.firstChild); + await waitFor(() => { + expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull(); + }); mockRectSpy.mockRestore(); }); }); diff --git a/components/typography/__tests__/enter-key-callback.test.tsx b/components/typography/__tests__/enter-key-callback.test.tsx index 21d8d8643244..eeb5a2a8cbcc 100644 --- a/components/typography/__tests__/enter-key-callback.test.tsx +++ b/components/typography/__tests__/enter-key-callback.test.tsx @@ -1,13 +1,13 @@ -import React from 'react'; -import { mount } from 'enzyme'; import KeyCode from 'rc-util/lib/KeyCode'; +import React from 'react'; +import { fireEvent, render } from '../../../tests/utils'; import Paragraph from '../Paragraph'; test('Callback on enter key is triggered', () => { const onEditStart = jest.fn(); const onCopy = jest.fn(); - const wrapper = mount( + const { container: wrapper } = render( { jest.spyOn(window, 'setTimeout').mockReturnValue(timer); jest.spyOn(window, 'clearTimeout'); // must copy first, because editing button will hide copy button - wrapper.find('.ant-typography-copy').at(0).simulate('keyup', { keyCode: KeyCode.ENTER }); - wrapper.find('.anticon-edit').at(0).simulate('keyup', { keyCode: KeyCode.ENTER }); + fireEvent.keyUp(wrapper.querySelectorAll('.ant-typography-copy')[0], { keyCode: KeyCode.ENTER }); + fireEvent.keyUp(wrapper.querySelectorAll('.anticon-edit')[0], { keyCode: KeyCode.ENTER }); expect(onEditStart.mock.calls.length).toBe(1); expect(onCopy.mock.calls.length).toBe(1); diff --git a/components/typography/__tests__/index.test.js b/components/typography/__tests__/index.test.js index 95bebab88db3..b63a33ee432b 100644 --- a/components/typography/__tests__/index.test.js +++ b/components/typography/__tests__/index.test.js @@ -1,13 +1,11 @@ +import { CheckOutlined, HighlightOutlined, LikeOutlined, SmileOutlined } from '@ant-design/icons'; import copy from 'copy-to-clipboard'; -import { mount } from 'enzyme'; -import { CheckOutlined, HighlightOutlined, LikeOutlined, SmileOutlined } from 'infra-design-icons'; import KeyCode from 'rc-util/lib/KeyCode'; -import { spyElementPrototype } from 'rc-util/lib/test/domHook'; import { resetWarned } from 'rc-util/lib/warning'; import React from 'react'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import { render, sleep } from '../../../tests/utils'; +import { fireEvent, render, sleep, waitFor } from '../../../tests/utils'; import Base from '../Base'; import Link from '../Link'; import Paragraph from '../Paragraph'; @@ -79,7 +77,7 @@ describe('Typography', () => { describe('Title', () => { it('warning if `level` not correct', () => { - mount(); + render(<Title level={false} />); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Typography.Title] Title only accept `1 | 2 | 3 | 4 | 5` as `level` value. And `5` need 4.6.0+ version.', @@ -93,47 +91,57 @@ describe('Typography', () => { it(name, async () => { jest.useFakeTimers(); const onCopy = jest.fn(); - const wrapper = mount( + const { container: wrapper, unmount } = render( <Base component="p" copyable={{ text, onCopy, icon, tooltips, format }}> test copy </Base>, ); if (icon) { - expect(wrapper.find('.anticon-smile').length).toBeTruthy(); + expect(wrapper.querySelectorAll('.anticon-smile').length).toBeGreaterThan(0); } else { - expect(wrapper.find('.anticon-copy').length).toBeTruthy(); + expect(wrapper.querySelectorAll('.anticon-copy').length).toBeGreaterThan(0); } - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); + fireEvent.mouseEnter(wrapper.querySelector('.ant-typography-copy')); jest.runAllTimers(); - wrapper.update(); if (tooltips === undefined || tooltips === true) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe('Copy'); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe('Copy'); + }); } else if (tooltips === false) { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else if (tooltips[0] === '' && tooltips[1] === '') { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else if (tooltips[0] === '' && tooltips[1]) { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else if (tooltips[1] === '' && tooltips[0]) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltips[0]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(tooltips[0]); + }); } else { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltips[0]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(tooltips[0]); + }); } - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelector('.ant-typography-copy')); jest.useRealTimers(); - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); - // tooltips 为 ['', 'xxx'] 时,切换时需要延时 mousenEnterDelay 的时长 + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); + // tooltips 为 ['', 'xxx'] 时,切换时需要延时 mouseEnterDelay 的时长 if (tooltips && tooltips[0] === '' && tooltips[1]) { await sleep(150); } expect(copy.lastStr).toEqual(target); expect(copy.lastOptions.format).toEqual(format); - wrapper.update(); expect(onCopy).toHaveBeenCalled(); let copiedIcon = '.anticon-check'; @@ -143,31 +151,43 @@ describe('Typography', () => { copiedIcon = '.anticon-check'; } - expect(wrapper.find(copiedIcon).length).toBeTruthy(); - wrapper.find('.ant-typography-copy').first().simulate('mouseenter'); + expect(wrapper.querySelectorAll(copiedIcon).length).toBeGreaterThan(0); + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); if (tooltips === undefined || tooltips === true) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe('Copied'); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe('Copied'); + }); } else if (tooltips === false) { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else if (tooltips[0] === '' && tooltips[1] === '') { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else if (tooltips[0] === '' && tooltips[1]) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltips[1]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(tooltips[1]); + }); } else if (tooltips[1] === '' && tooltips[0]) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(''); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(''); + }); } else { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltips[1]); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(tooltips[1]); + }); } jest.useFakeTimers(); - wrapper.find('.ant-typography-copy').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.runAllTimers(); - wrapper.update(); // Will set back when 3 seconds pass - expect(wrapper.find(copiedIcon).length).toBeFalsy(); - wrapper.unmount(); + await sleep(3000); + expect(wrapper.querySelectorAll(copiedIcon).length).toBe(0); + unmount(); jest.useRealTimers(); }); } @@ -221,15 +241,15 @@ describe('Typography', () => { submitFunc, expectFunc, ) { - it(name, () => { + it(name, async () => { jest.useFakeTimers(); const onStart = jest.fn(); const onChange = jest.fn(); const className = 'test'; - const style = {}; + const style = { padding: 'unset' }; - const wrapper = mount( + const { container: wrapper } = render( <Paragraph editable={{ onChange, onStart, icon, tooltip, triggerType, enterIcon }} className={className} @@ -241,64 +261,71 @@ describe('Typography', () => { if (triggerType === undefined || triggerType.indexOf('icon') !== -1) { if (icon) { - expect(wrapper.find('.anticon-highlight').length).toBeTruthy(); + expect(wrapper.querySelectorAll('.anticon-highlight').length).toBeGreaterThan(0); } else { - expect(wrapper.find('.anticon-edit').length).toBeTruthy(); + expect(wrapper.querySelectorAll('.anticon-edit').length).toBeGreaterThan(0); } if (triggerType === undefined || triggerType.indexOf('text') === -1) { - wrapper.simulate('click'); + fireEvent.click(wrapper.firstChild); expect(onStart).not.toHaveBeenCalled(); } - wrapper.find('.ant-typography-edit').first().simulate('mouseenter'); + fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-edit')[0]); jest.runAllTimers(); - wrapper.update(); if (tooltip === undefined || tooltip === true) { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe('Edit'); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe('Edit'); + }); } else if (tooltip === false) { - expect(wrapper.find('.ant-tooltip-inner').length).toBeFalsy(); + await waitFor(() => { + expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(0); + }); } else { - expect(wrapper.find('.ant-tooltip-inner').text()).toBe(tooltip); + await waitFor(() => { + expect(wrapper.querySelector('.ant-tooltip-inner').textContent).toBe(tooltip); + }); } - wrapper.find('.ant-typography-edit').first().simulate('click'); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-edit')[0]); expect(onStart).toHaveBeenCalled(); if (triggerType !== undefined && triggerType.indexOf('text') !== -1) { - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ESC }); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ESC }); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); expect(onChange).not.toHaveBeenCalled(); } } if (triggerType !== undefined && triggerType.indexOf('text') !== -1) { if (triggerType.indexOf('icon') === -1) { - expect(wrapper.find('.anticon-highlight').length).toBeFalsy(); - expect(wrapper.find('.anticon-edit').length).toBeFalsy(); + expect(wrapper.querySelectorAll('.anticon-highlight').length).toBe(0); + expect(wrapper.querySelectorAll('.anticon-edit').length).toBe(0); } - wrapper.simulate('click'); + fireEvent.click(wrapper.firstChild); expect(onStart).toHaveBeenCalled(); } // Should have className - const props = wrapper.find('div').first().props(); - expect(props.style).toEqual(style); + const props = wrapper.querySelectorAll('div')[0]; + expect(props.getAttribute('style')).toContain('padding: unset'); expect(props.className.includes(className)).toBeTruthy(); - wrapper.find('textarea').simulate('change', { + fireEvent.change(wrapper.querySelector('textarea'), { target: { value: 'Bamboo' }, }); if (enterIcon === undefined) { expect( - wrapper.find('span.ant-typography-edit-content-confirm').first().props().className, + wrapper.querySelectorAll('span.ant-typography-edit-content-confirm')[0].className, ).toContain('anticon-enter'); } else if (enterIcon === null) { - expect(wrapper.find('span.ant-typography-edit-content-confirm').length).toBe(0); + expect( + wrapper.querySelectorAll('span.ant-typography-edit-content-confirm').length, + ).toBe(0); } else { expect( - wrapper.find('span.ant-typography-edit-content-confirm').first().props().className, + wrapper.querySelectorAll('span.ant-typography-edit-content-confirm')[0].className, ).not.toContain('anticon-enter'); } @@ -319,21 +346,21 @@ describe('Typography', () => { testStep({ name: 'by key up' }, wrapper => { // Not trigger when inComposition - wrapper.find('textarea').simulate('compositionStart'); - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ENTER }); - wrapper.find('textarea').simulate('compositionEnd'); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ENTER }); + fireEvent.compositionStart(wrapper.querySelector('textarea')); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); + fireEvent.compositionEnd(wrapper.querySelector('textarea')); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); // Now trigger - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ENTER }); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ENTER }); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); }); testStep( { name: 'by esc key' }, wrapper => { - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ESC }); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ESC }); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); }, onChange => { // eslint-disable-next-line jest/no-standalone-expect @@ -342,7 +369,7 @@ describe('Typography', () => { ); testStep({ name: 'by blur' }, wrapper => { - wrapper.find('textarea').simulate('blur'); + fireEvent.blur(wrapper.querySelector('textarea')); }); testStep({ name: 'customize edit icon', icon: <HighlightOutlined /> }); @@ -359,47 +386,51 @@ describe('Typography', () => { it('should trigger onEnd when type Enter', () => { const onEnd = jest.fn(); - const wrapper = mount(<Paragraph editable={{ onEnd }}>Bamboo</Paragraph>); - wrapper.find('.ant-typography-edit').first().simulate('click'); - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ENTER }); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ENTER }); + const { container: wrapper } = render(<Paragraph editable={{ onEnd }}>Bamboo</Paragraph>); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-edit')[0]); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ENTER }); expect(onEnd).toHaveBeenCalledTimes(1); }); it('should trigger onCancel when type ESC', () => { const onCancel = jest.fn(); - const wrapper = mount(<Paragraph editable={{ onCancel }}>Bamboo</Paragraph>); - wrapper.find('.ant-typography-edit').first().simulate('click'); - wrapper.find('textarea').simulate('keyDown', { keyCode: KeyCode.ESC }); - wrapper.find('textarea').simulate('keyUp', { keyCode: KeyCode.ESC }); + const { container: wrapper } = render( + <Paragraph editable={{ onCancel }}>Bamboo</Paragraph>, + ); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-edit')[0]); + fireEvent.keyDown(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); + fireEvent.keyUp(wrapper.querySelector('textarea'), { keyCode: KeyCode.ESC }); expect(onCancel).toHaveBeenCalledTimes(1); }); it('should only trigger focus on the first time', () => { let triggerTimes = 0; - const mockFocus = spyElementPrototype(HTMLElement, 'focus', () => { + const { container: wrapper } = render(<Paragraph editable>Bamboo</Paragraph>); + const editIcon = wrapper.querySelectorAll('.ant-typography-edit')[0]; + + editIcon.addEventListener('focus', () => { triggerTimes += 1; }); - const wrapper = mount(<Paragraph editable>Bamboo</Paragraph>); + fireEvent.focus(editIcon); + expect(triggerTimes).toEqual(1); - wrapper.find('.ant-typography-edit').first().simulate('click'); + fireEvent.click(editIcon); expect(triggerTimes).toEqual(1); - wrapper.find('textarea').simulate('change', { + fireEvent.change(wrapper.querySelector('textarea'), { target: { value: 'good' }, }); expect(triggerTimes).toEqual(1); - - mockFocus.mockRestore(); }); }); it('should focus at the end of textarea', () => { - const wrapper = mount(<Paragraph editable>content</Paragraph>); - wrapper.find('.ant-typography-edit').first().simulate('click'); - const textareaNode = wrapper.find('textarea').getDOMNode(); + const { container: wrapper } = render(<Paragraph editable>content</Paragraph>); + fireEvent.click(wrapper.querySelectorAll('.ant-typography-edit')[0]); + const textareaNode = wrapper.querySelector('textarea'); expect(textareaNode.selectionStart).toBe(7); expect(textareaNode.selectionEnd).toBe(7); }); @@ -407,7 +438,7 @@ describe('Typography', () => { it('warning if use setContentRef', () => { const refFunc = () => {}; - mount(<Typography setContentRef={refFunc} />); + render(<Typography setContentRef={refFunc} />); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Typography] `setContentRef` is deprecated. Please use `ref` instead.', ); @@ -423,21 +454,21 @@ describe('Typography', () => { it('should get HTMLHeadingElement ref from Title', () => { const ref = React.createRef(); - mount(<Title level={1} ref={ref} />); + render(<Title level={1} ref={ref} />); expect(ref.current instanceof HTMLHeadingElement).toBe(true); }); it('should get HTMLDivElement ref from Paragraph', () => { const ref = React.createRef(); - mount(<Paragraph ref={ref} />); + render(<Paragraph ref={ref} />); expect(ref.current instanceof HTMLDivElement).toBe(true); }); it('should get HTMLSpanElement ref from Text', () => { const ref = React.createRef(); - mount(<Text ref={ref} />); + render(<Text ref={ref} />); expect(ref.current instanceof HTMLSpanElement).toBe(true); }); }); diff --git a/package.json b/package.json index 0defbe620145..e1f6eb1f8715 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "dependencies": { "@ant-design/colors": "^6.0.0", "@ant-design/icons": "^4.7.0", - "@ant-design/react-slick": "~0.28.1", + "@ant-design/react-slick": "~0.29.1", "@babel/runtime": "^7.12.5", "@ctrl/tinycolor": "^3.4.0", "axios": "^0.26.0", @@ -127,11 +127,11 @@ "rc-cascader": "~3.6.0", "rc-checkbox": "~2.3.0", "rc-collapse": "~3.3.0", - "rc-dialog": "~8.8.2", + "rc-dialog": "~8.9.0", "rc-drawer": "~4.4.2", "rc-dropdown": "~4.0.0", "rc-field-form": "~1.26.1", - "rc-image": "~5.6.0", + "rc-image": "~5.7.0", "rc-input": "~0.0.1-alpha.5", "rc-input-number": "~7.3.0", "rc-mentions": "~1.8.0", @@ -160,11 +160,10 @@ "scroll-into-view-if-needed": "^2.2.25" }, "devDependencies": { - "@ant-design/bisheng-plugin": "^3.2.0", + "@ant-design/bisheng-plugin": "^3.3.0-alpha.4", "@ant-design/hitu": "^0.0.0-alpha.13", - "@ant-design/jest-image-snapshot": "^4.5.2", "@docsearch/css": "^3.0.0", - "@infra-fe/tools": "^15.0.2", + "@infra-fe/tools": "^15.0.3", "@qixian.cs/github-contributors-list": "^1.0.3", "@stackblitz/sdk": "^1.3.0", "@testing-library/jest-dom": "^5.16.3", @@ -193,7 +192,7 @@ "antd-img-crop": "^4.0.0", "array-move": "^4.0.0", "babel-plugin-add-react-displayname": "^0.0.5", - "bisheng": "^3.5.0", + "bisheng": "^3.7.0-alpha.4", "bisheng-plugin-description": "^0.1.4", "bisheng-plugin-react": "^1.2.0", "bisheng-plugin-toc": "^0.4.4", @@ -277,7 +276,6 @@ "react-router-dom": "^6.0.2", "react-sortable-hoc": "^2.0.0", "react-sticky": "^6.0.3", - "react-text-loop-next": "0.0.3", "react-window": "^1.8.5", "remark": "^14.0.1", "remark-cli": "^10.0.0", @@ -288,10 +286,10 @@ "scrollama": "^3.0.0", "semver": "^7.3.5", "simple-git": "^3.0.0", - "stylelint": "14.8.3", + "stylelint": "^14.9.0", "stylelint-config-prettier": "^9.0.2", "stylelint-config-rational-order": "^0.1.2", - "stylelint-config-standard": "^25.0.0", + "stylelint-config-standard": "^26.0.0", "stylelint-declaration-block-no-ignored-properties": "^2.1.0", "stylelint-order": "^5.0.0", "theme-switcher": "^1.0.2", diff --git a/tsconfig.json b/tsconfig.json index 2a20159f4ba6..ba665f32f07d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,9 @@ "moduleResolution": "node", "esModuleInterop": true, "experimentalDecorators": true, - "jsx": "preserve", + "jsx": "react", + "jsxFactory": "React.createElement", + "jsxFragmentFactory": "React.Fragment", "noUnusedParameters": true, "noUnusedLocals": true, "noImplicitAny": true,