diff --git a/.dumirc.ts b/.dumirc.ts index 66d6828f3a..81313d857c 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -23,6 +23,7 @@ export default defineConfig({ mfsu: false, mako: {}, crossorigin: {}, + runtimePublicPath: {}, outputPath: '_site', favicons: ['https://gw.alipayobjects.com/zos/rmsportal/rlpTLlbMzTNYuZGGCVYM.png'], resolve: { diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index cef7b8e68f..53f6390b83 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -16,6 +16,14 @@ tag: vVERSION --- +## 5.20.3 + +`2024-08-26` + +- 🐞 Refactor Typography native css ellipsis measure logic to handle precision edge case. [#50514](https://github.com/ant-design/ant-design/pull/50514) [@zombieJ](https://github.com/zombieJ) +- 🐞 Fix ColorPicker `onChangeComplete` not correct when click directly without move on the picker panel. [#50501](https://github.com/ant-design/ant-design/pull/50501) [@zombieJ](https://github.com/zombieJ) +- 🐞 Fix FloatButton.Group with controlled mode warning for nest updating issue. [#50500](https://github.com/ant-design/ant-design/pull/50500) [@zombieJ](https://github.com/zombieJ) + ## 5.20.2 `2024-08-19` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index fd3b73bbb5..21e8a9369b 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -15,6 +15,14 @@ tag: vVERSION --- +## 5.20.3 + +`2024-08-26` + +- 🐞 重构 Typography 在使用 css 原生省略时的检查逻辑,以解决屏幕缩放等情况下的精度问题。[#50514](https://github.com/ant-design/ant-design/pull/50514) [@zombieJ](https://github.com/zombieJ) +- 🐞 修复 ColorPicker 组件在面板上不拖拽直接点击的时候,`onChangeComplete` 返回值不正确的问题。[#50501](https://github.com/ant-design/ant-design/pull/50501) [@zombieJ](https://github.com/zombieJ) +- 🐞 修复 FloatButton.Group 在受控模式下 React 会警告递归更新的问题。[#50500](https://github.com/ant-design/ant-design/pull/50500) [@zombieJ](https://github.com/zombieJ) + ## 5.20.2 `2024-08-19` diff --git a/README-zh_CN.md b/README-zh_CN.md index 0f84ba4e9f..4004ea016e 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -57,6 +57,8 @@ ## 🖥 兼容环境 +支持范围:https://browsersl.ist/#q=defaults + - 现代浏览器。 - 支持服务端渲染。 - [Electron](https://www.electronjs.org/) diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000000..a4ff737cd4 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,7 @@ +coverage: + status: + project: #add everything under here, more options at https://docs.codecov.com/docs/commit-status + default: + target: 100% + threshold: 0% + base: auto diff --git a/components/drawer/index.en-US.md b/components/drawer/index.en-US.md index 422ce1ce68..a85dd7998f 100644 --- a/components/drawer/index.en-US.md +++ b/components/drawer/index.en-US.md @@ -45,8 +45,8 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr Common props ref:[Common props](/docs/react/common-props) -:::info{title=注意} -v5 use `rootClassName` & `rootStyle` to config wrapper style instead of `className` & `style` in v4 to align the API with Modal. +:::info{title=Note} +v5 uses `rootClassName` & `rootStyle` to configure the outermost element style, instead of `className` & `style` from v4. This is done to align the API with Modal. ::: | Props | Description | Type | Default | Version | diff --git a/components/popconfirm/__tests__/index.test.tsx b/components/popconfirm/__tests__/index.test.tsx index d07e3fce16..881ab700ef 100644 --- a/components/popconfirm/__tests__/index.test.tsx +++ b/components/popconfirm/__tests__/index.test.tsx @@ -8,8 +8,8 @@ import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils'; import Button from '../../button'; describe('Popconfirm', () => { - mountTest(Popconfirm as any); - rtlTest(Popconfirm as any); + mountTest(() => ); + rtlTest(() => ); const eventObject = expect.objectContaining({ target: expect.anything(), diff --git a/components/segmented/__tests__/index.test.tsx b/components/segmented/__tests__/index.test.tsx index b550977b92..c80948ce62 100644 --- a/components/segmented/__tests__/index.test.tsx +++ b/components/segmented/__tests__/index.test.tsx @@ -29,8 +29,8 @@ function expectMatchChecked(container: HTMLElement, checkedList: boolean[]) { } describe('Segmented', () => { - mountTest(Segmented as any); - rtlTest(Segmented as any); + mountTest(() => ); + rtlTest(() => ); beforeAll(() => { jest.useFakeTimers(); diff --git a/components/theme/index.tsx b/components/theme/index.tsx index 481dd08d8e..aa891ac2f4 100644 --- a/components/theme/index.tsx +++ b/components/theme/index.tsx @@ -1,7 +1,11 @@ /* eslint-disable import/prefer-default-export */ import getDesignToken from './getDesignToken'; import type { GlobalToken, MappingAlgorithm } from './interface'; -import { defaultConfig, useToken as useInternalToken } from './internal'; +import { + defaultConfig, + DesignTokenContext as InternalDesignTokenContext, + useToken as useInternalToken, +} from './internal'; import compactAlgorithm from './themes/compact'; import darkAlgorithm from './themes/dark'; import defaultAlgorithm from './themes/default'; @@ -19,15 +23,21 @@ function useToken() { export type { GlobalToken, MappingAlgorithm }; export default { - /** @private Test Usage. Do not use in production. */ - defaultConfig, - /** Default seedToken */ defaultSeed: defaultConfig.token, - useToken, defaultAlgorithm, darkAlgorithm, compactAlgorithm, getDesignToken, + /** + * @private Private variable + * @warring 🔥 Do not use in production. 🔥 + */ + defaultConfig, + /** + * @private Private variable + * @warring 🔥 Do not use in production. 🔥 + */ + _internalContext: InternalDesignTokenContext, }; diff --git a/components/tree/demo/virtual-scroll.tsx b/components/tree/demo/virtual-scroll.tsx index a201ba6d6b..f128d73fcd 100644 --- a/components/tree/demo/virtual-scroll.tsx +++ b/components/tree/demo/virtual-scroll.tsx @@ -29,7 +29,10 @@ const App: React.FC = () => ( treeData={treeData} height={233} defaultExpandAll - titleRender={(item) => {item.title as any}} + titleRender={(item) => { + const title = item.title as React.ReactNode; + return {title}; + }} /> ); diff --git a/components/typography/Base/Ellipsis.tsx b/components/typography/Base/Ellipsis.tsx index 6c38f96316..c7c5975c54 100644 --- a/components/typography/Base/Ellipsis.tsx +++ b/components/typography/Base/Ellipsis.tsx @@ -224,6 +224,11 @@ export default function EllipsisMeasure(props: EllipsisProps) { // ========================= Text Content ========================= const finalContent = React.useMemo(() => { + // Skip everything if `enableMeasure` is disabled + if (!enableMeasure) { + return children(nodeList, false); + } + if ( needEllipsis !== STATUS_MEASURE_NEED_ELLIPSIS || !ellipsisCutIndex || diff --git a/components/typography/Base/index.tsx b/components/typography/Base/index.tsx index 12fc74ba2f..bd97df4da0 100644 --- a/components/typography/Base/index.tsx +++ b/components/typography/Base/index.tsx @@ -25,7 +25,7 @@ import Typography from '../Typography'; import CopyBtn from './CopyBtn'; import Ellipsis from './Ellipsis'; import EllipsisTooltip from './EllipsisTooltip'; -import { getEleSize } from './util'; +import { isEleEllipsis } from './util'; export type BaseType = 'secondary' | 'success' | 'warning' | 'danger'; @@ -281,11 +281,7 @@ const Base = React.forwardRef((props, ref) => { const textEle = typographyRef.current; if (enableEllipsis && cssEllipsis && textEle) { - const [offsetWidth, offsetHeight] = getEleSize(textEle); - - const currentEllipsis = cssLineClamp - ? offsetHeight < textEle.scrollHeight - : offsetWidth < textEle.scrollWidth; + const currentEllipsis = isEleEllipsis(textEle); if (isNativeEllipsis !== currentEllipsis) { setIsNativeEllipsis(currentEllipsis); @@ -379,15 +375,7 @@ const Base = React.forwardRef((props, ref) => { // Expand const renderExpand = () => { const { expandable, symbol } = ellipsisConfig; - - if (!expandable) { - return null; - } - if (expanded && expandable !== 'collapsible') { - return null; - } - - return ( + return expandable ? ( ((props, ref) => { > {typeof symbol === 'function' ? symbol(expanded) : symbol} - ); + ) : null; }; // Edit @@ -446,7 +434,6 @@ const Base = React.forwardRef((props, ref) => { }; const renderOperations = (canEllipsis: boolean) => [ - // (renderExpanded || ellipsisConfig.collapsible) && renderExpand(), canEllipsis && renderExpand(), renderEdit(), renderCopy(), diff --git a/components/typography/Base/util.ts b/components/typography/Base/util.ts index b9932468f0..5efdec424d 100644 --- a/components/typography/Base/util.ts +++ b/components/typography/Base/util.ts @@ -13,20 +13,38 @@ export function getNode(dom: React.ReactNode, defaultNode: React.ReactNode, need } /** - * Get React of element with precision. - * ref: https://github.com/ant-design/ant-design/issues/50143 + * Check for element is native ellipsis + * ref: + * - https://github.com/ant-design/ant-design/issues/50143 + * - https://github.com/ant-design/ant-design/issues/50414 */ -export function getEleSize(ele: HTMLElement): [width: number, height: number] { - const rect = ele.getBoundingClientRect(); - const { offsetWidth, offsetHeight } = ele; +export function isEleEllipsis(ele: HTMLElement): boolean { + // Create a new div to get the size + const childDiv = document.createElement('em'); + ele.appendChild(childDiv); - let returnWidth = offsetWidth; - let returnHeight = offsetHeight; - - if (Math.abs(offsetWidth - rect.width) < 1 && Math.abs(offsetHeight - rect.height) < 1) { - returnWidth = rect.width; - returnHeight = rect.height; + // For test case + if (process.env.NODE_ENV !== 'production') { + childDiv.className = 'ant-typography-css-ellipsis-content-measure'; } - return [returnWidth, returnHeight]; + const rect = ele.getBoundingClientRect(); + const childRect = childDiv.getBoundingClientRect(); + + // Reset + ele.removeChild(childDiv); + + // Range checker + if ( + // Horizontal in range + rect.left <= childRect.left && + childRect.right <= rect.right && + // Vertical in range + rect.top <= childRect.top && + childRect.bottom <= rect.bottom + ) { + return false; + } + + return true; } diff --git a/components/typography/__tests__/ellipsis.test.tsx b/components/typography/__tests__/ellipsis.test.tsx index df16c5d832..5340e6f60e 100644 --- a/components/typography/__tests__/ellipsis.test.tsx +++ b/components/typography/__tests__/ellipsis.test.tsx @@ -364,29 +364,48 @@ describe('Typography.Ellipsis', () => { describe('should tooltip support', () => { let domSpy: ReturnType; - let containerWidth = 100; - let contentWidth = 200; - let rectContainerWidth = 100; + let containerRect = { + left: 0, + top: 0, + right: 100, + bottom: 22, + }; + let measureRect = { + left: 200, + top: 0, + }; beforeAll(() => { domSpy = spyElementPrototypes(HTMLElement, { - offsetWidth: { - get: () => containerWidth, + getBoundingClientRect() { + if ( + (this as unknown as HTMLElement).classList.contains( + 'ant-typography-css-ellipsis-content-measure', + ) + ) { + return { + ...measureRect, + right: measureRect.left, + bottom: measureRect.top + 22, + }; + } + + return containerRect; }, - scrollWidth: { - get: () => contentWidth, - }, - getBoundingClientRect: () => ({ - width: rectContainerWidth, - height: 0, - }), }); }); beforeEach(() => { - containerWidth = 100; - contentWidth = 200; - rectContainerWidth = 100; + containerRect = { + left: 0, + top: 0, + right: 100, + bottom: 22, + }; + measureRect = { + left: 200, + top: 0, + }; }); afterAll(() => { @@ -453,22 +472,40 @@ describe('Typography.Ellipsis', () => { }); }); - // https://github.com/ant-design/ant-design/issues/50143 - it('precision', async () => { - containerWidth = 100; - contentWidth = 100; - rectContainerWidth = 99.9; + describe('precision', () => { + // https://github.com/ant-design/ant-design/issues/50143 + it('should show', async () => { + containerRect.right = 99.9; + measureRect.left = 100; - const { container, baseElement } = await getWrapper({ - title: true, - className: 'tooltip-class-name', - }); - fireEvent.mouseEnter(container.firstChild!); + const { container, baseElement } = await getWrapper({ + title: true, + className: 'tooltip-class-name', + }); + fireEvent.mouseEnter(container.firstChild!); + + await waitFakeTimer(); - await waitFor(() => { expect(container.querySelector('.tooltip-class-name')).toBeTruthy(); expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull(); }); + + // https://github.com/ant-design/ant-design/issues/50414 + it('should not show', async () => { + containerRect.right = 48.52; + measureRect.left = 48.52; + + const { container, baseElement } = await getWrapper({ + title: true, + className: 'tooltip-class-name', + }); + fireEvent.mouseEnter(container.firstChild!); + + await waitFakeTimer(); + + expect(container.querySelector('.tooltip-class-name')).toBeTruthy(); + expect(baseElement.querySelector('.ant-tooltip-open')).toBeFalsy(); + }); }); }); @@ -490,22 +527,26 @@ describe('Typography.Ellipsis', () => { it('should display tooltip if line clamp', async () => { mockRectSpy = spyElementPrototypes(HTMLElement, { - scrollHeight: { - get() { - let html = (this as any).innerHTML; - html = html.replace(/<[^>]*>/g, ''); - const lines = Math.ceil(html.length / LINE_STR_COUNT); - return lines * 16; - }, - }, - offsetHeight: { - get: () => 32, - }, - offsetWidth: { - get: () => 100, - }, - scrollWidth: { - get: () => 100, + getBoundingClientRect() { + if ( + (this as unknown as HTMLElement).classList.contains( + 'ant-typography-css-ellipsis-content-measure', + ) + ) { + return { + left: 0, + right: 0, + top: 100, + bottom: 122, + }; + } + + return { + left: 0, + right: 100, + top: 0, + bottom: 22 * 3, + }; }, }); @@ -527,6 +568,32 @@ describe('Typography.Ellipsis', () => { // https://github.com/ant-design/ant-design/issues/46580 it('dynamic to be ellipsis should show tooltip', async () => { + let dynamicWidth = 100; + + mockRectSpy = spyElementPrototypes(HTMLElement, { + getBoundingClientRect() { + if ( + (this as unknown as HTMLElement).classList.contains( + 'ant-typography-css-ellipsis-content-measure', + ) + ) { + return { + left: 0, + right: dynamicWidth, + top: 0, + bottom: 22, + }; + } + + return { + left: 100, + right: 100, + top: 0, + bottom: 22, + }; + }, + }); + const ref = React.createRef(); render( @@ -535,8 +602,7 @@ describe('Typography.Ellipsis', () => { ); // Force to narrow - offsetWidth = 1; - scrollWidth = 100; + dynamicWidth = 50; triggerResize(ref.current!); await waitFakeTimer(); @@ -544,6 +610,8 @@ describe('Typography.Ellipsis', () => { fireEvent.mouseEnter(ref.current!); await waitFakeTimer(); expect(document.querySelector('.ant-tooltip')).toBeTruthy(); + + mockRectSpy.mockRestore(); }); it('not force single line if expanded', async () => { diff --git a/docs/react/compatible-style.en-US.md b/docs/react/compatible-style.en-US.md index aaa308ac59..c2d0780a70 100644 --- a/docs/react/compatible-style.en-US.md +++ b/docs/react/compatible-style.en-US.md @@ -5,37 +5,24 @@ order: 1 title: CSS Compatible --- -Ant Design supports the last 2 versions of modern browsers. If you need to be compatible with legacy browsers, please perform downgrade processing according to actual needs: +### Default Style Compatibility -## StyleProvider +Ant Design supports the [last 2 versions of modern browsers](https://browsersl.ist/#q=defaults). If you need to be compatible with legacy browsers, please perform downgrade processing according to actual needs: -Please ref [`@ant-design/cssinjs`](https://github.com/ant-design/cssinjs#styleprovider). +| Feature | antd version | Compatibility | Minimum Chrome Version | Compatibility workaround | +| --- | --- | --- | --- | --- | +| [:where Selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) | `>=5.0.0` | [caniuse](https://caniuse.com/?search=%3Awhere) | Chrome 88 | `` | +| [CSS Logical Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) | `>=5.0.0` | [caniuse](https://caniuse.com/css-logical-props) | Chrome 89 | `` | -## `layer` Downgrade +If you need to support older browsers, please use [StyleProvider](https://github.com/ant-design/cssinjs#styleprovider) for degradation handling according to your actual requirements. -Ant Design supports configuring `layer` for unified downgrade since `5.17.0`. After the downgrade, the style of antd will always be lower than the default CSS selector priority, so that users can override the style (please be sure to check the browser compatibility of `@layer`): +## `:where` in selector -```tsx -import { StyleProvider } from '@ant-design/cssinjs'; - -export default () => ( - - - -); -``` - -antd styles will be encapsulated in `@layer` to lower the priority: - -```diff -++ @layer antd { - :where(.css-bAMboO).ant-btn { - color: #fff; - } -++ } -``` - -## Compatible adjustment +- antd version: `>=5.0.0` +- MDN: [:where](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) +- Browser Compatibility: [caniuse](https://caniuse.com/?search=%3Awhere) +- Minimum Chrome Version Supported: 88 +- Default Enabled: Yes 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, you can use `@ant-design/cssinjs` to disable the default lowering of specificity (please ensure version consistency with antd). @@ -77,6 +64,12 @@ Raise priority through plugin: ## CSS Logical Properties +- antd version: `>=5.0.0` +- MDN:[CSS Logical Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) +- Browser Compatibility: [caniuse](https://caniuse.com/css-logical-props) +- Minimum Chrome Version Supported: 89 +- Default Enabled: Yes + To unify LTR and RTL styles, Ant Design uses CSS logical properties. For example, the original `margin-left` is replaced by `margin-inline-start`, so that it is the starting position spacing under both LTR and RTL. If you need to be compatible with older browsers, you can configure `transformers` through the `StyleProvider` of `@ant-design/cssinjs`: ```tsx @@ -102,6 +95,36 @@ When toggled, styles will downgrade CSS logical properties: } ``` +## `@layer` + +- antd version: `>=5.17.0` +- MDN:[CSS @layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) +- Browser Compatibility: [caniuse](https://caniuse.com/css-at-rule-layer) +- Minimum Chrome Version Supported: 99 +- Default Enabled: No + +Ant Design supports configuring `@layer` for unified css priority downgrade since `5.17.0`. After the downgrade, the style of antd will always be lower than the default CSS selector priority, so that users can override the style (please be sure to check the browser compatibility of `@layer`): + +```tsx +import { StyleProvider } from '@ant-design/cssinjs'; + +export default () => ( + + + +); +``` + +antd styles will be encapsulated in `@layer` to lower the priority: + +```diff +++ @layer antd { + :where(.css-bAMboO).ant-btn { + color: #fff; + } +++ } +``` + ## Rem Adaptation In responsive web development, there is a need for a convenient and flexible way to achieve page adaptation and responsive design. The `px2remTransformer` transformer can quickly and accurately convert pixel units in style sheets to rem units relative to the root element (HTML tag), enabling the implementation of adaptive and responsive layouts. diff --git a/docs/react/compatible-style.zh-CN.md b/docs/react/compatible-style.zh-CN.md index fd0b28e639..4f6567d848 100644 --- a/docs/react/compatible-style.zh-CN.md +++ b/docs/react/compatible-style.zh-CN.md @@ -5,38 +5,25 @@ order: 1 title: 样式兼容 --- -Ant Design 支持最近 2 个版本的现代浏览器。如果你需要兼容旧版浏览器,请根据实际需求进行降级处理: +## 默认样式兼容性说明 -## StyleProvider +Ant Design 5.x 支持[最近 2 个版本的现代浏览器](https://browsersl.ist/#q=defaults)。默认情况下,我们使用了一些现代 CSS 特性来提高样式的可维护性和可扩展性,这些特性在旧版浏览器中可能不被支持,好在我们可以通过一些降级兼容方案来解决。 -查看 [`@ant-design/cssinjs`](https://github.com/ant-design/cssinjs#styleprovider). +| 特性 | antd 版本 | 兼容性 | 最低 Chrome 版本 | 降级兼容方案 | +| --- | --- | --- | --- | --- | +| [:where 选择器](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) | `>=5.0.0` | [caniuse](https://caniuse.com/?search=%3Awhere) | Chrome 88 | `` | +| [CSS 逻辑属性](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties) | `>=5.0.0` | [caniuse](https://caniuse.com/css-logical-props) | Chrome 89 | `` | -## `layer` 降权 - -Ant Design 从 `5.17.0` 起支持配置 `layer` 进行统一降权。经过降权后,antd 的样式将始终低于默认的 CSS 选择器优先级,以便于用户进行样式覆盖(请务必注意检查 `@layer` 浏览器兼容性): - -```tsx -import { StyleProvider } from '@ant-design/cssinjs'; - -export default () => ( - - - -); -``` - -antd 的样式会被封装在 `@layer` 中,以降低优先级: - -```diff -++ @layer antd { - :where(.css-bAMboO).ant-btn { - color: #fff; - } -++ } -``` +如果你需要兼容旧版浏览器,请根据实际需求使用 [StyleProvider](https://github.com/ant-design/cssinjs#styleprovider) 降级处理。 ## `:where` 选择器 +- 支持版本:`>=5.0.0` +- MDN 文档:[:where](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) +- 浏览器兼容性:[caniuse](https://caniuse.com/?search=%3Awhere) +- Chrome 最低支持版本:88 +- 默认启用:是 + Ant Design 的 CSS-in-JS 默认通过 `:where` 选择器降低 CSS Selector 优先级,以减少用户升级时额外调整自定义样式的成本,不过 `:where` 语法的[兼容性](https://developer.mozilla.org/en-US/docs/Web/CSS/:where#browser_compatibility)在低版本浏览器比较差。在某些场景下你如果需要支持旧版浏览器,你可以使用 `@ant-design/cssinjs` 取消默认的降权操作(请注意版本保持与 antd 一致): ```tsx @@ -77,9 +64,15 @@ export default () => ( ## CSS 逻辑属性 +- 支持版本:`>=5.0.0` +- MDN 文档:[:where](https://developer.mozilla.org/en-US/docs/Web/CSS/:where) +- 浏览器兼容性:[caniuse](https://caniuse.com/css-logical-props) +- Chrome 最低支持版本:89 +- 默认启用:是 + 为了统一 LTR 和 RTL 样式,Ant Design 使用了 CSS 逻辑属性。例如原 `margin-left` 使用 `margin-inline-start` 代替,使其在 LTR 和 RTL 下都为起始位置间距。如果你需要兼容旧版浏览器(如 360 浏览器、QQ 浏览器 等等),可以通过 `@ant-design/cssinjs` 的 `StyleProvider` 配置 `transformers` 将其转换: -```tsx +```tsx | pure import { legacyLogicalPropertiesTransformer, StyleProvider } from '@ant-design/cssinjs'; // `transformers` 提供预处理功能将样式进行转换 @@ -102,11 +95,41 @@ export default () => ( } ``` +## `@layer` 样式优先级降权 + +- 支持版本:`>=5.17.0` +- MDN 文档:[@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) +- 浏览器兼容性:[caniuse](https://caniuse.com/?search=%40layer) +- Chrome 最低支持版本:99 +- 默认启用:否 + +Ant Design 从 `5.17.0` 起支持配置 `layer` 进行统一降权。经过降权后,antd 的样式将始终低于默认的 CSS 选择器优先级,以便于用户进行样式覆盖(请务必注意检查 `@layer` 浏览器兼容性): + +```tsx | pure +import { StyleProvider } from '@ant-design/cssinjs'; + +export default () => ( + + + +); +``` + +antd 的样式会被封装在 `@layer` 中,以降低优先级: + +```diff +++ @layer antd { + :where(.css-bAMboO).ant-btn { + color: #fff; + } +++ } +``` + ## rem 适配 在响应式网页开发中,需要一种方便且灵活的方式来实现页面的适配和响应式设计。`px2remTransformer` 转换器可以快速而准确地将样式表中的像素单位转换为相对于根元素(HTML 标签)的 rem 单位,实现页面的自适应和响应式布局。 -```tsx +```tsx | pure import { px2remTransformer, StyleProvider } from '@ant-design/cssinjs'; const px2rem = px2remTransformer({ diff --git a/package.json b/package.json index d5e1c2ea4a..cdd70ba521 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "5.20.2", + "version": "5.20.3", "description": "An enterprise-class UI design language and React components implementation", "keywords": [ "ant", @@ -340,11 +340,13 @@ "size-limit": [ { "path": "./dist/antd.min.js", - "limit": "350 KiB" + "limit": "500 KiB", + "gzip": true }, { "path": "./dist/antd-with-locales.min.js", - "limit": "400 KiB" + "limit": "500 KiB", + "gzip": true } ], "title": "Ant Design",