From d66737f83c4e517b533cfc3e37e1ea174b719dba Mon Sep 17 00:00:00 2001 From: xrkffgg Date: Tue, 10 Oct 2023 15:19:09 +0800 Subject: [PATCH 01/16] docs: add changelog 5.10.0 (#45244) * docs: add changelog 5.10.0 * fix: lint * fix: lint * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 Signed-off-by: xrkffgg * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 Signed-off-by: xrkffgg * Update CHANGELOG.zh-CN.md Co-authored-by: afc163 Signed-off-by: xrkffgg * Update CHANGELOG.zh-CN.md Co-authored-by: lijianan <574980606@qq.com> Signed-off-by: xrkffgg * fix: doc --------- Signed-off-by: xrkffgg Co-authored-by: afc163 Co-authored-by: lijianan <574980606@qq.com> --- CHANGELOG.en-US.md | 33 +++++++++++++++++++++++++++++++++ CHANGELOG.zh-CN.md | 33 +++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 38c025931df7..a351bbdba82f 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -16,6 +16,39 @@ tag: vVERSION --- +## 5.10.0 + +`2023-10-10` + +- 🔥 New component Flex, used to set flexible layout. [#44362](https://github.com/ant-design/ant-design/pull/44362) +- 🔥 Notification component supports `stack` configuration. By default, more than three notifications will be stacked. [#44618](https://github.com/ant-design/ant-design/pull/44618) +- 🔥 Update the active styles of Input, InputNumber, Select, Cascader, TreeSelect, DatePicker, and ColorPicker. [#45009](https://github.com/ant-design/ant-design/pull/45009) +- 🆕 Watermark supports setting the text alignment direction through `textAlign`. [#44888](https://github.com/ant-design/ant-design/pull/44888) [@Yuiai01](https://github.com/Yuiai01) +- 🆕 Slider supports any number of nodes and migrates xxxStyles to semantic `styles` and `classNames` properties. [#45000](https://github.com/ant-design/ant-design/pull/45000) +- 🆕 Cascader supports the Cascader.Panel component for inline use. [#45089](https://github.com/ant-design/ant-design/pull/45089) +- 🆕 Tooltip adds `fresh` attribute to support scenarios where content still needs to be updated when closed. [#45020](https://github.com/ant-design/ant-design/pull/45020) +- 🆕 Drawer supports customizing the `className` of built-in modules through `classNames`. [#44935](https://github.com/ant-design/ant-design/pull/44935) +- 🆕 ConfigProvider supports the `warning` attribute to configure warning levels (e.g. filter out deprecated API warnings). [#44809](https://github.com/ant-design/ant-design/pull/44809) +- Modal + - 🆕 Modal supports customizing the `className` of built-in modules through `classNames`. [#44934](https://github.com/ant-design/ant-design/pull/44934) + - 🐞 Fixed the content overflow problem when Modal.confirm `description` is a long text. [#45212](https://github.com/ant-design/ant-design/pull/45212) +- 🐞 Fix the problem that the nested Typography of Menu.Item cannot be vertically centered when `ellipsis` is true. [#41146](https://github.com/ant-design/ant-design/pull/41146) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 Fix Select internal input not being able to apply fontFamily. [#45197](https://github.com/ant-design/ant-design/pull/45197) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 Fix InputNumber border issue when using `addonBefore` in Space.Compact. [#45004](https://github.com/ant-design/ant-design/pull/45004) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 Fix the problem that Tag.CheckableTag does not support ref. [#45164](https://github.com/ant-design/ant-design/pull/45164) [@mingming-ma](https://github.com/mingming-ma) +- 🐞 Fixed the issue where the font in the Avatar.Group component does not support responsiveness. [#34722](https://github.com/ant-design/ant-design/pull/34722) [@laishiwen](https://github.com/laishiwen) +- 🛠 Refactor Affix into a functional component. [#42674](https://github.com/ant-design/ant-design/pull/42674) +- 🛠 The Popover component deprecates the `minWidth` component token and adds `titleMinWidth` as a replacement. [#44750](https://github.com/ant-design/ant-design/pull/44750) +- 🌈 Token + - 🆕 Input adds `hoverBg` `activeBg` token to set the input box hover and activation background color. [#44752](https://github.com/ant-design/ant-design/pull/44752) [@Pan-yongyong](https://github.com/Pan-yongyong) + - 🆕 Descriptions Added `titleColor` and `contentColor` to set the title color and content area text color. [#44729](https://github.com/ant-design/ant-design/pull/44729) [@Child-qjj](https://github.com/Child-qjj) + - 🐞 Fixed the issue where the Input component Token `addonBg` is invalid. [#45222](https://github.com/ant-design/ant-design/pull/45222) +- TypeScript + - 🤖 The ArgsProps type for exported Notification is NotificationArgsProps. [#45147](https://github.com/ant-design/ant-design/pull/45147) +- 🌐 Locales + - 🇵🇱 Added Tour locales for pl_PL. [#45166](https://github.com/ant-design/ant-design/pull/45166) [@antonisierakowski](https://github.com/antonisierakowski) + - 🇰🇷 Optimize ko_KR locales. [#45150](https://github.com/ant-design/ant-design/pull/45150) [@owjs3901](https://github.com/owjs3901) + ## 5.9.4 `2023-09-28` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index d6a8391d6d50..a7459075ae58 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -16,6 +16,39 @@ tag: vVERSION --- +## 5.10.0 + +`2023-10-10` + +- 🔥 新增 Flex 组件,用于设置弹性布局。[#44362](https://github.com/ant-design/ant-design/pull/44362) +- 🔥 Notification 组件支持 `stack` 配置,默认超过三个以上的提示会堆叠起来。[#44618](https://github.com/ant-design/ant-design/pull/44618) +- 🔥 更新 Input、InputNumber、Select、Cascader、TreeSelect、DatePicker、ColorPicker 的激活态样式。[#45009](https://github.com/ant-design/ant-design/pull/45009) +- 🆕 Watermark 支持通过 `textAlign` 设置文本对齐方向。[#44888](https://github.com/ant-design/ant-design/pull/44888) [@Yuiai01](https://github.com/Yuiai01) +- 🆕 Slider 支持任意节点数并且将 xxxStyle 迁移至语义化 `styles` 和 `classNames` 属性中。[#45000](https://github.com/ant-design/ant-design/pull/45000) +- 🆕 Cascader 支持 Cascader.Panel 组件供内联使用。[#45089](https://github.com/ant-design/ant-design/pull/45089) +- 🆕 Tooltip 添加 `fresh` 属性以支持在关闭时仍然需要更新内容的场景。[#45020](https://github.com/ant-design/ant-design/pull/45020) +- 🆕 Drawer 支持通过 `classNames` 自定义内置模块的 `className`。[#44935](https://github.com/ant-design/ant-design/pull/44935) +- 🆕 ConfigProvider 支持 `warning` 属性以配置警告等级(如过滤掉废弃 API 警告)。[#44809](https://github.com/ant-design/ant-design/pull/44809) +- Modal + - 🆕 Modal 支持通过 `classNames` 自定义内置模块的 `className`。[#44934](https://github.com/ant-design/ant-design/pull/44934) + - 🐞 修复 Modal.confirm `description` 是长文本时的内容溢出问题。[#45212](https://github.com/ant-design/ant-design/pull/45212) +- 🐞 修复 Menu.Item 嵌套的 Typography 其 `ellipsis` 为 true 时无法垂直居中的问题。[#41146](https://github.com/ant-design/ant-design/pull/41146) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 修复 Select 内部 input 无法应用 fontFamily 的问题。[#45197](https://github.com/ant-design/ant-design/pull/45197) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 修复 InputNumber 在 Space.Compact 中使用 `addonBefore` 时的边框问题。[#45004](https://github.com/ant-design/ant-design/pull/45004) [@Yuiai01](https://github.com/Yuiai01) +- 🐞 修复 Tag.CheckableTag 不支持 ref 的问题。[#45164](https://github.com/ant-design/ant-design/pull/45164) [@mingming-ma](https://github.com/mingming-ma) +- 🐞 修复 Avatar.Group 组件内的字体不支持响应式的问题。[#34722](https://github.com/ant-design/ant-design/pull/34722) [@laishiwen](https://github.com/laishiwen) +- 🛠 重构 Affix 为函数组件。[#42674](https://github.com/ant-design/ant-design/pull/42674) +- 🛠 Popover 组件废弃 `minWidth` 组件 token,并添加 `titleMinWidth` 作为替代。[#44750](https://github.com/ant-design/ant-design/pull/44750) +- 🌈 Token + - 🆕 Input 新增 `hoverBg` `activeBg` token 用以设置输入框 hover 和 激活时背景颜色。[#44752](https://github.com/ant-design/ant-design/pull/44752) [@Pan-yongyong](https://github.com/Pan-yongyong) + - 🆕 Descriptions 新增 `titleColor` `contentColor` 用以设置标题颜色和内容区域文字颜色。[#44729](https://github.com/ant-design/ant-design/pull/44729) [@Child-qjj](https://github.com/Child-qjj) + - 🐞 修复 Input 组件 Token `addonBg` 失效的问题。[#45222](https://github.com/ant-design/ant-design/pull/45222) +- TypeScript + - 🤖 导出 Notification 的 ArgsProps 类型为 NotificationArgsProps。[#45147](https://github.com/ant-design/ant-design/pull/45147) +- 🌐 国际化 + - 🇵🇱 为 pl_PL 补充 Tour 国际化。[#45166](https://github.com/ant-design/ant-design/pull/45166) [@antonisierakowski](https://github.com/antonisierakowski) + - 🇰🇷 优化 ko_KR 国际化。[#45150](https://github.com/ant-design/ant-design/pull/45150) [@owjs3901](https://github.com/owjs3901) + ## 5.9.4 `2023-09-28` diff --git a/package.json b/package.json index 43ca5d664de8..f1f751d6a337 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.9.4", + "version": "5.10.0", "packageManager": "^npm@9.0.0", "description": "An enterprise-class UI design language and React components implementation", "title": "Ant Design", From 72fc3b6f3c01031214268d146f2507faee58f3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=A2?= Date: Tue, 10 Oct 2023 17:30:46 +0800 Subject: [PATCH 02/16] chore(site): anchor jump don't work (#45243) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: fix typo error * chore: fix anchor jump failure * Revert "chore: fix anchor jump failure" This reverts commit 9a1127353d80e7e6e1aa17dde1f88e71b61f0181. * chore: fix * Revert "chore: fix" This reverts commit 9dc69f11647738d01fa95b5c92031a197dbef952. * Revert "site: remove legacy code for hash jump (#44836)" This reverts commit 72da2678aac10d3388c7d7139425233122a099e9. * chore: remove * Update .dumi/theme/layouts/DocLayout/index.tsx Co-authored-by: afc163 Signed-off-by: 红 * chore: update --------- Signed-off-by: 红 Co-authored-by: afc163 --- .dumi/theme/builtins/Previewer/CodePreviewer.tsx | 9 +++++---- .dumi/theme/layouts/DocLayout/index.tsx | 12 ++++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.dumi/theme/builtins/Previewer/CodePreviewer.tsx b/.dumi/theme/builtins/Previewer/CodePreviewer.tsx index 51c960a1f70b..6ddc80f67dc3 100644 --- a/.dumi/theme/builtins/Previewer/CodePreviewer.tsx +++ b/.dumi/theme/builtins/Previewer/CodePreviewer.tsx @@ -8,7 +8,7 @@ import classNames from 'classnames'; import { FormattedMessage, useSiteData } from 'dumi'; import LZString from 'lz-string'; -import type { AntdPreviewerProps } from '.'; +import type { AntdPreviewerProps } from './Previewer'; import useLocation from '../../../hooks/useLocation'; import BrowserFrame from '../../common/BrowserFrame'; import ClientOnly from '../../common/ClientOnly'; @@ -171,7 +171,6 @@ const CodePreviewer: React.FC = (props) => { }); const localizedTitle = title; - const introChildren =
; const highlightClass = classNames('highlight-wrapper', { 'highlight-wrapper-expand': codeExpand, }); @@ -205,7 +204,7 @@ const CodePreviewer: React.FC = (props) => { const suffix = codeType === 'tsx' ? 'tsx' : 'js'; - const dependencies: Record = jsx.split('\n').reduce( + const dependencies = (jsx as string).split('\n').reduce>( (acc, line) => { const matches = line.match(/import .+? from '(.+)';$/); if (matches?.[1]) { @@ -377,7 +376,9 @@ createRoot(document.getElementById('container')).render(); } filename={filename} />
-
{introChildren}
+ {description && ( +
+ )} {showOnlineUrl && ( }> diff --git a/.dumi/theme/layouts/DocLayout/index.tsx b/.dumi/theme/layouts/DocLayout/index.tsx index 50728d6e1bf8..8ddbf828c777 100644 --- a/.dumi/theme/layouts/DocLayout/index.tsx +++ b/.dumi/theme/layouts/DocLayout/index.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; import dayjs from 'dayjs'; import 'dayjs/locale/zh-cn'; -import { Helmet, useOutlet } from 'dumi'; +import { Helmet, useOutlet, useSiteData } from 'dumi'; import React, { useContext, useEffect, useLayoutEffect, useMemo, useRef } from 'react'; import zhCN from 'antd/es/locale/zh_CN'; import ConfigProvider from 'antd/es/config-provider'; @@ -30,10 +30,11 @@ const locales = { const DocLayout: React.FC = () => { const outlet = useOutlet(); const location = useLocation(); - const { pathname, search } = location; + const { pathname, search, hash } = location; const [locale, lang] = useLocale(locales); const timerRef = useRef | null>(null); const { direction } = useContext(SiteContext); + const { loading } = useSiteData(); useLayoutEffect(() => { if (lang === 'cn') { @@ -52,6 +53,13 @@ const DocLayout: React.FC = () => { } }, []); + // handle hash change or visit page hash from Link component, and jump after async chunk loaded + useEffect(() => { + const id = hash.replace('#', ''); + + if (id) document.getElementById(decodeURIComponent(id))?.scrollIntoView(); + }, [loading, hash]); + useEffect(() => { if (typeof (window as any).ga !== 'undefined') { (window as any).ga('send', 'pageview', pathname + search); From cb256e580867e2ca399b150144c145fc755a8669 Mon Sep 17 00:00:00 2001 From: killa Date: Tue, 10 Oct 2023 18:12:58 +0800 Subject: [PATCH 03/16] docs: add nodejs recruit info (#45247) --- docs/resources.zh-CN.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/resources.zh-CN.md b/docs/resources.zh-CN.md index 7df0f3c9231c..d9a30fab084c 100644 --- a/docs/resources.zh-CN.md +++ b/docs/resources.zh-CN.md @@ -163,6 +163,23 @@ toc: false - 负责 Ant Design 前端基础设施研发。 - 负责中后台设计/前端工具体系建设。 +### Node.js 工程师 + +简历请投递:zhubin.gzb@antgroup.com + +> 注明简历来自 ant.design 官网 + +- 岗位级别:P5/P6/P7/P8 +- 岗位地点:杭州/上海 +- 岗位要求: + - 在 Node.js 技术栈持续耕耘,情有独钟。 + - 热爱开源。 + - 坚持和善于用技术和工具解决其他问题。 + - 丰富的 Node.js 研发经验。 +- 岗位职责: + - 负责 Node.js 前端基础设施研发。 + - 负责大前端工具体系建设。 + ### ADI(Artificial Design Intelligence) 工程师 简历和作品集请投递:jiayin.liu#antgroup.com From 940a1a5f41ae03a2a46dc8065fccd6554a9f0ad0 Mon Sep 17 00:00:00 2001 From: afc163 Date: Tue, 10 Oct 2023 19:08:46 +0800 Subject: [PATCH 04/16] docs: Update compatible-style.zh-CN.md (#45248) * Update compatible-style.zh-CN.md Signed-off-by: afc163 * Update compatible-style.en-US.md Signed-off-by: afc163 * Update compatible-style.en-US.md Signed-off-by: afc163 * Update docs/react/compatible-style.zh-CN.md Signed-off-by: afc163 --------- Signed-off-by: afc163 --- docs/react/compatible-style.en-US.md | 2 +- docs/react/compatible-style.zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/react/compatible-style.en-US.md b/docs/react/compatible-style.en-US.md index 34593e1e8b5a..35188cbf56f8 100644 --- a/docs/react/compatible-style.en-US.md +++ b/docs/react/compatible-style.en-US.md @@ -13,7 +13,7 @@ Please ref [`@ant-design/cssinjs`](https://github.com/ant-design/cssinjs#stylepr ## Compatible adjustment -Ant Design default using CSS-in-JS with `:where` Selector to reduce priority to avoid user additional adjust style cost when updating. If you want to support old browser (or some other CSS framework selector priority conflict like TailwindCSS), you can use `@ant-design/cssinjs` to adjust this behavior (Please note keep version align with antd): +The CSS-in-JS feature of Ant Design uses the ":where" selector by default to lower the CSS selector specificity, reducing the additional cost of adjusting custom styles when upgrading for users. However, the compatibility of the ":where" syntax is relatively poor in older browsers ([compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)). In certain scenarios, if you need to support older browsers (or encounter priority conflicts like TailwindCSS), you can use `@ant-design/cssinjs` to disable the default lowering of specificity (please ensure version consistency with antd). ```tsx import { StyleProvider } from '@ant-design/cssinjs'; diff --git a/docs/react/compatible-style.zh-CN.md b/docs/react/compatible-style.zh-CN.md index c00d422ec935..3059ca107ed9 100644 --- a/docs/react/compatible-style.zh-CN.md +++ b/docs/react/compatible-style.zh-CN.md @@ -13,7 +13,7 @@ Ant Design 支持最近 2 个版本的现代浏览器。如果你需要兼容旧 ## `:where` 选择器 -Ant Design 的 CSS-in-JS 默认通过 `:where` 选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式成本。在某些场景下你如果需要支持的旧版浏览器(或者如 TailwindCSS 优先级冲突),你可以使用 `@ant-design/cssinjs` 取消默认的降权操作(请注意版本保持与 antd 一致): +Ant Design 的 CSS-in-JS 默认通过 `:where` 选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式成本,不过 `:where` 语法的[兼容性](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)在低版本浏览器比较差。在某些场景下你如果需要支持的旧版浏览器(或者如 TailwindCSS 优先级冲突),你可以使用 `@ant-design/cssinjs` 取消默认的降权操作(请注意版本保持与 antd 一致): ```tsx import { StyleProvider } from '@ant-design/cssinjs'; From f5d1c1140626fa18f189797c3d700569311b6bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=A2?= Date: Wed, 11 Oct 2023 10:23:57 +0800 Subject: [PATCH 05/16] ci: migrate site E2E workflow (#45235) * ci: migrate site E2E workflow * chore: update * chore: update --- .github/workflows/preview-build.yml | 29 ++++++++++++++++++ .github/workflows/site-test.yml | 47 ----------------------------- 2 files changed, 29 insertions(+), 47 deletions(-) delete mode 100644 .github/workflows/site-test.yml diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml index 1a1a4c8589cd..03660a33f417 100644 --- a/.github/workflows/preview-build.yml +++ b/.github/workflows/preview-build.yml @@ -94,3 +94,32 @@ jobs: with: name: pr path: ./pr-id.txt + + site-test: + name: site E2E test + runs-on: ubuntu-latest + needs: [setup, build-site] + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: restore cache from package-lock.json + uses: actions/cache@v3 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v3 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: download site artifact + uses: actions/download-artifact@v3 + with: + name: site + path: _site + + - name: run e2e test + run: npm run site:test diff --git a/.github/workflows/site-test.yml b/.github/workflows/site-test.yml deleted file mode 100644 index 2d6c34d1180a..000000000000 --- a/.github/workflows/site-test.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Site E2E Test - -on: - workflow_run: - workflows: ["Preview Build"] - types: - - completed - -permissions: - contents: read - -jobs: - e2e-test: - permissions: - actions: read # for dawidd6/action-download-artifact to query and download artifacts - name: E2E Test - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: restore cache from package-lock.json - uses: actions/cache@v3 - with: - path: package-temp-dir - key: lock-${{ github.sha }} - - - name: restore cache from node_modules - uses: actions/cache@v3 - with: - path: node_modules - key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} - - # Download site artifact - - name: download site artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} - name: site - path: _site - - - name: Run E2E Test - run: npm run site:test From 083fd55be3b07ed84377a61fbadb2553d081bef0 Mon Sep 17 00:00:00 2001 From: afc163 Date: Wed, 11 Oct 2023 10:24:27 +0800 Subject: [PATCH 06/16] chore: remove --force-exit in jest options (#45002) * test: try some jest options * Apply suggestions from code review Signed-off-by: afc163 --------- Signed-off-by: afc163 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f1f751d6a337..9119e3a9761b 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "test-all": "sh -e ./scripts/test-all.sh", "test-node": "npm run version && jest --config .jest.node.js --no-cache", "tsc": "tsc --noEmit", - "site:test": "jest --config .jest.site.js --no-cache --force-exit", + "site:test": "jest --config .jest.site.js", "test-image": "jest --config .jest.image.js --no-cache -i -u", "argos": "tsx scripts/argos-upload.ts", "version": "tsx scripts/generate-version.ts", From dd4ef28239046de626e3fd9f59fb91cb8e54ecfa Mon Sep 17 00:00:00 2001 From: JiaQi <112228030+Yuiai01@users.noreply.github.com> Date: Wed, 11 Oct 2023 10:31:36 +0800 Subject: [PATCH 07/16] docs: add description of the available components of Space.Compact (#45259) --- components/space/index.en-US.md | 1 + components/space/index.zh-CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/components/space/index.en-US.md b/components/space/index.en-US.md index 9ef95699646d..41b451d90d76 100644 --- a/components/space/index.en-US.md +++ b/components/space/index.en-US.md @@ -55,6 +55,7 @@ Use Space.Compact when child form components are compactly connected and the bor - Cascader - DatePicker - Input/Input.Search +- InputNumber - Select - TimePicker - TreeSelect diff --git a/components/space/index.zh-CN.md b/components/space/index.zh-CN.md index d5539e27aa62..41dd446df1e6 100644 --- a/components/space/index.zh-CN.md +++ b/components/space/index.zh-CN.md @@ -63,6 +63,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*37T2R6O9oi0AAA - Cascader - DatePicker - Input/Input.Search +- InputNumber - Select - TimePicker - TreeSelect From 92c9c038588e38c3bc1a598798191c22b5f7c902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E6=B3=A5?= <1656081615@qq.com> Date: Wed, 11 Oct 2023 11:01:40 +0800 Subject: [PATCH 08/16] docs: remove repeat code (#45260) --- docs/react/migrate-less-variables.en-US.md | 4 ---- docs/react/migrate-less-variables.zh-CN.md | 4 ---- 2 files changed, 8 deletions(-) diff --git a/docs/react/migrate-less-variables.en-US.md b/docs/react/migrate-less-variables.en-US.md index 5b45a783971d..251c1e1a50ef 100644 --- a/docs/react/migrate-less-variables.en-US.md +++ b/docs/react/migrate-less-variables.en-US.md @@ -17,10 +17,6 @@ We could configure global token and component token for each component through t import React from 'react'; import { Checkbox, ConfigProvider, Radio } from 'antd'; -import { Checkbox, ConfigProvider, Radio } from 'antd'; - -import { Checkbox, ConfigProvider, Radio } from 'antd'; - const App: React.FC = () => ( ( Date: Wed, 11 Oct 2023 13:47:11 +0800 Subject: [PATCH 09/16] docs: Historical Debt of API (#45263) * docs: Historical Debt of API * docs: update doc --- docs/blog/historical-debt.en-US.md | 83 ++++++++++++++++++++++++++++++ docs/blog/historical-debt.zh-CN.md | 83 ++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 docs/blog/historical-debt.en-US.md create mode 100644 docs/blog/historical-debt.zh-CN.md diff --git a/docs/blog/historical-debt.en-US.md b/docs/blog/historical-debt.en-US.md new file mode 100644 index 000000000000..c8c81c62603d --- /dev/null +++ b/docs/blog/historical-debt.en-US.md @@ -0,0 +1,83 @@ +--- +title: Historical Debt of API +date: 2023-10-11 +author: zombieJ +--- + +You may have received this warning when upgrading Ant Design: + +```text +Warning: [antd: XXX] `old prop` is deprecated. Please use `new prop` instead. +``` + +This is because antd has some historical debt in API design. For example, in antd v3 and before, the code of TreeSelect was directly copied from Select and extended on this basis. There are differences in their search styles: + +Select + +TreeSelect + +And in the maintenance process, developers want to control the content of the search box. Unfortunately, this requirement was PR by different developers at different times. So two different properties were added, one called `inputValue` and the other called `searchValue`: + +```tsx +// Select in combobox mode, the search box is the input box, `inputValue` looks reasonable + + +// TreeSelect 的搜索框在弹出层,`searchValue` 也很合理 + +``` + +在多选模式下,类 Select 组件在选择内容后会清除搜索框内容。但是有些场景下,开发者希望能够保留。因而 TreeSelect 和 Select 又添加了 `autoClearSearchValue` 属性。 + +等等,Select 明明叫 `inputValue`,为什么要叫 `autoClearSearchValue`?明显应该叫做 `autoClearInputValue` 呐。如果我们在现有的 API 上继续生长其他的同类 API 风格。你会发现组件的 prop 变得越来越分裂。这也会导致代码维护出现坏味道。例如上面这个例子,在之后我们对类 Select 组件抽成了统一的 UI 层并将其合并到 `rc-select` 组件中。`rc-tree-select` 只需要实现弹出层的内容,而输入框的结构和样式可以和 Select 完全复用。但是由于两者的 API 不一致,导致我们需要额外的处理,所以我们在迭代过程中需要对这些 API 债务进行重构并将其统一起来。(在 v4 中,我们将其合并为了 `searchValue` 并且对设计也进行了统一) + +然而世上没有银弹,我们无法在一开始就设计出完美的 API。有一些 API 在设计之初显得非常合理,而随着迭代又会发现或多或少不合时宜。比如说弹出层早期起名为 dropdown,这对应了 Dropdown 以及类 Select 组件的弹出内容。但是对于 Tooltip 而言,dropdown 显然是不适合的。从统一的角度看,popup 会更适合。 + +### 废弃警告 + +在维护过程中,我们逐渐统一了 API 命名规范([API Naming rules](https://github.com/ant-design/ant-design/wiki/API-Naming-rules))。在添加新的 feature 时,优先从现存的 API 中寻找接近。对于现存的 API,逐步添加废弃警告。为了保持兼容,我们的策略是每个版本提供的废弃警告会继续兼容一个大版本,而在下下个大版本中移除它。例如在 v4 中添加了废弃警告,那么在 v5 中仍然可以使用,但是在 v6 中将会被移除。以此确保开发者有足够的时间进行迁移。 + +但是从开发者角度看,这也并不合理。开发者本身只是对 antd 进行了升级,却要因为组件库 API 设计的失误而遭受 console 的侵扰。如果在废弃警告中混入几个使用警告,开发者往往很难发现它们。这种情况在大版本升级中尤为显著,业务可能并没有给你足够的时间去做升级迁移,因而不得不使用兼容包以及其他的一些技术手段让它先跑起来。而对于冗长的废弃警告,开发者不得不选择暂时(或者永远)无视它们。针对这种情况,使用警告会更为重要,因而我们提出了 [Warning Filter RFC](https://github.com/ant-design/ant-design/discussions/44551)。 + +#### 警告过滤 + +通过 ConfigProvider 的 `warning` 属性,可以将废弃信息进行聚合: + +```tsx + +``` + +聚合后,原本打平的废弃信息会合并为一个数组在 console 中展示。而对于使用警告则不会影响: + +![Merged Message](https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*MG-rQ4NSbbcAAAAAAAAAAAAADrJ8AQ/original) + +### 拓展问题 + +如上所述,API 设计不存在银弹。为了防止 breaking change,我们一般不会改动现有的 API 实现。但是对于一些约定的内容,这就会造成麻烦。比如说 `ref` 组件是很典型的约定,只要是 React 的开发者就能明白,通过 `ref` 可以获取 DOM 节点以及做一些诸如 `focus` 的基本操作。但是对于复合组件而言,调用方法和 DOM 不一定能够统一。比如说 Table 组件的 `ref` 显然应该是最外层的 div,但是对于 `scrollTo` 方法则应该对应到滚动容器上(如果是 VirtualTable 则应该交由内部的 `rc-virtual-list` 进行处理)。在 antd mobile 中 `ref` 被设计为复合结构,DOM 节点总是通过 `nativeElement` 返回: + +```tsx +export interface SampleRef { + nativeElement: HTMLElement; + focus(): void; + blur(): void; +} +``` + +而在 antd 中,由于我们早期没有对 `ref` 进行约定,导致在实现方法是就遇到了难题。不过好在有 Proxy 支持,我们可以通过 Proxy 对 `ref` 进行拦截并返回我们想要的结果: + +```tsx +useImperativeHandle( + ref, + () => + new Proxy(divRef.current, { + get(target, key) { + // ... + }, + }), +); +``` + +通过这种方式,我们可以继续兼容之前的使用。它仍然是一个 DOM 节点,但是同样也支持了 SampleRef 的定义调用。 + +## 总结 + +API 设计是个难题,随着技术栈以及组件本身的迭代。一些设计会逐渐腐朽,而 API 升级本身对于开发者也是痛苦的。我们希望通过这篇文章,让开发者能够理解我们的设计思路以及在升级过程中的一些问题。如果你有任何的建议或者想法,欢迎在 Github 中讨论。 From 000589bf7d81cbe6b8ecaeef2e6d03ae5229892d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Wed, 11 Oct 2023 14:45:09 +0800 Subject: [PATCH 10/16] docs: update Flex diff (#45270) --- components/flex/index.en-US.md | 5 +++++ components/flex/index.zh-CN.md | 5 +++++ components/space/index.en-US.md | 5 +++++ components/space/index.zh-CN.md | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/components/flex/index.en-US.md b/components/flex/index.en-US.md index c11c9e1a2fcb..933d48920258 100644 --- a/components/flex/index.en-US.md +++ b/components/flex/index.en-US.md @@ -14,6 +14,11 @@ Flex. Available since `5.10.0`. - Good for setting spacing between elements. - Suitable for setting various horizontal and vertical alignments. +### Difference with Space component + +- Space is used to set the spacing between inline elements. It will add a wrapper element for each child element for inline alignment. Suitable for equidistant arrangement of multiple child elements in rows and columns. +- Flex is used to set the layout of block-level elements. It does not add a wrapper element. Suitable for layout of child elements in vertical or horizontal direction, and provides more flexibility and control. + ## Examples diff --git a/components/flex/index.zh-CN.md b/components/flex/index.zh-CN.md index 8ca29d83ea01..965d8d63ba19 100644 --- a/components/flex/index.zh-CN.md +++ b/components/flex/index.zh-CN.md @@ -15,6 +15,11 @@ tag: New - 适合设置元素之间的间距。 - 适合设置各种水平、垂直对齐方式。 +### 与 Space 组件的区别 + +- Space 为内联元素提供间距,其本身会为每一个子元素添加包裹元素用于内联对齐。适用于行、列中多个子元素的等距排列。 +- Flex 为块级元素提供间距,其本身不会添加包裹元素。适用于垂直或水平方向上的子元素布局,并提供了更多的灵活性和控制能力。 + ## 代码演示 diff --git a/components/space/index.en-US.md b/components/space/index.en-US.md index 41b451d90d76..5e106f09e2f6 100644 --- a/components/space/index.en-US.md +++ b/components/space/index.en-US.md @@ -13,6 +13,11 @@ Set components spacing. - Avoid components clinging together and set a unified space. - Use Space.Compact when child form components are compactly connected and the border is collapsed (After version `antd@4.24.0` Supported). +### Difference with Flex component + +- Space is used to set the spacing between inline elements. It will add a wrapper element for each child element for inline alignment. Suitable for equidistant arrangement of multiple child elements in rows and columns. +- Flex is used to set the layout of block-level elements. It does not add a wrapper element. Suitable for layout of child elements in vertical or horizontal direction, and provides more flexibility and control. + ## Examples diff --git a/components/space/index.zh-CN.md b/components/space/index.zh-CN.md index 41dd446df1e6..23d34d21595b 100644 --- a/components/space/index.zh-CN.md +++ b/components/space/index.zh-CN.md @@ -17,6 +17,11 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*37T2R6O9oi0AAA - 可以设置各种水平对齐方式。 - 需要表单组件之间紧凑连接且合并边框时,使用 Space.Compact(自 `antd@4.24.0` 版本开始提供该组件)。 +### 与 Flex 组件的区别 + +- Space 为内联元素提供间距,其本身会为每一个子元素添加包裹元素用于内联对齐。适用于行、列中多个子元素的等距排列。 +- Flex 为块级元素提供间距,其本身不会添加包裹元素。适用于垂直或水平方向上的子元素布局,并提供了更多的灵活性和控制能力。 + ## 代码演示 From e093b100d515373e9a608d63d0b7a3cae7dbb0b5 Mon Sep 17 00:00:00 2001 From: MadCcc <1075746765@qq.com> Date: Wed, 11 Oct 2023 15:43:59 +0800 Subject: [PATCH 11/16] fix: Card head fit small size tabs (#45272) * fix: Card tabs should fit small size * chore: update snapshot --- .../card/__tests__/__snapshots__/demo-extend.test.ts.snap | 2 +- components/card/__tests__/__snapshots__/demo.test.ts.snap | 2 +- components/card/demo/tabs.tsx | 3 +++ components/card/style/index.ts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/components/card/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/card/__tests__/__snapshots__/demo-extend.test.ts.snap index ac364b586d5d..766a5ee9ce4d 100644 --- a/components/card/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/card/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -1190,7 +1190,7 @@ Array [ class="ant-card-head-wrapper" />
{ activeTabKey={activeTabKey2} tabBarExtraContent={More} onTabChange={onTab2Change} + tabProps={{ + size: 'middle', + }} > {contentListNoTitle[activeTabKey2]} diff --git a/components/card/style/index.ts b/components/card/style/index.ts index 5825de419fcc..06bd2b29d626 100644 --- a/components/card/style/index.ts +++ b/components/card/style/index.ts @@ -364,6 +364,7 @@ const genCardStyle: GenerateStyle = (token): CSSObject => { [`${componentCls}-contain-tabs`]: { [`> ${componentCls}-head`]: { + minHeight: 0, [`${componentCls}-head-title, ${componentCls}-extra`]: { paddingTop: cardHeadPadding, }, @@ -405,7 +406,6 @@ const genCardSizeStyle: GenerateStyle = (token): CSSObject => { [`${componentCls}-small${componentCls}-contain-tabs`]: { [`> ${componentCls}-head`]: { [`${componentCls}-head-title, ${componentCls}-extra`]: { - minHeight: headerHeightSM, paddingTop: 0, display: 'flex', alignItems: 'center', From 80da4e5885cb685025c93d66d9b1fc090e2579eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=93=E5=AE=89?= <455454007@qq.com> Date: Wed, 11 Oct 2023 17:03:15 +0800 Subject: [PATCH 12/16] fix (DirectoryTree) : selectedNodes in onSelect method could not get a value when configuring fieldNames (#45036) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix🐛(DirectoryTree): fieldNames support * fix🐛(DirectoryTree): fieldNames support * test✅(DirectoryTree): Update directoryTree test * test✅(DirectoryTree): Update directoryTree test * chore: simple code * chore: align logic --------- Co-authored-by: yuanzhian Co-authored-by: 二货机器人 --- components/tree/DirectoryTree.tsx | 13 ++-- components/tree/__tests__/directory.test.tsx | 34 ++++++++ components/tree/utils/dictUtil.ts | 81 +++++++++++++------- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/components/tree/DirectoryTree.tsx b/components/tree/DirectoryTree.tsx index 914973981aa0..f546bfcb11f8 100644 --- a/components/tree/DirectoryTree.tsx +++ b/components/tree/DirectoryTree.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import FileOutlined from '@ant-design/icons/FileOutlined'; import FolderOpenOutlined from '@ant-design/icons/FolderOpenOutlined'; import FolderOutlined from '@ant-design/icons/FolderOutlined'; @@ -7,9 +8,8 @@ import type { BasicDataNode } from 'rc-tree'; import type { DataNode, EventDataNode, Key } from 'rc-tree/lib/interface'; import { conductExpandParent } from 'rc-tree/lib/util'; import { convertDataToEntities, convertTreeToData } from 'rc-tree/lib/utils/treeUtil'; -import * as React from 'react'; -import { ConfigContext } from '../config-provider'; +import { ConfigContext } from '../config-provider'; import type { AntdTreeNodeAttribute, TreeProps } from './Tree'; import Tree from './Tree'; import { calcRangeKeys, convertDirectoryKeysToNodes } from './utils/dictUtil'; @@ -113,7 +113,7 @@ const DirectoryTree: React.ForwardRefRenderFunction nativeEvent: MouseEvent; }, ) => { - const { multiple } = props; + const { multiple, fieldNames } = props; const { node, nativeEvent } = event; const { key = '' } = node; @@ -137,7 +137,7 @@ const DirectoryTree: React.ForwardRefRenderFunction newSelectedKeys = keys; lastSelectedKey.current = key; cachedSelectedKeys.current = newSelectedKeys; - newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys); + newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames); } else if (multiple && shiftPick) { // Shift click newSelectedKeys = Array.from( @@ -148,16 +148,17 @@ const DirectoryTree: React.ForwardRefRenderFunction expandedKeys, startKey: key, endKey: lastSelectedKey.current, + fieldNames, }), ]), ); - newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys); + newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames); } else { // Single click newSelectedKeys = [key]; lastSelectedKey.current = key; cachedSelectedKeys.current = newSelectedKeys; - newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys); + newEvent.selectedNodes = convertDirectoryKeysToNodes(treeData, newSelectedKeys, fieldNames); } props.onSelect?.(newSelectedKeys, newEvent); diff --git a/components/tree/__tests__/directory.test.tsx b/components/tree/__tests__/directory.test.tsx index fbb30bfad97f..5c168019cc60 100644 --- a/components/tree/__tests__/directory.test.tsx +++ b/components/tree/__tests__/directory.test.tsx @@ -264,4 +264,38 @@ describe('Directory Tree', () => { render(createTree({ ref: treeRef })); expect('scrollTo' in treeRef.current!).toBeTruthy(); }); + + it('fieldNames support', () => { + const treeData = [ + { + id: '0-0-0', + label: 'Folder', + child: [ + { + label: 'Folder2', + id: '0-0-1', + child: [ + { + label: 'File', + id: '0-0-2', + isLeaf: true, + }, + ], + }, + ], + }, + ]; + const onSelect = jest.fn(); + const { container } = render( + createTree({ + defaultExpandAll: true, + // @ts-ignore + treeData, + onSelect, + fieldNames: { key: 'id', title: 'label', children: 'child' }, + }), + ); + fireEvent.click(container.querySelectorAll('.ant-tree-node-content-wrapper')[0]); + expect(onSelect.mock.calls[0][1].selectedNodes.length).toBe(1); + }); }); diff --git a/components/tree/utils/dictUtil.ts b/components/tree/utils/dictUtil.ts index bc6cfa03439b..794fb2361d5d 100644 --- a/components/tree/utils/dictUtil.ts +++ b/components/tree/utils/dictUtil.ts @@ -1,4 +1,7 @@ import type { DataNode, Key } from 'rc-tree/lib/interface'; +import { fillFieldNames } from 'rc-tree/lib/utils/treeUtil'; + +import type { TreeProps } from '../Tree'; enum Record { None, @@ -6,14 +9,20 @@ enum Record { End, } +type FieldNames = TreeProps['fieldNames']; + function traverseNodesKey( treeData: DataNode[], callback: (key: Key | number | null, node: DataNode) => boolean, + fieldNames: Required>, ) { - function processNode(dataNode: DataNode) { - const { key, children } = dataNode; + const { key: fieldKey, children: fieldChildren } = fieldNames; + + function processNode(dataNode: DataNode & FieldNames[keyof FieldNames]) { + const key = dataNode[fieldKey]; + const children = dataNode[fieldChildren]; if (callback(key, dataNode) !== false) { - traverseNodesKey(children || [], callback); + traverseNodesKey(children || [], callback, fieldNames); } } @@ -26,11 +35,13 @@ export function calcRangeKeys({ expandedKeys, startKey, endKey, + fieldNames, }: { treeData: DataNode[]; expandedKeys: Key[]; startKey?: Key; endKey?: Key; + fieldNames?: FieldNames; }): Key[] { const keys: Key[] = []; let record: Record = Record.None; @@ -46,42 +57,54 @@ export function calcRangeKeys({ return key === startKey || key === endKey; } - traverseNodesKey(treeData, (key: Key) => { - if (record === Record.End) { - return false; - } + traverseNodesKey( + treeData, + (key: Key) => { + if (record === Record.End) { + return false; + } - if (matchKey(key)) { - // Match test - keys.push(key); + if (matchKey(key)) { + // Match test + keys.push(key); - if (record === Record.None) { - record = Record.Start; + if (record === Record.None) { + record = Record.Start; + } else if (record === Record.Start) { + record = Record.End; + return false; + } } else if (record === Record.Start) { - record = Record.End; - return false; + // Append selection + keys.push(key); } - } else if (record === Record.Start) { - // Append selection - keys.push(key); - } - return expandedKeys.includes(key); - }); + return expandedKeys.includes(key); + }, + fillFieldNames(fieldNames), + ); return keys; } -export function convertDirectoryKeysToNodes(treeData: DataNode[], keys: Key[]) { +export function convertDirectoryKeysToNodes( + treeData: DataNode[], + keys: Key[], + fieldNames?: FieldNames, +) { const restKeys: Key[] = [...keys]; const nodes: DataNode[] = []; - traverseNodesKey(treeData, (key: Key, node: DataNode) => { - const index = restKeys.indexOf(key); - if (index !== -1) { - nodes.push(node); - restKeys.splice(index, 1); - } + traverseNodesKey( + treeData, + (key: Key, node: DataNode) => { + const index = restKeys.indexOf(key); + if (index !== -1) { + nodes.push(node); + restKeys.splice(index, 1); + } - return !!restKeys.length; - }); + return !!restKeys.length; + }, + fillFieldNames(fieldNames), + ); return nodes; } From 4cacadbce0e3cdafcbb2ba606bb2bcb38da204a7 Mon Sep 17 00:00:00 2001 From: Jonasz Date: Wed, 11 Oct 2023 17:07:52 +0200 Subject: [PATCH 13/16] docs: added AntBlocks UI to the resources docs (#44439) * Update resources.en-US.md Resource update - added AntBlocks UI * Apply suggestions from code review Signed-off-by: afc163 --------- Signed-off-by: afc163 Co-authored-by: Mateusz Wierzbicki Co-authored-by: afc163 --- docs/resources.en-US.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/resources.en-US.md b/docs/resources.en-US.md index 428d458ccac9..8c589e977e1b 100644 --- a/docs/resources.en-US.md +++ b/docs/resources.en-US.md @@ -78,6 +78,10 @@ Please find below some of the design resources and tools about Ant Design that w - https://mastergo-local-default.oss-cn-beijing.aliyuncs.com/ant-design-mastergo.svg - Use fully components and templates on MasterGo - https://mastergo.com/community/?utm_source=antdesign&utm_medium=link&utm_campaign=resource&cata_name=AntDesign +- AntBlocks UI for Figma + - https://uploads-ssl.webflow.com/64dc925e7cb893427a5c9cdc/64e4610f7818dcc7501057ad_antblocks-ui-card-img.svg + - High-quality, responsive, and customizable React components built on Ant Design + - https://www.antblocksui.com/#figma ## Articles From 0379ee5b6852ce8725037138d22281d975fa274d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BA=A2?= Date: Wed, 11 Oct 2023 23:12:55 +0800 Subject: [PATCH 14/16] ci: merge preview workflows (#45276) * ci: merge preview workflows * chore: update * chore: update --- .github/workflows/preview-build.yml | 125 ---------------- .github/workflows/preview-deploy.yml | 106 -------------- .github/workflows/preview-start.yml | 31 ---- .github/workflows/preview.yml | 208 +++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 262 deletions(-) delete mode 100644 .github/workflows/preview-build.yml delete mode 100644 .github/workflows/preview-deploy.yml delete mode 100644 .github/workflows/preview-start.yml create mode 100644 .github/workflows/preview.yml diff --git a/.github/workflows/preview-build.yml b/.github/workflows/preview-build.yml deleted file mode 100644 index 03660a33f417..000000000000 --- a/.github/workflows/preview-build.yml +++ /dev/null @@ -1,125 +0,0 @@ -# Each PR will build preview site that help to check code is work as expect. - -name: Preview Build - -on: - pull_request: - types: [opened, synchronize, reopened] - -# Cancel prev CI if new commit come -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - # Prepare node modules. Reuse cache if available - setup: - name: prepare preview - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: cache package-lock.json - uses: actions/cache@v3 - with: - path: package-temp-dir - key: lock-${{ github.sha }} - - - name: create package-lock.json - run: npm i --package-lock-only --ignore-scripts - - - name: hack for single file - run: | - if [ ! -d "package-temp-dir" ]; then - mkdir package-temp-dir - fi - cp package-lock.json package-temp-dir - - name: cache node_modules - id: node_modules_cache_id - uses: actions/cache@v3 - with: - path: node_modules - key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} - - - name: install - if: steps.node_modules_cache_id.outputs.cache-hit != 'true' - run: npm ci - - build-site: - name: build preview - runs-on: ubuntu-latest - needs: setup - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: restore cache from package-lock.json - uses: actions/cache@v3 - with: - path: package-temp-dir - key: lock-${{ github.sha }} - - - name: restore cache from node_modules - uses: actions/cache@v3 - with: - path: node_modules - key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} - - - name: npm run site - id: site - run: npm run site - env: - SITE_ENV: development - NODE_OPTIONS: "--max_old_space_size=4096 --openssl-legacy-provider" - - - name: upload site artifact - uses: actions/upload-artifact@v3 - with: - name: site - path: _site/ - retention-days: 5 - - # Upload PR id for next workflow use - - name: Save PR number - if: ${{ always() }} - run: echo ${{ github.event.number }} > ./pr-id.txt - - - name: Upload PR number - if: ${{ always() }} - uses: actions/upload-artifact@v3 - with: - name: pr - path: ./pr-id.txt - - site-test: - name: site E2E test - runs-on: ubuntu-latest - needs: [setup, build-site] - steps: - - name: checkout - uses: actions/checkout@v4 - - - name: restore cache from package-lock.json - uses: actions/cache@v3 - with: - path: package-temp-dir - key: lock-${{ github.sha }} - - - name: restore cache from node_modules - uses: actions/cache@v3 - with: - path: node_modules - key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} - - - name: download site artifact - uses: actions/download-artifact@v3 - with: - name: site - path: _site - - - name: run e2e test - run: npm run site:test diff --git a/.github/workflows/preview-deploy.yml b/.github/workflows/preview-deploy.yml deleted file mode 100644 index b0ad8e52252a..000000000000 --- a/.github/workflows/preview-deploy.yml +++ /dev/null @@ -1,106 +0,0 @@ -# Each PR will build preview site that help to check code is work as expect. - -name: Preview Deploy - -on: - workflow_run: - workflows: ["Preview Build"] - types: - - completed - -permissions: - contents: read - -jobs: - deploy-site: - permissions: - actions: read # for dawidd6/action-download-artifact to query and download artifacts - issues: write # for actions-cool/maintain-one-comment to modify or create issue comments - pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments - name: deploy preview - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' - steps: - # We need get PR id first - - name: download pr artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} - name: pr - - # Save PR id to output - - name: save PR id - id: pr - run: echo "id=$(> $GITHUB_OUTPUT - - # Download site artifact - - name: download site artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} - name: site - - - name: upload surge service - id: deploy - run: | - export DEPLOY_DOMAIN=https://preview-${{ steps.pr.outputs.id }}-ant-design.surge.sh - npx surge --project ./ --domain $DEPLOY_DOMAIN --token ${{ secrets.SURGE_TOKEN }} - - - name: update status comment - uses: actions-cool/maintain-one-comment@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - body: | - [](https://preview-${{ steps.pr.outputs.id }}-ant-design.surge.sh) - - body-include: '' - number: ${{ steps.pr.outputs.id }} - - - name: The job has failed - if: ${{ failure() }} - uses: actions-cool/maintain-one-comment@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - body: | - - - body-include: '' - number: ${{ steps.pr.outputs.id }} - - build-site-failed: - permissions: - actions: read # for dawidd6/action-download-artifact to query and download artifacts - issues: write # for actions-cool/maintain-one-comment to modify or create issue comments - pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments - name: build preview failed - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'failure' - steps: - # We need get PR id first - - name: download pr artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: ${{ github.event.workflow_run.workflow_id }} - run_id: ${{ github.event.workflow_run.id }} - name: pr - - # Save PR id to output - - name: save PR id - id: pr - run: echo "id=$(> $GITHUB_OUTPUT - - - name: The job has failed - uses: actions-cool/maintain-one-comment@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - body: | - - - body-include: '' - number: ${{ steps.pr.outputs.id }} diff --git a/.github/workflows/preview-start.yml b/.github/workflows/preview-start.yml deleted file mode 100644 index 7cc3b9b27a4e..000000000000 --- a/.github/workflows/preview-start.yml +++ /dev/null @@ -1,31 +0,0 @@ -# When `preview-build` start. Leave a message on the PR -# -# 🚨🚨🚨 Important 🚨🚨🚨 -# Never do any `checkout` or `npm install` action! -# `pull_request_target` will enable PR to access the secrets! - -name: Preview Start - -on: - pull_request_target: - types: [opened, synchronize, reopened] - -permissions: - contents: read - -jobs: - preview-start: - permissions: - issues: write # for actions-cool/maintain-one-comment to modify or create issue comments - pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments - name: start preview info - runs-on: ubuntu-latest - steps: - - name: update status comment - uses: actions-cool/maintain-one-comment@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - body: | - ![Prepare preview](https://user-images.githubusercontent.com/5378891/72351368-2c979e00-371b-11ea-9652-eb4e825d745e.gif) - - body-include: '' diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 000000000000..c8aa66092459 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,208 @@ +name: PR Preview + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +# Cancel prev CI if new commit come +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + preview-start: + permissions: + issues: write # for actions-cool/maintain-one-comment to modify or create issue comments + pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments + name: Prepare preview + runs-on: ubuntu-latest + steps: + - name: update status comment + uses: actions-cool/maintain-one-comment@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + body: | + ![Prepare preview](https://user-images.githubusercontent.com/5378891/72351368-2c979e00-371b-11ea-9652-eb4e825d745e.gif) + + body-include: "" + + setup: + name: Setup + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: cache package-lock.json + uses: actions/cache@v3 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: create package-lock.json + run: npm i --package-lock-only --ignore-scripts + + - name: hack for single file + run: | + if [ ! -d "package-temp-dir" ]; then + mkdir package-temp-dir + fi + cp package-lock.json package-temp-dir + - name: cache node_modules + id: node_modules_cache_id + uses: actions/cache@v3 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: install + if: steps.node_modules_cache_id.outputs.cache-hit != 'true' + run: npm ci + + build-site: + name: Build Preview Site + runs-on: ubuntu-latest + needs: setup + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: restore cache from package-lock.json + uses: actions/cache@v3 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v3 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: npm run site + id: site + run: npm run site + env: + SITE_ENV: development + NODE_OPTIONS: "--max_old_space_size=4096 --openssl-legacy-provider" + + - name: upload site artifact + uses: actions/upload-artifact@v3 + with: + name: site + path: _site/ + retention-days: 5 + + # Upload PR id for next workflow use + - name: Save PR number + if: ${{ always() }} + run: echo ${{ github.event.number }} > ./pr-id.txt + + - name: Upload PR number + if: ${{ always() }} + uses: actions/upload-artifact@v3 + with: + name: pr + path: ./pr-id.txt + + site-test: + name: Site E2E Test + runs-on: ubuntu-latest + needs: build-site + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: restore cache from package-lock.json + uses: actions/cache@v3 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v3 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: download site artifact + uses: actions/download-artifact@v3 + with: + name: site + path: _site + + - name: run e2e test + run: npm run site:test + + preview-deploy: + name: Deploy Preview + runs-on: ubuntu-latest + needs: build-site + steps: + # We need get PR id first + - name: download pr artifact + uses: actions/download-artifact@v3 + with: + name: pr + + # Save PR id to output + - name: save PR id + id: pr + run: echo "id=$(> $GITHUB_OUTPUT + + # Download site artifact + - name: download site artifact + uses: actions/download-artifact@v3 + with: + name: site + + - name: upload surge service + id: deploy + run: | + export DEPLOY_DOMAIN=https://preview-${{ steps.pr.outputs.id }}-ant-design.surge.sh + npx surge --project ./ --domain $DEPLOY_DOMAIN --token ${{ secrets.SURGE_TOKEN }} + + preview-end: + name: Preview End + runs-on: ubuntu-latest + needs: + - build-site + - preview-deploy + if: always() + permissions: + issues: write # for actions-cool/maintain-one-comment to modify or create issue comments + pull-requests: write # for actions-cool/maintain-one-comment to modify or create PR comments + steps: + - name: download pr artifact + uses: actions/download-artifact@v3 + with: + name: pr + + - name: save PR id + id: pr + run: echo "id=$(> $GITHUB_OUTPUT + + - name: success comment + if: needs.build-site.result == 'success' && needs.preview-deploy.result == 'success' + uses: actions-cool/maintain-one-comment@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + body: | + [Preview Is ready](https://preview-${{ steps.pr.outputs.id }}-ant-design.surge.sh) + + body-include: "" + number: ${{ steps.pr.outputs.id }} + + - name: failed comment + if: needs.build-site.result == 'failure' || needs.preview-deploy.result == 'failure' + uses: actions-cool/maintain-one-comment@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + body: | + Preview Failed + + body-include: "" + number: ${{ steps.pr.outputs.id }} From 8024bbd346b5215415a0acbee56f5668d8d76b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Wed, 11 Oct 2023 23:13:13 +0800 Subject: [PATCH 15/16] fix: ListField reset should not fill it (#45284) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9119e3a9761b..59f85c0d87d1 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "rc-dialog": "~9.3.3", "rc-drawer": "~6.5.2", "rc-dropdown": "~4.1.0", - "rc-field-form": "~1.38.2", + "rc-field-form": "~1.39.0", "rc-image": "~7.3.1", "rc-input": "~1.2.1", "rc-input-number": "~8.1.0", From 70ce748d57dfbc8e04782a4c1232c9a2e4c87b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Thu, 12 Oct 2023 09:43:35 +0800 Subject: [PATCH 16/16] fix: options missing id (#45287) --- .../index/components/Theme/ColorPicker.tsx | 4 +- .../index/components/Theme/RadiusPicker.tsx | 6 +- .../index/components/Theme/ThemePicker.tsx | 81 ++++++++++--------- .dumi/pages/index/components/Theme/index.tsx | 19 +++-- components/checkbox/Group.tsx | 6 +- components/checkbox/__tests__/group.test.tsx | 8 ++ components/radio/__tests__/group.test.tsx | 8 ++ components/radio/group.tsx | 1 + 8 files changed, 86 insertions(+), 47 deletions(-) diff --git a/.dumi/pages/index/components/Theme/ColorPicker.tsx b/.dumi/pages/index/components/Theme/ColorPicker.tsx index fa080e766197..464566be4759 100644 --- a/.dumi/pages/index/components/Theme/ColorPicker.tsx +++ b/.dumi/pages/index/components/Theme/ColorPicker.tsx @@ -35,6 +35,7 @@ const useStyle = createStyles(({ token, css }) => ({ })); export interface ColorPickerProps { + id?: string; children?: React.ReactNode; value?: string | Color; onChange?: (value?: Color | string) => void; @@ -66,7 +67,7 @@ const DebouncedColorPicker: React.FC = (props) => { ); }; -const ThemeColorPicker: React.FC = ({ value, onChange }) => { +const ThemeColorPicker: React.FC = ({ value, onChange, id }) => { const { styles } = useStyle(); const matchColors = React.useMemo(() => { @@ -95,6 +96,7 @@ const ThemeColorPicker: React.FC = ({ value, onChange }) => { value={typeof value === 'string' ? value : value?.toHexString()} onChange={(event) => onChange?.(event.target.value)} style={{ width: 120 }} + id={id} /> diff --git a/.dumi/pages/index/components/Theme/RadiusPicker.tsx b/.dumi/pages/index/components/Theme/RadiusPicker.tsx index d0718b58e68c..ee7f03e574c7 100644 --- a/.dumi/pages/index/components/Theme/RadiusPicker.tsx +++ b/.dumi/pages/index/components/Theme/RadiusPicker.tsx @@ -1,12 +1,13 @@ import React from 'react'; -import { InputNumber, Space, Slider } from 'antd'; +import { InputNumber, Slider, Space } from 'antd'; export interface RadiusPickerProps { + id?: string; value?: number; onChange?: (value: number | null) => void; } -export default function RadiusPicker({ value, onChange }: RadiusPickerProps) { +export default function RadiusPicker({ value, onChange, id }: RadiusPickerProps) { return ( `${val}px`} parser={(str) => (str ? parseFloat(str) : (str as any))} + id={id} /> ({ themeCard: css` - border-radius: ${token.borderRadius}px; - cursor: pointer; - transition: all ${token.motionDurationSlow}; - overflow: hidden; - display: inline-block; - - & > input[type="radio"] { - width: 0; - height: 0; - opacity: 0; - position: absolute; - } - - img { - vertical-align: top; - box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), - 0 9px 28px 8px rgba(0, 0, 0, 0.05); - } - - &:focus-within, - &:hover { - transform: scale(1.04); - } - `, + border-radius: ${token.borderRadius}px; + cursor: pointer; + transition: all ${token.motionDurationSlow}; + overflow: hidden; + display: inline-block; + + & > input[type='radio'] { + width: 0; + height: 0; + opacity: 0; + position: absolute; + } + + img { + vertical-align: top; + box-shadow: + 0 3px 6px -4px rgba(0, 0, 0, 0.12), + 0 6px 16px 0 rgba(0, 0, 0, 0.08), + 0 9px 28px 8px rgba(0, 0, 0, 0.05); + } + + &:focus-within, + &:hover { + transform: scale(1.04); + } + `, themeCardActive: css` - box-shadow: 0 0 0 1px ${token.colorBgContainer}, - 0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary}; - - &, - &:hover:not(:focus-within) { - transform: scale(1); - } - `, + box-shadow: + 0 0 0 1px ${token.colorBgContainer}, + 0 0 0 ${token.controlOutlineWidth * 2 + 1}px ${token.colorPrimary}; + + &, + &:hover:not(:focus-within) { + transform: scale(1); + } + `, })); export interface ThemePickerProps { + id?: string; value?: string; onChange?: (value: string) => void; } -export default function ThemePicker({ value, onChange }: ThemePickerProps) { +export default function ThemePicker(props: ThemePickerProps) { + const { value, onChange, id } = props; + const token = useTheme(); const { styles } = useStyle(); @@ -82,7 +89,7 @@ export default function ThemePicker({ value, onChange }: ThemePickerProps) { return ( - {Object.keys(THEMES).map((theme) => { + {Object.keys(THEMES).map((theme, index) => { const url = THEMES[theme as THEME]; return ( @@ -94,7 +101,7 @@ export default function ThemePicker({ value, onChange }: ThemePickerProps) { onChange?.(theme); }} > - + {theme} {locale[theme as keyof typeof locale]} diff --git a/.dumi/pages/index/components/Theme/index.tsx b/.dumi/pages/index/components/Theme/index.tsx index 258d0f64b974..e528a1ad398e 100644 --- a/.dumi/pages/index/components/Theme/index.tsx +++ b/.dumi/pages/index/components/Theme/index.tsx @@ -534,11 +534,20 @@ export default function Theme() { - - - {locale.default} - {locale.compact} - + + diff --git a/components/checkbox/Group.tsx b/components/checkbox/Group.tsx index 4b6a304a653c..94dba906651e 100644 --- a/components/checkbox/Group.tsx +++ b/components/checkbox/Group.tsx @@ -1,11 +1,11 @@ +import * as React from 'react'; import classNames from 'classnames'; import omit from 'rc-util/lib/omit'; -import * as React from 'react'; + import { ConfigContext } from '../config-provider'; import type { CheckboxChangeEvent } from './Checkbox'; import Checkbox from './Checkbox'; import GroupContext from './GroupContext'; - import useStyle from './style'; export type CheckboxValueType = string | number | boolean; @@ -16,6 +16,7 @@ export interface CheckboxOptionType { style?: React.CSSProperties; disabled?: boolean; title?: string; + id?: string; onChange?: (e: CheckboxChangeEvent) => void; } @@ -124,6 +125,7 @@ const InternalGroup: React.ForwardRefRenderFunction {option.label} diff --git a/components/checkbox/__tests__/group.test.tsx b/components/checkbox/__tests__/group.test.tsx index cd643627cf40..1178df577624 100644 --- a/components/checkbox/__tests__/group.test.tsx +++ b/components/checkbox/__tests__/group.test.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; + import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { fireEvent, render } from '../../../tests/utils'; @@ -268,4 +269,11 @@ describe('CheckboxGroup', () => { fireEvent.click(container.querySelector('.ant-checkbox-input')!); expect(onChange).toHaveBeenCalledWith(['A']); }); + + it('options support id', () => { + const { container } = render( + , + ); + expect(container.querySelector('#bamboo')).toBeTruthy(); + }); }); diff --git a/components/radio/__tests__/group.test.tsx b/components/radio/__tests__/group.test.tsx index 8839f89c4cef..9179cd850df6 100644 --- a/components/radio/__tests__/group.test.tsx +++ b/components/radio/__tests__/group.test.tsx @@ -1,5 +1,6 @@ import type { RefAttributes } from 'react'; import React from 'react'; + import type { RadioGroupProps } from '..'; import Radio from '..'; import { fireEvent, render } from '../../../tests/utils'; @@ -252,4 +253,11 @@ describe('Radio Group', () => { fireEvent.blur(container.firstChild!); expect(handleBlur).toHaveBeenCalledTimes(1); }); + + it('options support id', () => { + const { container } = render( + , + ); + expect(container.querySelector('#bamboo')).toBeTruthy(); + }); }); diff --git a/components/radio/group.tsx b/components/radio/group.tsx index a5c2cdd9a643..9e2efab1c526 100644 --- a/components/radio/group.tsx +++ b/components/radio/group.tsx @@ -79,6 +79,7 @@ const RadioGroup = React.forwardRef((props, ref checked={value === option.value} title={option.title} style={option.style} + id={option.id} > {option.label}