From ee3fb62f9b5df949a898eb96db7c7f6cf5daeb1b Mon Sep 17 00:00:00 2001 From: azro Date: Tue, 29 Nov 2022 21:18:27 +0100 Subject: [PATCH 01/20] Add XXXL size --- components/_util/responsiveObserve.ts | 5 +-- components/avatar/__tests__/Avatar.test.tsx | 2 +- .../__snapshots__/Avatar.test.tsx.snap | 14 ++++++++ components/avatar/avatar.tsx | 2 +- components/avatar/demo/responsive.tsx | 2 +- components/descriptions/demo/responsive.tsx | 2 +- components/descriptions/index.tsx | 1 + components/grid/__tests__/index.test.tsx | 1 + components/grid/col.tsx | 3 +- components/grid/demo/responsive-more.md | 4 +-- components/grid/demo/responsive.md | 4 +-- components/grid/index.en-US.md | 33 ++++++++++--------- components/grid/index.zh-CN.md | 33 ++++++++++--------- components/grid/row.tsx | 4 ++- components/grid/style/index.tsx | 1 + components/layout/Sider.tsx | 3 +- components/layout/index.en-US.md | 3 +- components/layout/index.zh-CN.md | 3 +- components/list/demo/responsive.tsx | 1 + components/list/index.en-US.md | 1 + components/list/index.tsx | 5 +-- components/list/index.zh-CN.md | 1 + components/theme/interface.ts | 4 +++ .../themes/compact/genCompactSizeMapToken.ts | 1 + .../theme/themes/shared/genSizeMapToken.ts | 1 + components/theme/util/alias.ts | 4 +++ 26 files changed, 89 insertions(+), 49 deletions(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 9de911fe62d4..d21573c55e90 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,9 +1,9 @@ -export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; +export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type BreakpointMap = Record; export type ScreenMap = Partial>; export type ScreenSizeMap = Partial>; -export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; +export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs']; export const responsiveMap: BreakpointMap = { xs: '(max-width: 575px)', @@ -12,6 +12,7 @@ export const responsiveMap: BreakpointMap = { lg: '(min-width: 992px)', xl: '(min-width: 1200px)', xxl: '(min-width: 1600px)', + xxxl: '(min-width: 2000px)', }; type SubscribeFunc = (screens: ScreenMap) => void; diff --git a/components/avatar/__tests__/Avatar.test.tsx b/components/avatar/__tests__/Avatar.test.tsx index 13b36249861d..6012d0a57942 100644 --- a/components/avatar/__tests__/Avatar.test.tsx +++ b/components/avatar/__tests__/Avatar.test.tsx @@ -13,7 +13,7 @@ describe('Avatar Render', () => { mountTest(Avatar); rtlTest(Avatar); - const sizes = { xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }; + const sizes = { xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100, xxxl: 120 }; let originOffsetWidth: PropertyDescriptor['get']; beforeAll(() => { // Mock offsetHeight diff --git a/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap b/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap index 80dce08eba7f..a8eba4b5f7c7 100644 --- a/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap +++ b/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap @@ -84,6 +84,20 @@ exports[`Avatar Render adjusts component size to 100 when window size is xxl 1`] `; +exports[`Avatar Render adjusts component size to 120 when window size is xxxl 1`] = ` +
+ + + +
+`; + exports[`Avatar Render fallback 1`] = ` - ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key), + ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].includes(key), ); const screens = useBreakpoint(needResponsive); const responsiveSizeStyle: React.CSSProperties = React.useMemo(() => { diff --git a/components/avatar/demo/responsive.tsx b/components/avatar/demo/responsive.tsx index e4d0b02736e8..3583061fc610 100644 --- a/components/avatar/demo/responsive.tsx +++ b/components/avatar/demo/responsive.tsx @@ -4,7 +4,7 @@ import { Avatar } from 'antd'; const App: React.FC = () => ( } /> ); diff --git a/components/descriptions/demo/responsive.tsx b/components/descriptions/demo/responsive.tsx index ffd50c7959bc..af516d1040bf 100644 --- a/components/descriptions/demo/responsive.tsx +++ b/components/descriptions/demo/responsive.tsx @@ -6,7 +6,7 @@ const App: React.FC = () => ( Cloud Database Prepaid diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index 92f90fa1d44f..6b045afb7c01 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -20,6 +20,7 @@ export interface DescriptionsContextProps { export const DescriptionsContext = React.createContext({}); const DEFAULT_COLUMN_MAP: Record = { + xxxl: 4, xxl: 3, xl: 3, lg: 3, diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index 3bbe53e44f47..38e3a3fd2da8 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -141,6 +141,7 @@ describe('Grid', () => { lg: false, xl: false, xxl: false, + xxxl: false, }); }); diff --git a/components/grid/col.tsx b/components/grid/col.tsx index 4205b48007c5..9da53814f03b 100644 --- a/components/grid/col.tsx +++ b/components/grid/col.tsx @@ -31,6 +31,7 @@ export interface ColProps extends React.HTMLAttributes { lg?: ColSpanType | ColSize; xl?: ColSpanType | ColSize; xxl?: ColSpanType | ColSize; + xxxl?: ColSpanType | ColSize; prefixCls?: string; } @@ -45,7 +46,7 @@ function parseFlex(flex: FlexType): string { return flex; } -const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const; +const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'] as const; const Col = React.forwardRef((props, ref) => { const { getPrefixCls, direction } = React.useContext(ConfigContext); const { gutter, wrap, supportFlexGap } = React.useContext(RowContext); diff --git a/components/grid/demo/responsive-more.md b/components/grid/demo/responsive-more.md index 9c66c22cfb17..f433ad391dfd 100644 --- a/components/grid/demo/responsive-more.md +++ b/components/grid/demo/responsive-more.md @@ -1,9 +1,9 @@ ## zh-CN -`span` `pull` `push` `offset` `order` 属性可以通过内嵌到 `xs` `sm` `md` `lg` `xl` `xxl` 属性中来使用。 +`span` `pull` `push` `offset` `order` 属性可以通过内嵌到 `xs` `sm` `md` `lg` `xl` `xxl` `xxxl` 属性中来使用。 其中 `xs={6}` 相当于 `xs={{ span: 6 }}`。 ## en-US -`span` `pull` `push` `offset` `order` property can be embedded into `xs` `sm` `md` `lg` `xl` `xxl` properties to use, where `xs={6}` is equivalent to `xs={{span: 6}}`. +`span` `pull` `push` `offset` `order` property can be embedded into `xs` `sm` `md` `lg` `xl` `xxl` `xxxl` properties to use, where `xs={6}` is equivalent to `xs={{span: 6}}`. diff --git a/components/grid/demo/responsive.md b/components/grid/demo/responsive.md index 76646cabdb8c..208aaeaea22d 100644 --- a/components/grid/demo/responsive.md +++ b/components/grid/demo/responsive.md @@ -1,7 +1,7 @@ ## zh-CN -参照 Bootstrap 的 [响应式设计](http://getbootstrap.com/css/#grid-media-queries),预设六个响应尺寸:`xs` `sm` `md` `lg` `xl` `xxl`。 +参照 Bootstrap 的 [响应式设计](http://getbootstrap.com/css/#grid-media-queries),预设七个响应尺寸:`xs` `sm` `md` `lg` `xl` `xxl` `xxxl`。 ## en-US -Referring to the Bootstrap [responsive design](http://getbootstrap.com/css/#grid-media-queries), here preset six dimensions: `xs` `sm` `md` `lg` `xl` `xxl`. +Referring to the Bootstrap [responsive design](http://getbootstrap.com/css/#grid-media-queries), here preset seven dimensions: `xs` `sm` `md` `lg` `xl` `xxl` `xxxl`. diff --git a/components/grid/index.en-US.md b/components/grid/index.en-US.md index 6e3aefcca8e0..f583129073ea 100644 --- a/components/grid/index.en-US.md +++ b/components/grid/index.en-US.md @@ -59,27 +59,28 @@ If the Ant Design grid layout component does not meet your needs, you can use th | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| align | Vertical alignment | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | +| align | Vertical alignment | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | | gutter | Spacing between grids, could be a number or a object like { xs: 8, sm: 16, md: 24}. Or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` | number \| object \| array | 0 | | -| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | +| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | | wrap | Auto wrap line | boolean | true | 4.8.0 | ### Col -| Property | Description | Type | Default | Version | -| --- | --- | --- | --- | --- | -| flex | Flex layout style | string \| number | - | | -| offset | The number of cells to offset Col from the left | number | 0 | | -| order | Raster order | number | 0 | | -| pull | The number of cells that raster is moved to the left | number | 0 | | -| push | The number of cells that raster is moved to the right | number | 0 | | -| span | Raster number of cells to occupy, 0 corresponds to `display: none` | number | none | | -| xs | `screen < 576px` and also default setting, could be a `span` value or an object containing above props | number \| object | - | | -| sm | `screen ≥ 576px`, could be a `span` value or an object containing above props | number \| object | - | | -| md | `screen ≥ 768px`, could be a `span` value or an object containing above props | number \| object | - | | -| lg | `screen ≥ 992px`, could be a `span` value or an object containing above props | number \| object | - | | -| xl | `screen ≥ 1200px`, could be a `span` value or an object containing above props | number \| object | - | | -| xxl | `screen ≥ 1600px`, could be a `span` value or an object containing above props | number \| object | - | | +| Property | Description | Type | Default | Version | +|----------|-------------------------------------------------------------------------------------------------------| --- | --- | --- | +| flex | Flex layout style | string \| number | - | | +| offset | The number of cells to offset Col from the left | number | 0 | | +| order | Raster order | number | 0 | | +| pull | The number of cells that raster is moved to the left | number | 0 | | +| push | The number of cells that raster is moved to the right | number | 0 | | +| span | Raster number of cells to occupy, 0 corresponds to `display: none` | number | none | | +| xs | `screen < 576px` and also default setting, could be a `span` value or an object containing above props | number \| object | - | | +| sm | `screen ≥ 576px`, could be a `span` value or an object containing above props | number \| object | - | | +| md | `screen ≥ 768px`, could be a `span` value or an object containing above props | number \| object | - | | +| lg | `screen ≥ 992px`, could be a `span` value or an object containing above props | number \| object | - | | +| xl | `screen ≥ 1200px`, could be a `span` value or an object containing above props | number \| object | - | | +| xxl | `screen ≥ 1600px`, could be a `span` value or an object containing above props | number \| object | - | | +| xxxl | `screen ≥ 2000px`, could be a `span` value or an object containing above props | number \| object | - | 5.0.x | The breakpoints of responsive grid follow [BootStrap 4 media queries rules](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints) (not including `occasionally part`). diff --git a/components/grid/index.zh-CN.md b/components/grid/index.zh-CN.md index 00e0806a04e5..3691120027b2 100644 --- a/components/grid/index.zh-CN.md +++ b/components/grid/index.zh-CN.md @@ -58,27 +58,28 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用 | 成员 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| align | 垂直对齐方式 | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | +| align | 垂直对齐方式 | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | | gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 { xs: 8, sm: 16, md: 24}。或者使用数组形式同时设置 `[水平间距, 垂直间距]` | number \| object \| array | 0 | | -| justify | 水平排列方式 | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | +| justify | 水平排列方式 | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | | wrap | 是否自动换行 | boolean | true | 4.8.0 | ### Col -| 成员 | 说明 | 类型 | 默认值 | 版本 | -| --- | --- | --- | --- | --- | -| flex | flex 布局属性 | string \| number | - | | -| offset | 栅格左侧的间隔格数,间隔内不可以有栅格 | number | 0 | | -| order | 栅格顺序 | number | 0 | | -| pull | 栅格向左移动格数 | number | 0 | | -| push | 栅格向右移动格数 | number | 0 | | -| span | 栅格占位格数,为 0 时相当于 `display: none` | number | - | | -| xs | `屏幕 < 576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| sm | `屏幕 ≥ 576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| md | `屏幕 ≥ 768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| lg | `屏幕 ≥ 992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| xl | `屏幕 ≥ 1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| xxl | `屏幕 ≥ 1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| 成员 | 说明 | 类型 | 默认值 | 版本 | +|--------|---------------------------------------| --- | --- | --- | +| flex | flex 布局属性 | string \| number | - | | +| offset | 栅格左侧的间隔格数,间隔内不可以有栅格 | number | 0 | | +| order | 栅格顺序 | number | 0 | | +| pull | 栅格向左移动格数 | number | 0 | | +| push | 栅格向右移动格数 | number | 0 | | +| span | 栅格占位格数,为 0 时相当于 `display: none` | number | - | | +| xs | `屏幕 < 576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| sm | `屏幕 ≥ 576px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| md | `屏幕 ≥ 768px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| lg | `屏幕 ≥ 992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| xl | `屏幕 ≥ 1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| xxl | `屏幕 ≥ 1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | +| xxxl | `屏幕 ≥ 2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | 5.0.x | 响应式栅格的断点扩展自 [BootStrap 4 的规则](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints)(不包含链接里 `occasionally` 的部分)。 diff --git a/components/grid/row.tsx b/components/grid/row.tsx index fc458815d8fb..d7bbda9815cf 100644 --- a/components/grid/row.tsx +++ b/components/grid/row.tsx @@ -11,7 +11,7 @@ import { useRowStyle } from './style'; const RowAligns = tuple('top', 'middle', 'bottom', 'stretch'); const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between', 'space-evenly'); -type Responsive = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; +type Responsive = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; type ResponsiveLike = { [key in Responsive]?: T; }; @@ -77,6 +77,7 @@ const Row = React.forwardRef((props, ref) => { lg: true, xl: true, xxl: true, + xxxl: true, }); // to save screens info when responsiveObserve callback had been call const [curScreens, setCurScreens] = React.useState({ @@ -86,6 +87,7 @@ const Row = React.forwardRef((props, ref) => { lg: false, xl: false, xxl: false, + xxxl: false, }); // ================================== calc reponsive data ================================== diff --git a/components/grid/style/index.tsx b/components/grid/style/index.tsx index afff2bb91c1d..287ef35fe7b4 100644 --- a/components/grid/style/index.tsx +++ b/components/grid/style/index.tsx @@ -160,6 +160,7 @@ export const useColStyle = genComponentStyleHook('Grid', (token) => { '-lg': gridToken.screenLGMin, '-xl': gridToken.screenXLMin, '-xxl': gridToken.screenXXLMin, + '-xxxl': gridToken.screenXXXLMin, }; return [ diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index 4df4f05478c1..cedcf1129679 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -17,6 +17,7 @@ const dimensionMaxMap = { lg: '991.98px', xl: '1199.98px', xxl: '1599.98px', + xxxl: '1999.98px', }; export interface SiderContextProps { @@ -40,7 +41,7 @@ export interface SiderProps extends React.HTMLAttributes { trigger?: React.ReactNode; width?: number | string; collapsedWidth?: number | string; - breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; + breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl'; theme?: SiderTheme; onBreakpoint?: (broken: boolean) => void; } diff --git a/components/layout/index.en-US.md b/components/layout/index.en-US.md index c06f12eef377..01819563253e 100644 --- a/components/layout/index.en-US.md +++ b/components/layout/index.en-US.md @@ -99,7 +99,7 @@ The sidebar. | Property | Description | Type | Default | | --- | --- | --- | --- | -| breakpoint | [Breakpoints](/components/grid/#Col) of the responsive layout | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` | - | +| breakpoint | [Breakpoints](/components/grid/#Col) of the responsive layout | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` \| `xxxl` | - | | className | Container className | string | - | | collapsed | To set the current status | boolean | - | | collapsedWidth | Width of the collapsed sidebar, by setting to 0 a special trigger will appear | number | 80 | @@ -124,6 +124,7 @@ The sidebar. lg: '992px', xl: '1200px', xxl: '1600px', + xxxl: '2000px', } ``` diff --git a/components/layout/index.zh-CN.md b/components/layout/index.zh-CN.md index 92ccdc6a4c32..608f135f2edf 100644 --- a/components/layout/index.zh-CN.md +++ b/components/layout/index.zh-CN.md @@ -100,7 +100,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/hzEndUVEx/Layout.svg | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| breakpoint | 触发响应式布局的[断点](/components/grid/#Col) | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` | - | +| breakpoint | 触发响应式布局的[断点](/components/grid/#Col) | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` \| `xxxl` | - | | className | 容器 className | string | - | | collapsed | 当前收起状态 | boolean | - | | collapsedWidth | 收缩宽度,设置为 0 会出现特殊 trigger | number | 80 | @@ -125,6 +125,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/hzEndUVEx/Layout.svg lg: '992px', xl: '1200px', xxl: '1600px', + xxxl: '2000px', } ``` diff --git a/components/list/demo/responsive.tsx b/components/list/demo/responsive.tsx index a0fb07f085de..8b9432b2e83d 100644 --- a/components/list/demo/responsive.tsx +++ b/components/list/demo/responsive.tsx @@ -32,6 +32,7 @@ const App: React.FC = () => ( lg: 4, xl: 6, xxl: 3, + xxxl: 2, }} dataSource={data} renderItem={(item) => ( diff --git a/components/list/index.en-US.md b/components/list/index.en-US.md index dbad66a3de1e..e8ffc3cb9e5b 100644 --- a/components/list/index.en-US.md +++ b/components/list/index.en-US.md @@ -69,6 +69,7 @@ More about pagination, please check [`Pagination`](/components/pagination/). | lg | `≥992px` column of grid | number | - | | | xl | `≥1200px` column of grid | number | - | | | xxl | `≥1600px` column of grid | number | - | | +| xxxl | `≥2000px` column of grid | number | - | 5.0.x | ### List.Item diff --git a/components/list/index.tsx b/components/list/index.tsx index 0c80c34224d4..89d3f622b9a6 100644 --- a/components/list/index.tsx +++ b/components/list/index.tsx @@ -21,7 +21,7 @@ export type { ListItemMetaProps, ListItemProps } from './Item'; export type ColumnCount = number; -export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; +export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl'; export interface ListGridType { gutter?: number; @@ -32,6 +32,7 @@ export interface ListGridType { lg?: ColumnCount; xl?: ColumnCount; xxl?: ColumnCount; + xxxl?: ColumnCount; } export type ListSize = 'small' | 'default' | 'large'; @@ -223,7 +224,7 @@ function List({ } const needResponsive = Object.keys(grid || {}).some((key) => - ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key), + ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].includes(key), ); const screens = useBreakpoint(needResponsive); const currentBreakpoint = React.useMemo(() => { diff --git a/components/list/index.zh-CN.md b/components/list/index.zh-CN.md index d5d5f3be2899..1fbd638bdbc6 100644 --- a/components/list/index.zh-CN.md +++ b/components/list/index.zh-CN.md @@ -70,6 +70,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5FrZKStG_/List.svg | lg | `≥992px` 展示的列数 | number | - | | | xl | `≥1200px` 展示的列数 | number | - | | | xxl | `≥1600px` 展示的列数 | number | - | | +| xxxl | `≥2000px` 展示的列数 of grid | number | - | 5.0.x | ### List.Item diff --git a/components/theme/interface.ts b/components/theme/interface.ts index 444973f59d74..59757e2b3c5c 100644 --- a/components/theme/interface.ts +++ b/components/theme/interface.ts @@ -654,6 +654,7 @@ export interface ColorMapToken extends NeutralColorMapToken { export interface SizeMapToken { // Size + sizeXXXL: number; sizeXXL: number; sizeXL: number; sizeLG: number; @@ -847,6 +848,9 @@ export interface AliasToken extends MapToken { screenXXL: number; screenXXLMin: number; screenXXLMax: number; + screenXXXL: number; + screenXXXLMin: number; + screenXXXLMax: number; /** Used for DefaultButton, Switch which has default outline */ controlTmpOutline: string; diff --git a/components/theme/themes/compact/genCompactSizeMapToken.ts b/components/theme/themes/compact/genCompactSizeMapToken.ts index b473808eca0f..5d383a84169c 100644 --- a/components/theme/themes/compact/genCompactSizeMapToken.ts +++ b/components/theme/themes/compact/genCompactSizeMapToken.ts @@ -6,6 +6,7 @@ export default function genSizeMapToken(token: SeedToken): SizeMapToken { const compactSizeStep = sizeStep - 2; return { + sizeXXXL: sizeUnit * (compactSizeStep + 14), sizeXXL: sizeUnit * (compactSizeStep + 10), sizeXL: sizeUnit * (compactSizeStep + 6), sizeLG: sizeUnit * (compactSizeStep + 2), diff --git a/components/theme/themes/shared/genSizeMapToken.ts b/components/theme/themes/shared/genSizeMapToken.ts index 3449c24dfe22..a644fb31ed77 100644 --- a/components/theme/themes/shared/genSizeMapToken.ts +++ b/components/theme/themes/shared/genSizeMapToken.ts @@ -4,6 +4,7 @@ export default function genSizeMapToken(token: SeedToken): SizeMapToken { const { sizeUnit, sizeStep } = token; return { + sizeXXXL: sizeUnit * (sizeStep + 16), // 80 sizeXXL: sizeUnit * (sizeStep + 8), // 48 sizeXL: sizeUnit * (sizeStep + 4), // 32 sizeLG: sizeUnit * (sizeStep + 2), // 24 diff --git a/components/theme/util/alias.ts b/components/theme/util/alias.ts index 33d54307c53b..0bb1a6117ee3 100644 --- a/components/theme/util/alias.ts +++ b/components/theme/util/alias.ts @@ -31,6 +31,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken const screenLG = 992; const screenXL = 1200; const screenXXL = 1600; + const screenXXXL = 2000; const fontSizeSM = fontSizes[0]; @@ -174,6 +175,9 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken screenXXL, screenXXLMin: screenXXL, screenXXLMax: screenXXL - 1, + screenXXXL, + screenXXXLMin: screenXXXL, + screenXXXLMax: screenXXXL - 1, // FIXME: component box-shadow, should be removed boxShadowPopoverArrow: `3px 3px 7px rgba(0, 0, 0, 0.1)`, From 3d42ce9e4be8096264981c49b025788eaf3bcebf Mon Sep 17 00:00:00 2001 From: azro352 <35503478+azro352@users.noreply.github.com> Date: Wed, 30 Nov 2022 09:41:31 +0100 Subject: [PATCH 02/20] Update index.zh-CN.md --- components/list/index.zh-CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/list/index.zh-CN.md b/components/list/index.zh-CN.md index 1fbd638bdbc6..62d6d245774a 100644 --- a/components/list/index.zh-CN.md +++ b/components/list/index.zh-CN.md @@ -70,7 +70,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5FrZKStG_/List.svg | lg | `≥992px` 展示的列数 | number | - | | | xl | `≥1200px` 展示的列数 | number | - | | | xxl | `≥1600px` 展示的列数 | number | - | | -| xxxl | `≥2000px` 展示的列数 of grid | number | - | 5.0.x | +| xxxl | `≥2000px` 展示的列数 | number | - | 5.0.x | ### List.Item From 00ffde21220408fa56956b9ff077f1c26fb18287 Mon Sep 17 00:00:00 2001 From: azro352 <35503478+azro352@users.noreply.github.com> Date: Wed, 30 Nov 2022 09:49:38 +0100 Subject: [PATCH 03/20] Update components/list/index.zh-CN.md Co-authored-by: Amumu --- components/grid/index.en-US.md | 2 +- components/grid/index.zh-CN.md | 2 +- components/list/index.en-US.md | 2 +- components/list/index.zh-CN.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/grid/index.en-US.md b/components/grid/index.en-US.md index f583129073ea..b1204c3b2d41 100644 --- a/components/grid/index.en-US.md +++ b/components/grid/index.en-US.md @@ -80,7 +80,7 @@ If the Ant Design grid layout component does not meet your needs, you can use th | lg | `screen ≥ 992px`, could be a `span` value or an object containing above props | number \| object | - | | | xl | `screen ≥ 1200px`, could be a `span` value or an object containing above props | number \| object | - | | | xxl | `screen ≥ 1600px`, could be a `span` value or an object containing above props | number \| object | - | | -| xxxl | `screen ≥ 2000px`, could be a `span` value or an object containing above props | number \| object | - | 5.0.x | +| xxxl | `screen ≥ 2000px`, could be a `span` value or an object containing above props | number \| object | - | 5.1.0 | The breakpoints of responsive grid follow [BootStrap 4 media queries rules](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints) (not including `occasionally part`). diff --git a/components/grid/index.zh-CN.md b/components/grid/index.zh-CN.md index 3691120027b2..cd56dacc0932 100644 --- a/components/grid/index.zh-CN.md +++ b/components/grid/index.zh-CN.md @@ -79,7 +79,7 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用 | lg | `屏幕 ≥ 992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | | xl | `屏幕 ≥ 1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | | xxl | `屏幕 ≥ 1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| xxxl | `屏幕 ≥ 2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | 5.0.x | +| xxxl | `屏幕 ≥ 2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | 5.1.0 | 响应式栅格的断点扩展自 [BootStrap 4 的规则](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints)(不包含链接里 `occasionally` 的部分)。 diff --git a/components/list/index.en-US.md b/components/list/index.en-US.md index e8ffc3cb9e5b..dca4b59a4a4d 100644 --- a/components/list/index.en-US.md +++ b/components/list/index.en-US.md @@ -69,7 +69,7 @@ More about pagination, please check [`Pagination`](/components/pagination/). | lg | `≥992px` column of grid | number | - | | | xl | `≥1200px` column of grid | number | - | | | xxl | `≥1600px` column of grid | number | - | | -| xxxl | `≥2000px` column of grid | number | - | 5.0.x | +| xxxl | `≥2000px` column of grid | number | - | 5.1.0 | ### List.Item diff --git a/components/list/index.zh-CN.md b/components/list/index.zh-CN.md index 62d6d245774a..bd51cab02558 100644 --- a/components/list/index.zh-CN.md +++ b/components/list/index.zh-CN.md @@ -70,7 +70,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5FrZKStG_/List.svg | lg | `≥992px` 展示的列数 | number | - | | | xl | `≥1200px` 展示的列数 | number | - | | | xxl | `≥1600px` 展示的列数 | number | - | | -| xxxl | `≥2000px` 展示的列数 | number | - | 5.0.x | +| xxxl | `≥2000px` 展示的列数 | number | - | 5.1.0 | ### List.Item From 09257b863ae1bd3005a11b5452791fb0c50c7eb4 Mon Sep 17 00:00:00 2001 From: azro Date: Thu, 1 Dec 2022 11:56:05 +0100 Subject: [PATCH 04/20] Try to use `useToken` for building responsiveMap --- .../_util/__tests__/responsiveObserve.test.ts | 4 ++-- components/_util/responsiveObserve.ts | 23 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/components/_util/__tests__/responsiveObserve.test.ts b/components/_util/__tests__/responsiveObserve.test.ts index 6ab86ec802ea..27bc6694b380 100644 --- a/components/_util/__tests__/responsiveObserve.test.ts +++ b/components/_util/__tests__/responsiveObserve.test.ts @@ -1,8 +1,8 @@ -import ResponsiveObserve, { responsiveMap } from '../responsiveObserve'; +import ResponsiveObserve, { useResponsiveMap } from '../responsiveObserve'; describe('Test ResponsiveObserve', () => { it('test ResponsiveObserve subscribe and unsubscribe', () => { - const { xs } = responsiveMap; + const { xs } = useResponsiveMap(); const subscribeFunc = jest.fn(); const token = ResponsiveObserve.subscribe(subscribeFunc); expect(ResponsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index d21573c55e90..86d5856d328a 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,3 +1,5 @@ +import { useToken } from '../theme/internal'; + export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type BreakpointMap = Record; export type ScreenMap = Partial>; @@ -5,14 +7,17 @@ export type ScreenSizeMap = Partial>; export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs']; -export const responsiveMap: BreakpointMap = { - xs: '(max-width: 575px)', - sm: '(min-width: 576px)', - md: '(min-width: 768px)', - lg: '(min-width: 992px)', - xl: '(min-width: 1200px)', - xxl: '(min-width: 1600px)', - xxxl: '(min-width: 2000px)', +const useResponsiveMap = (): BreakpointMap => { + const [, token] = useToken(); + return { + xs: `(max-width: ${token.screenXS}px)`, + sm: `(max-width: ${token.screenSM}px)`, + md: `(max-width: ${token.screenMD}px)`, + lg: `(max-width: ${token.screenLG}px)`, + xl: `(max-width: ${token.screenXL}px)`, + xxl: `(max-width: ${token.screenXXL}px)`, + xxxl: `(max-width: ${token.screenXXXL}px)`, + } as BreakpointMap; }; type SubscribeFunc = (screens: ScreenMap) => void; @@ -44,6 +49,7 @@ const responsiveObserve = { if (!subscribers.size) this.unregister(); }, unregister() { + const responsiveMap: BreakpointMap = useResponsiveMap(); Object.keys(responsiveMap).forEach((screen: Breakpoint) => { const matchMediaQuery = responsiveMap[screen]; const handler = this.matchHandlers[matchMediaQuery]; @@ -52,6 +58,7 @@ const responsiveObserve = { subscribers.clear(); }, register() { + const responsiveMap: BreakpointMap = useResponsiveMap(); Object.keys(responsiveMap).forEach((screen: Breakpoint) => { const matchMediaQuery = responsiveMap[screen]; const listener = ({ matches }: { matches: boolean }) => { From dd4a04ba8686bc60835d75ef4c81c7798dcba522 Mon Sep 17 00:00:00 2001 From: azro Date: Fri, 2 Dec 2022 12:09:16 +0100 Subject: [PATCH 05/20] Try useResponsiveObserve --- .../_util/__tests__/responsiveObserve.test.ts | 13 +- components/_util/responsiveObserve.ts | 129 +++++++++--------- components/descriptions/index.tsx | 7 +- components/grid/__tests__/index.test.tsx | 8 +- components/grid/hooks/useBreakpoint.tsx | 7 +- components/grid/row.tsx | 7 +- 6 files changed, 88 insertions(+), 83 deletions(-) diff --git a/components/_util/__tests__/responsiveObserve.test.ts b/components/_util/__tests__/responsiveObserve.test.ts index 27bc6694b380..1857924b7f2b 100644 --- a/components/_util/__tests__/responsiveObserve.test.ts +++ b/components/_util/__tests__/responsiveObserve.test.ts @@ -1,14 +1,15 @@ -import ResponsiveObserve, { useResponsiveMap } from '../responsiveObserve'; +import useResponsiveObserve from '../responsiveObserve'; describe('Test ResponsiveObserve', () => { it('test ResponsiveObserve subscribe and unsubscribe', () => { - const { xs } = useResponsiveMap(); + const reponsiveObserve = useResponsiveObserve(); + const { xs } = reponsiveObserve.responsiveMap; const subscribeFunc = jest.fn(); - const token = ResponsiveObserve.subscribe(subscribeFunc); - expect(ResponsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); + const token = reponsiveObserve.subscribe(subscribeFunc); + expect(reponsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); expect(subscribeFunc).toHaveBeenCalledTimes(1); - ResponsiveObserve.unsubscribe(token); - expect(ResponsiveObserve.matchHandlers[xs].mql.removeListener).toHaveBeenCalled(); + reponsiveObserve.unsubscribe(token); + expect(reponsiveObserve.matchHandlers[xs].mql.removeListener).toHaveBeenCalled(); }); }); diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 86d5856d328a..56d3b2b3234a 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,3 +1,4 @@ +import { GlobalToken } from '../theme/interface'; import { useToken } from '../theme/internal'; export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; @@ -7,76 +8,74 @@ export type ScreenSizeMap = Partial>; export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs']; -const useResponsiveMap = (): BreakpointMap => { - const [, token] = useToken(); - return { - xs: `(max-width: ${token.screenXS}px)`, - sm: `(max-width: ${token.screenSM}px)`, - md: `(max-width: ${token.screenMD}px)`, - lg: `(max-width: ${token.screenLG}px)`, - xl: `(max-width: ${token.screenXL}px)`, - xxl: `(max-width: ${token.screenXXL}px)`, - xxxl: `(max-width: ${token.screenXXXL}px)`, - } as BreakpointMap; -}; +const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ + xs: `(max-width: ${token.screenXS}px)`, + sm: `(max-width: ${token.screenSM}px)`, + md: `(max-width: ${token.screenMD}px)`, + lg: `(max-width: ${token.screenLG}px)`, + xl: `(max-width: ${token.screenXL}px)`, + xxl: `(max-width: ${token.screenXXL}px)`, + xxxl: `(max-width: ${token.screenXXXL}px)`, +}); type SubscribeFunc = (screens: ScreenMap) => void; const subscribers = new Map(); let subUid = -1; let screens = {}; -const responsiveObserve = { - matchHandlers: {} as { - [prop: string]: { - mql: MediaQueryList; - listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; - }; - }, - dispatch(pointMap: ScreenMap) { - screens = pointMap; - subscribers.forEach((func) => func(screens)); - return subscribers.size >= 1; - }, - subscribe(func: SubscribeFunc): number { - if (!subscribers.size) this.register(); - subUid += 1; - subscribers.set(subUid, func); - func(screens); - return subUid; - }, - unsubscribe(token: number) { - subscribers.delete(token); - if (!subscribers.size) this.unregister(); - }, - unregister() { - const responsiveMap: BreakpointMap = useResponsiveMap(); - Object.keys(responsiveMap).forEach((screen: Breakpoint) => { - const matchMediaQuery = responsiveMap[screen]; - const handler = this.matchHandlers[matchMediaQuery]; - handler?.mql.removeListener(handler?.listener); - }); - subscribers.clear(); - }, - register() { - const responsiveMap: BreakpointMap = useResponsiveMap(); - Object.keys(responsiveMap).forEach((screen: Breakpoint) => { - const matchMediaQuery = responsiveMap[screen]; - const listener = ({ matches }: { matches: boolean }) => { - this.dispatch({ - ...screens, - [screen]: matches, - }); - }; - const mql = window.matchMedia(matchMediaQuery); - mql.addListener(listener); - this.matchHandlers[matchMediaQuery] = { - mql, - listener, +export default function useResponsiveObserve() { + const [, token] = useToken(); + const responsiveMap: BreakpointMap = getResponsiveMap(token); + return { + matchHandlers: {} as { + [prop: string]: { + mql: MediaQueryList; + listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; }; + }, + dispatch(pointMap: ScreenMap) { + screens = pointMap; + subscribers.forEach((func) => func(screens)); + return subscribers.size >= 1; + }, + subscribe(func: SubscribeFunc): number { + if (!subscribers.size) this.register(); + subUid += 1; + subscribers.set(subUid, func); + func(screens); + return subUid; + }, + unsubscribe(token: number) { + subscribers.delete(token); + if (!subscribers.size) this.unregister(); + }, + unregister() { + Object.keys(responsiveMap).forEach((screen: Breakpoint) => { + const matchMediaQuery = responsiveMap[screen]; + const handler = this.matchHandlers[matchMediaQuery]; + handler?.mql.removeListener(handler?.listener); + }); + subscribers.clear(); + }, + register() { + Object.keys(responsiveMap).forEach((screen: Breakpoint) => { + const matchMediaQuery = responsiveMap[screen]; + const listener = ({ matches }: { matches: boolean }) => { + this.dispatch({ + ...screens, + [screen]: matches, + }); + }; + const mql = window.matchMedia(matchMediaQuery); + mql.addListener(listener); + this.matchHandlers[matchMediaQuery] = { + mql, + listener, + }; - listener(mql); - }); - }, -}; - -export default responsiveObserve; + listener(mql); + }); + }, + responsiveMap, + }; +} diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index 6b045afb7c01..abab35a43fc6 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { ConfigContext } from '../config-provider'; import { cloneElement } from '../_util/reactNode'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve'; -import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; +import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; import warning from '../_util/warning'; import DescriptionsItem from './Item'; import Row from './Row'; @@ -139,7 +139,8 @@ function Descriptions({ // Responsive React.useEffect(() => { - const token = ResponsiveObserve.subscribe((newScreens) => { + const responsiveObserve = useResponsiveObserve(); + const token = responsiveObserve.subscribe((newScreens) => { if (typeof column !== 'object') { return; } @@ -147,7 +148,7 @@ function Descriptions({ }); return () => { - ResponsiveObserve.unsubscribe(token); + responsiveObserve.unsubscribe(token); }; }, []); diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index 38e3a3fd2da8..6b70ca026e2b 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Col, Row } from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import ResponsiveObserve from '../../_util/responsiveObserve'; +import useResponsiveObserve from '../../_util/responsiveObserve'; import useBreakpoint from '../hooks/useBreakpoint'; import { render, act } from '../../../tests/utils'; @@ -14,7 +14,8 @@ describe('Grid', () => { rtlTest(Col); afterEach(() => { - ResponsiveObserve.unregister(); + const responsiveObserve = useResponsiveObserve(); + responsiveObserve.unregister(); }); it('should render Col', () => { @@ -89,7 +90,8 @@ describe('Grid', () => { }); it('ResponsiveObserve.unsubscribe should be called when unmounted', () => { - const Unmount = jest.spyOn(ResponsiveObserve, 'unsubscribe'); + const responsiveObserve = useResponsiveObserve(); + const Unmount = jest.spyOn(responsiveObserve, 'unsubscribe'); const { unmount } = render(); act(() => { unmount(); diff --git a/components/grid/hooks/useBreakpoint.tsx b/components/grid/hooks/useBreakpoint.tsx index 0435b198b81b..869133f8d542 100644 --- a/components/grid/hooks/useBreakpoint.tsx +++ b/components/grid/hooks/useBreakpoint.tsx @@ -1,21 +1,22 @@ import { useEffect, useRef } from 'react'; import useForceUpdate from '../../_util/hooks/useForceUpdate'; import type { ScreenMap } from '../../_util/responsiveObserve'; -import ResponsiveObserve from '../../_util/responsiveObserve'; +import useResponsiveObserve from '../../_util/responsiveObserve'; function useBreakpoint(refreshOnChange: boolean = true): ScreenMap { const screensRef = useRef({}); const forceUpdate = useForceUpdate(); useEffect(() => { - const token = ResponsiveObserve.subscribe((supportScreens) => { + const responsiveObserve = useResponsiveObserve(); + const token = responsiveObserve.subscribe((supportScreens) => { screensRef.current = supportScreens; if (refreshOnChange) { forceUpdate(); } }); - return () => ResponsiveObserve.unsubscribe(token); + return () => responsiveObserve.unsubscribe(token); }, []); return screensRef.current; diff --git a/components/grid/row.tsx b/components/grid/row.tsx index d7bbda9815cf..611132e02a08 100644 --- a/components/grid/row.tsx +++ b/components/grid/row.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { ConfigContext } from '../config-provider'; import useFlexGapSupport from '../_util/hooks/useFlexGapSupport'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve'; -import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; +import useResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve'; import { tuple } from '../_util/type'; import RowContext from './RowContext'; import { useRowStyle } from './style'; @@ -101,7 +101,8 @@ const Row = React.forwardRef((props, ref) => { // ================================== Effect ================================== React.useEffect(() => { - const token = ResponsiveObserve.subscribe((screen) => { + const responsiveObserve = useResponsiveObserve(); + const token = responsiveObserve.subscribe((screen) => { setCurScreens(screen); const currentGutter = gutterRef.current || 0; if ( @@ -112,7 +113,7 @@ const Row = React.forwardRef((props, ref) => { setScreens(screen); } }); - return () => ResponsiveObserve.unsubscribe(token); + return () => responsiveObserve.unsubscribe(token); }, []); // ================================== Render ================================== From 50865e4798b41ef92d5dfc35c6409c9f0dad6810 Mon Sep 17 00:00:00 2001 From: azro Date: Fri, 2 Dec 2022 15:53:29 +0100 Subject: [PATCH 06/20] Fix useResponsiveObserve --- .../_util/__tests__/responsiveObserve.test.ts | 12 +++++------ components/_util/responsiveObserve.ts | 21 +++++++++---------- components/avatar/__tests__/Avatar.test.tsx | 2 +- .../__snapshots__/Avatar.test.tsx.snap | 14 ------------- components/avatar/avatar.tsx | 2 +- components/avatar/demo/responsive.tsx | 2 +- components/descriptions/demo/responsive.tsx | 2 +- components/descriptions/index.tsx | 3 +-- components/grid/__tests__/index.test.tsx | 1 - components/grid/col.tsx | 3 +-- components/grid/demo/responsive-more.md | 4 ++-- components/grid/demo/responsive.md | 4 ++-- components/grid/hooks/useBreakpoint.tsx | 2 +- components/grid/index.en-US.md | 5 ++--- components/grid/index.zh-CN.md | 5 ++--- components/grid/row.tsx | 7 +++---- components/grid/style/index.tsx | 1 - components/layout/Sider.tsx | 3 +-- components/layout/index.en-US.md | 3 +-- components/layout/index.zh-CN.md | 3 +-- components/list/demo/responsive.tsx | 1 - components/list/index.en-US.md | 1 - components/list/index.tsx | 5 ++--- components/list/index.zh-CN.md | 21 +++++++++---------- .../themes/compact/genCompactSizeMapToken.ts | 1 - .../theme/themes/shared/genSizeMapToken.ts | 1 - components/theme/util/alias.ts | 4 ---- 27 files changed, 49 insertions(+), 84 deletions(-) diff --git a/components/_util/__tests__/responsiveObserve.test.ts b/components/_util/__tests__/responsiveObserve.test.ts index 1857924b7f2b..6ff06b53c850 100644 --- a/components/_util/__tests__/responsiveObserve.test.ts +++ b/components/_util/__tests__/responsiveObserve.test.ts @@ -2,14 +2,14 @@ import useResponsiveObserve from '../responsiveObserve'; describe('Test ResponsiveObserve', () => { it('test ResponsiveObserve subscribe and unsubscribe', () => { - const reponsiveObserve = useResponsiveObserve(); - const { xs } = reponsiveObserve.responsiveMap; + const responsiveObserve = useResponsiveObserve(); + const { xs } = responsiveObserve.responsiveMap; const subscribeFunc = jest.fn(); - const token = reponsiveObserve.subscribe(subscribeFunc); - expect(reponsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); + const token = responsiveObserve.subscribe(subscribeFunc); + expect(responsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); expect(subscribeFunc).toHaveBeenCalledTimes(1); - reponsiveObserve.unsubscribe(token); - expect(reponsiveObserve.matchHandlers[xs].mql.removeListener).toHaveBeenCalled(); + responsiveObserve.unsubscribe(token); + expect(responsiveObserve.matchHandlers[xs].mql.removeListener).toHaveBeenCalled(); }); }); diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 56d3b2b3234a..7c208789c5b9 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,21 +1,20 @@ -import { GlobalToken } from '../theme/interface'; +import type { GlobalToken } from '../theme/interface'; import { useToken } from '../theme/internal'; -export type Breakpoint = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; +export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; export type BreakpointMap = Record; export type ScreenMap = Partial>; export type ScreenSizeMap = Partial>; -export const responsiveArray: Breakpoint[] = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs']; +export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ xs: `(max-width: ${token.screenXS}px)`, - sm: `(max-width: ${token.screenSM}px)`, - md: `(max-width: ${token.screenMD}px)`, - lg: `(max-width: ${token.screenLG}px)`, - xl: `(max-width: ${token.screenXL}px)`, - xxl: `(max-width: ${token.screenXXL}px)`, - xxxl: `(max-width: ${token.screenXXXL}px)`, + sm: `(min-width: ${token.screenSM}px)`, + md: `(min-width: ${token.screenMD}px)`, + lg: `(min-width: ${token.screenLG}px)`, + xl: `(min-width: ${token.screenXL}px)`, + xxl: `(min-width: ${token.screenXXL}px)`, }); type SubscribeFunc = (screens: ScreenMap) => void; @@ -45,8 +44,8 @@ export default function useResponsiveObserve() { func(screens); return subUid; }, - unsubscribe(token: number) { - subscribers.delete(token); + unsubscribe(paramToken: number) { + subscribers.delete(paramToken); if (!subscribers.size) this.unregister(); }, unregister() { diff --git a/components/avatar/__tests__/Avatar.test.tsx b/components/avatar/__tests__/Avatar.test.tsx index 6012d0a57942..13b36249861d 100644 --- a/components/avatar/__tests__/Avatar.test.tsx +++ b/components/avatar/__tests__/Avatar.test.tsx @@ -13,7 +13,7 @@ describe('Avatar Render', () => { mountTest(Avatar); rtlTest(Avatar); - const sizes = { xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100, xxxl: 120 }; + const sizes = { xs: 24, sm: 32, md: 40, lg: 64, xl: 80, xxl: 100 }; let originOffsetWidth: PropertyDescriptor['get']; beforeAll(() => { // Mock offsetHeight diff --git a/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap b/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap index a8eba4b5f7c7..80dce08eba7f 100644 --- a/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap +++ b/components/avatar/__tests__/__snapshots__/Avatar.test.tsx.snap @@ -84,20 +84,6 @@ exports[`Avatar Render adjusts component size to 100 when window size is xxl 1`] `; -exports[`Avatar Render adjusts component size to 120 when window size is xxxl 1`] = ` -
- - - -
-`; - exports[`Avatar Render fallback 1`] = ` - ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].includes(key), + ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key), ); const screens = useBreakpoint(needResponsive); const responsiveSizeStyle: React.CSSProperties = React.useMemo(() => { diff --git a/components/avatar/demo/responsive.tsx b/components/avatar/demo/responsive.tsx index 3583061fc610..e4d0b02736e8 100644 --- a/components/avatar/demo/responsive.tsx +++ b/components/avatar/demo/responsive.tsx @@ -4,7 +4,7 @@ import { Avatar } from 'antd'; const App: React.FC = () => ( } /> ); diff --git a/components/descriptions/demo/responsive.tsx b/components/descriptions/demo/responsive.tsx index af516d1040bf..ffd50c7959bc 100644 --- a/components/descriptions/demo/responsive.tsx +++ b/components/descriptions/demo/responsive.tsx @@ -6,7 +6,7 @@ const App: React.FC = () => ( Cloud Database Prepaid diff --git a/components/descriptions/index.tsx b/components/descriptions/index.tsx index abab35a43fc6..b3eea24065d5 100644 --- a/components/descriptions/index.tsx +++ b/components/descriptions/index.tsx @@ -20,7 +20,6 @@ export interface DescriptionsContextProps { export const DescriptionsContext = React.createContext({}); const DEFAULT_COLUMN_MAP: Record = { - xxxl: 4, xxl: 3, xl: 3, lg: 3, @@ -136,10 +135,10 @@ function Descriptions({ const mergedColumn = getColumn(column, screens); const [wrapSSR, hashId] = useStyle(prefixCls); + const responsiveObserve = useResponsiveObserve(); // Responsive React.useEffect(() => { - const responsiveObserve = useResponsiveObserve(); const token = responsiveObserve.subscribe((newScreens) => { if (typeof column !== 'object') { return; diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index 6b70ca026e2b..89ef63e3c441 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -143,7 +143,6 @@ describe('Grid', () => { lg: false, xl: false, xxl: false, - xxxl: false, }); }); diff --git a/components/grid/col.tsx b/components/grid/col.tsx index 9da53814f03b..4205b48007c5 100644 --- a/components/grid/col.tsx +++ b/components/grid/col.tsx @@ -31,7 +31,6 @@ export interface ColProps extends React.HTMLAttributes { lg?: ColSpanType | ColSize; xl?: ColSpanType | ColSize; xxl?: ColSpanType | ColSize; - xxxl?: ColSpanType | ColSize; prefixCls?: string; } @@ -46,7 +45,7 @@ function parseFlex(flex: FlexType): string { return flex; } -const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'] as const; +const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const; const Col = React.forwardRef((props, ref) => { const { getPrefixCls, direction } = React.useContext(ConfigContext); const { gutter, wrap, supportFlexGap } = React.useContext(RowContext); diff --git a/components/grid/demo/responsive-more.md b/components/grid/demo/responsive-more.md index f433ad391dfd..9c66c22cfb17 100644 --- a/components/grid/demo/responsive-more.md +++ b/components/grid/demo/responsive-more.md @@ -1,9 +1,9 @@ ## zh-CN -`span` `pull` `push` `offset` `order` 属性可以通过内嵌到 `xs` `sm` `md` `lg` `xl` `xxl` `xxxl` 属性中来使用。 +`span` `pull` `push` `offset` `order` 属性可以通过内嵌到 `xs` `sm` `md` `lg` `xl` `xxl` 属性中来使用。 其中 `xs={6}` 相当于 `xs={{ span: 6 }}`。 ## en-US -`span` `pull` `push` `offset` `order` property can be embedded into `xs` `sm` `md` `lg` `xl` `xxl` `xxxl` properties to use, where `xs={6}` is equivalent to `xs={{span: 6}}`. +`span` `pull` `push` `offset` `order` property can be embedded into `xs` `sm` `md` `lg` `xl` `xxl` properties to use, where `xs={6}` is equivalent to `xs={{span: 6}}`. diff --git a/components/grid/demo/responsive.md b/components/grid/demo/responsive.md index 208aaeaea22d..c284a628b165 100644 --- a/components/grid/demo/responsive.md +++ b/components/grid/demo/responsive.md @@ -1,7 +1,7 @@ ## zh-CN -参照 Bootstrap 的 [响应式设计](http://getbootstrap.com/css/#grid-media-queries),预设七个响应尺寸:`xs` `sm` `md` `lg` `xl` `xxl` `xxxl`。 +参照 Bootstrap 的 [响应式设计](http://getbootstrap.com/css/#grid-media-queries),预设六个响应尺寸:`xs` `sm` `md` `lg` `xl` `xxl`。 ## en-US -Referring to the Bootstrap [responsive design](http://getbootstrap.com/css/#grid-media-queries), here preset seven dimensions: `xs` `sm` `md` `lg` `xl` `xxl` `xxxl`. +Referring to the Bootstrap [responsive design](http://getbootstrap.com/css/#grid-media-queries), here preset six dimensions: `xs` `sm` `md` `lg` `xl` `xxl`. diff --git a/components/grid/hooks/useBreakpoint.tsx b/components/grid/hooks/useBreakpoint.tsx index 869133f8d542..a66e2bd8908d 100644 --- a/components/grid/hooks/useBreakpoint.tsx +++ b/components/grid/hooks/useBreakpoint.tsx @@ -6,9 +6,9 @@ import useResponsiveObserve from '../../_util/responsiveObserve'; function useBreakpoint(refreshOnChange: boolean = true): ScreenMap { const screensRef = useRef({}); const forceUpdate = useForceUpdate(); + const responsiveObserve = useResponsiveObserve(); useEffect(() => { - const responsiveObserve = useResponsiveObserve(); const token = responsiveObserve.subscribe((supportScreens) => { screensRef.current = supportScreens; if (refreshOnChange) { diff --git a/components/grid/index.en-US.md b/components/grid/index.en-US.md index d72d0f6cb1b7..1ba54f99c112 100644 --- a/components/grid/index.en-US.md +++ b/components/grid/index.en-US.md @@ -59,9 +59,9 @@ If the Ant Design grid layout component does not meet your needs, you can use th | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | -| align | Vertical alignment | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | +| align | Vertical alignment | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | | gutter | Spacing between grids, could be a number or a object like { xs: 8, sm: 16, md: 24}. Or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` | number \| object \| array | 0 | | -| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | +| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | | wrap | Auto wrap line | boolean | true | 4.8.0 | ### Col @@ -80,7 +80,6 @@ If the Ant Design grid layout component does not meet your needs, you can use th | lg | `screen ≥ 992px`, could be a `span` value or an object containing above props | number \| object | - | | | xl | `screen ≥ 1200px`, could be a `span` value or an object containing above props | number \| object | - | | | xxl | `screen ≥ 1600px`, could be a `span` value or an object containing above props | number \| object | - | | -| xxxl | `screen ≥ 2000px`, could be a `span` value or an object containing above props | number \| object | - | 5.1.0 | The breakpoints of responsive grid follow [BootStrap 4 media queries rules](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints) (not including `occasionally part`). diff --git a/components/grid/index.zh-CN.md b/components/grid/index.zh-CN.md index e4219791ee96..895fc09dfc75 100644 --- a/components/grid/index.zh-CN.md +++ b/components/grid/index.zh-CN.md @@ -58,9 +58,9 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用 | 成员 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | -| align | 垂直对齐方式 | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | +| align | 垂直对齐方式 | `top` \| `middle` \| `bottom` \| `stretch` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'top' \| 'middle' \| 'bottom' \| 'stretch'}` | `top` | object: 4.24.0 | | gutter | 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 { xs: 8, sm: 16, md: 24}。或者使用数组形式同时设置 `[水平间距, 垂直间距]` | number \| object \| array | 0 | | -| justify | 水平排列方式 | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'xxxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | +| justify | 水平排列方式 | `start` \| `end` \| `center` \| `space-around` \| `space-between` \| `space-evenly` \| `{[key in 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl']: 'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'}` | `start` | object: 4.24.0 | | wrap | 是否自动换行 | boolean | true | 4.8.0 | ### Col @@ -79,7 +79,6 @@ Ant Design 的布局组件若不能满足你的需求,你也可以直接使用 | lg | `屏幕 ≥ 992px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | | xl | `屏幕 ≥ 1200px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | | xxl | `屏幕 ≥ 1600px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | | -| xxxl | `屏幕 ≥ 2000px` 响应式栅格,可为栅格数或一个包含其他属性的对象 | number \| object | - | 5.1.0 | 响应式栅格的断点扩展自 [BootStrap 4 的规则](https://getbootstrap.com/docs/4.0/layout/overview/#responsive-breakpoints)(不包含链接里 `occasionally` 的部分)。 diff --git a/components/grid/row.tsx b/components/grid/row.tsx index 611132e02a08..310b36c36620 100644 --- a/components/grid/row.tsx +++ b/components/grid/row.tsx @@ -11,7 +11,7 @@ import { useRowStyle } from './style'; const RowAligns = tuple('top', 'middle', 'bottom', 'stretch'); const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between', 'space-evenly'); -type Responsive = 'xxxl' | 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; +type Responsive = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; type ResponsiveLike = { [key in Responsive]?: T; }; @@ -77,7 +77,6 @@ const Row = React.forwardRef((props, ref) => { lg: true, xl: true, xxl: true, - xxxl: true, }); // to save screens info when responsiveObserve callback had been call const [curScreens, setCurScreens] = React.useState({ @@ -87,7 +86,6 @@ const Row = React.forwardRef((props, ref) => { lg: false, xl: false, xxl: false, - xxxl: false, }); // ================================== calc reponsive data ================================== @@ -99,9 +97,10 @@ const Row = React.forwardRef((props, ref) => { const gutterRef = React.useRef(gutter); + const responsiveObserve = useResponsiveObserve(); + // ================================== Effect ================================== React.useEffect(() => { - const responsiveObserve = useResponsiveObserve(); const token = responsiveObserve.subscribe((screen) => { setCurScreens(screen); const currentGutter = gutterRef.current || 0; diff --git a/components/grid/style/index.tsx b/components/grid/style/index.tsx index 287ef35fe7b4..afff2bb91c1d 100644 --- a/components/grid/style/index.tsx +++ b/components/grid/style/index.tsx @@ -160,7 +160,6 @@ export const useColStyle = genComponentStyleHook('Grid', (token) => { '-lg': gridToken.screenLGMin, '-xl': gridToken.screenXLMin, '-xxl': gridToken.screenXXLMin, - '-xxxl': gridToken.screenXXXLMin, }; return [ diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index cedcf1129679..4df4f05478c1 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -17,7 +17,6 @@ const dimensionMaxMap = { lg: '991.98px', xl: '1199.98px', xxl: '1599.98px', - xxxl: '1999.98px', }; export interface SiderContextProps { @@ -41,7 +40,7 @@ export interface SiderProps extends React.HTMLAttributes { trigger?: React.ReactNode; width?: number | string; collapsedWidth?: number | string; - breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl'; + breakpoint?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; theme?: SiderTheme; onBreakpoint?: (broken: boolean) => void; } diff --git a/components/layout/index.en-US.md b/components/layout/index.en-US.md index 8459c0abd22b..222342567cb9 100644 --- a/components/layout/index.en-US.md +++ b/components/layout/index.en-US.md @@ -99,7 +99,7 @@ The sidebar. | Property | Description | Type | Default | | --- | --- | --- | --- | -| breakpoint | [Breakpoints](/components/grid/#Col) of the responsive layout | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` \| `xxxl` | - | +| breakpoint | [Breakpoints](/components/grid/#Col) of the responsive layout | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` | - | | className | Container className | string | - | | collapsed | To set the current status | boolean | - | | collapsedWidth | Width of the collapsed sidebar, by setting to 0 a special trigger will appear | number | 80 | @@ -124,7 +124,6 @@ The sidebar. lg: '992px', xl: '1200px', xxl: '1600px', - xxxl: '2000px', } ``` diff --git a/components/layout/index.zh-CN.md b/components/layout/index.zh-CN.md index 41a573e40161..3fca43cd3f66 100644 --- a/components/layout/index.zh-CN.md +++ b/components/layout/index.zh-CN.md @@ -100,7 +100,7 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*4i58ToAcxaYAAAAAAA | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| breakpoint | 触发响应式布局的[断点](/components/grid/#Col) | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` \| `xxxl` | - | +| breakpoint | 触发响应式布局的[断点](/components/grid/#Col) | `xs` \| `sm` \| `md` \| `lg` \| `xl` \| `xxl` | - | | className | 容器 className | string | - | | collapsed | 当前收起状态 | boolean | - | | collapsedWidth | 收缩宽度,设置为 0 会出现特殊 trigger | number | 80 | @@ -125,7 +125,6 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*4i58ToAcxaYAAAAAAA lg: '992px', xl: '1200px', xxl: '1600px', - xxxl: '2000px', } ``` diff --git a/components/list/demo/responsive.tsx b/components/list/demo/responsive.tsx index 8b9432b2e83d..a0fb07f085de 100644 --- a/components/list/demo/responsive.tsx +++ b/components/list/demo/responsive.tsx @@ -32,7 +32,6 @@ const App: React.FC = () => ( lg: 4, xl: 6, xxl: 3, - xxxl: 2, }} dataSource={data} renderItem={(item) => ( diff --git a/components/list/index.en-US.md b/components/list/index.en-US.md index 78f3e9af077c..ef1862d9212b 100644 --- a/components/list/index.en-US.md +++ b/components/list/index.en-US.md @@ -69,7 +69,6 @@ More about pagination, please check [`Pagination`](/components/pagination/). | lg | `≥992px` column of grid | number | - | | | xl | `≥1200px` column of grid | number | - | | | xxl | `≥1600px` column of grid | number | - | | -| xxxl | `≥2000px` column of grid | number | - | 5.1.0 | ### List.Item diff --git a/components/list/index.tsx b/components/list/index.tsx index 89d3f622b9a6..0c80c34224d4 100644 --- a/components/list/index.tsx +++ b/components/list/index.tsx @@ -21,7 +21,7 @@ export type { ListItemMetaProps, ListItemProps } from './Item'; export type ColumnCount = number; -export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl'; +export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; export interface ListGridType { gutter?: number; @@ -32,7 +32,6 @@ export interface ListGridType { lg?: ColumnCount; xl?: ColumnCount; xxl?: ColumnCount; - xxxl?: ColumnCount; } export type ListSize = 'small' | 'default' | 'large'; @@ -224,7 +223,7 @@ function List({ } const needResponsive = Object.keys(grid || {}).some((key) => - ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'].includes(key), + ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key), ); const screens = useBreakpoint(needResponsive); const currentBreakpoint = React.useMemo(() => { diff --git a/components/list/index.zh-CN.md b/components/list/index.zh-CN.md index 7bc37098ea1b..39704ee00c83 100644 --- a/components/list/index.zh-CN.md +++ b/components/list/index.zh-CN.md @@ -60,17 +60,16 @@ cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*EYuhSpw1iSwAAAAAAA ### List grid props -| 参数 | 说明 | 类型 | 默认值 | 版本 | -| ------ | -------------------- | ------ | ------ | ----- | -| column | 列数 | number | - | | -| gutter | 栅格间隔 | number | 0 | | -| xs | `<576px` 展示的列数 | number | - | | -| sm | `≥576px` 展示的列数 | number | - | | -| md | `≥768px` 展示的列数 | number | - | | -| lg | `≥992px` 展示的列数 | number | - | | -| xl | `≥1200px` 展示的列数 | number | - | | -| xxl | `≥1600px` 展示的列数 | number | - | | -| xxxl | `≥2000px` 展示的列数 | number | - | 5.1.0 | +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| ------ | -------------------- | ------ | ------ | ---- | +| column | 列数 | number | - | | +| gutter | 栅格间隔 | number | 0 | | +| xs | `<576px` 展示的列数 | number | - | | +| sm | `≥576px` 展示的列数 | number | - | | +| md | `≥768px` 展示的列数 | number | - | | +| lg | `≥992px` 展示的列数 | number | - | | +| xl | `≥1200px` 展示的列数 | number | - | | +| xxl | `≥1600px` 展示的列数 | number | - | | ### List.Item diff --git a/components/theme/themes/compact/genCompactSizeMapToken.ts b/components/theme/themes/compact/genCompactSizeMapToken.ts index 5d383a84169c..b473808eca0f 100644 --- a/components/theme/themes/compact/genCompactSizeMapToken.ts +++ b/components/theme/themes/compact/genCompactSizeMapToken.ts @@ -6,7 +6,6 @@ export default function genSizeMapToken(token: SeedToken): SizeMapToken { const compactSizeStep = sizeStep - 2; return { - sizeXXXL: sizeUnit * (compactSizeStep + 14), sizeXXL: sizeUnit * (compactSizeStep + 10), sizeXL: sizeUnit * (compactSizeStep + 6), sizeLG: sizeUnit * (compactSizeStep + 2), diff --git a/components/theme/themes/shared/genSizeMapToken.ts b/components/theme/themes/shared/genSizeMapToken.ts index a644fb31ed77..3449c24dfe22 100644 --- a/components/theme/themes/shared/genSizeMapToken.ts +++ b/components/theme/themes/shared/genSizeMapToken.ts @@ -4,7 +4,6 @@ export default function genSizeMapToken(token: SeedToken): SizeMapToken { const { sizeUnit, sizeStep } = token; return { - sizeXXXL: sizeUnit * (sizeStep + 16), // 80 sizeXXL: sizeUnit * (sizeStep + 8), // 48 sizeXL: sizeUnit * (sizeStep + 4), // 32 sizeLG: sizeUnit * (sizeStep + 2), // 24 diff --git a/components/theme/util/alias.ts b/components/theme/util/alias.ts index b37e260d03f0..0a45b6db69ff 100644 --- a/components/theme/util/alias.ts +++ b/components/theme/util/alias.ts @@ -31,7 +31,6 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken const screenLG = 992; const screenXL = 1200; const screenXXL = 1600; - const screenXXXL = 2000; const fontSizeSM = fontSizes[0]; @@ -174,9 +173,6 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken screenXLMax: screenXXL - 1, screenXXL, screenXXLMin: screenXXL, - screenXXLMax: screenXXXL - 1, - screenXXXL, - screenXXXLMin: screenXXXL, // FIXME: component box-shadow, should be removed boxShadowPopoverArrow: `3px 3px 7px rgba(0, 0, 0, 0.1)`, From f34ba028152a651344fd86ba26e72f331f1854e3 Mon Sep 17 00:00:00 2001 From: azro Date: Wed, 7 Dec 2022 08:16:25 +0100 Subject: [PATCH 07/20] Some try --- .../_util/__tests__/responsiveObserve.test.ts | 15 ----------- .../__tests__/responsiveObserve.test.tsx | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) delete mode 100644 components/_util/__tests__/responsiveObserve.test.ts create mode 100644 components/_util/__tests__/responsiveObserve.test.tsx diff --git a/components/_util/__tests__/responsiveObserve.test.ts b/components/_util/__tests__/responsiveObserve.test.ts deleted file mode 100644 index 6ff06b53c850..000000000000 --- a/components/_util/__tests__/responsiveObserve.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import useResponsiveObserve from '../responsiveObserve'; - -describe('Test ResponsiveObserve', () => { - it('test ResponsiveObserve subscribe and unsubscribe', () => { - const responsiveObserve = useResponsiveObserve(); - const { xs } = responsiveObserve.responsiveMap; - const subscribeFunc = jest.fn(); - const token = responsiveObserve.subscribe(subscribeFunc); - expect(responsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy(); - expect(subscribeFunc).toHaveBeenCalledTimes(1); - - responsiveObserve.unsubscribe(token); - expect(responsiveObserve.matchHandlers[xs].mql.removeListener).toHaveBeenCalled(); - }); -}); diff --git a/components/_util/__tests__/responsiveObserve.test.tsx b/components/_util/__tests__/responsiveObserve.test.tsx new file mode 100644 index 000000000000..73ad30e182c8 --- /dev/null +++ b/components/_util/__tests__/responsiveObserve.test.tsx @@ -0,0 +1,25 @@ +import { render } from '../../../tests/utils'; +import useResponsiveObserve from '../responsiveObserve'; + +describe('Test ResponsiveObserve', () => { + it('test ResponsiveObserve subscribe and unsubscribe', () => { + let responsiveObserveRef: any; + const Demo = () => { + const responsiveObserve = useResponsiveObserve(); + responsiveObserveRef = responsiveObserve; + return null; + }; + render(); + const subscribeFunc = jest.fn(); + const token = responsiveObserveRef.subscribe(subscribeFunc); + expect( + responsiveObserveRef.matchHandlers[responsiveObserveRef.responsiveMap.xs].mql.matches, + ).toBeTruthy(); + expect(subscribeFunc).toHaveBeenCalledTimes(1); + + responsiveObserveRef.unsubscribe(token); + expect( + responsiveObserveRef.matchHandlers[responsiveObserveRef.responsiveMap.xs].mql.removeListener, + ).toHaveBeenCalled(); + }); +}); From c50b02300f1d4279779f915c353200e7337577ef Mon Sep 17 00:00:00 2001 From: azro Date: Wed, 7 Dec 2022 08:26:50 +0100 Subject: [PATCH 08/20] Some try --- components/_util/__tests__/responsiveObserve.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/components/_util/__tests__/responsiveObserve.test.tsx b/components/_util/__tests__/responsiveObserve.test.tsx index 73ad30e182c8..0bcb6167ca87 100644 --- a/components/_util/__tests__/responsiveObserve.test.tsx +++ b/components/_util/__tests__/responsiveObserve.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { render } from '../../../tests/utils'; import useResponsiveObserve from '../responsiveObserve'; From 671b3f95ea5deacd1faefa091697f25734e0db21 Mon Sep 17 00:00:00 2001 From: azro Date: Wed, 7 Dec 2022 08:51:36 +0100 Subject: [PATCH 09/20] Some try --- components/grid/__tests__/index.test.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index 89ef63e3c441..e3b9825e048b 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -13,11 +13,6 @@ describe('Grid', () => { rtlTest(Row); rtlTest(Col); - afterEach(() => { - const responsiveObserve = useResponsiveObserve(); - responsiveObserve.unregister(); - }); - it('should render Col', () => { const { asFragment } = render(); expect(asFragment().firstChild).toMatchSnapshot(); @@ -90,8 +85,14 @@ describe('Grid', () => { }); it('ResponsiveObserve.unsubscribe should be called when unmounted', () => { - const responsiveObserve = useResponsiveObserve(); - const Unmount = jest.spyOn(responsiveObserve, 'unsubscribe'); + let responsiveObserveRef: any; + const Demo = () => { + const responsiveObserve = useResponsiveObserve(); + responsiveObserveRef = responsiveObserve; + return null; + }; + render(); + const Unmount = jest.spyOn(responsiveObserveRef, 'unsubscribe'); const { unmount } = render(); act(() => { unmount(); From a052c4be54492146f6f19c5c7818d0b16c54b442 Mon Sep 17 00:00:00 2001 From: azro Date: Wed, 7 Dec 2022 21:15:24 +0100 Subject: [PATCH 10/20] Remove impossible test --- components/grid/__tests__/index.test.tsx | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index e3b9825e048b..ebd458afccc9 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Col, Row } from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import useResponsiveObserve from '../../_util/responsiveObserve'; import useBreakpoint from '../hooks/useBreakpoint'; import { render, act } from '../../../tests/utils'; @@ -84,22 +83,6 @@ describe('Grid', () => { expect(asFragment().firstChild).toMatchSnapshot(); }); - it('ResponsiveObserve.unsubscribe should be called when unmounted', () => { - let responsiveObserveRef: any; - const Demo = () => { - const responsiveObserve = useResponsiveObserve(); - responsiveObserveRef = responsiveObserve; - return null; - }; - render(); - const Unmount = jest.spyOn(responsiveObserveRef, 'unsubscribe'); - const { unmount } = render(); - act(() => { - unmount(); - }); - expect(Unmount).toHaveBeenCalled(); - }); - it('should work correct when gutter is object', () => { const { container } = render(); expect(container.querySelector('div')!.style.marginLeft).toEqual('-10px'); From 95f07c338e30b6a40ae1d4980945bd4fadaee032 Mon Sep 17 00:00:00 2001 From: azro Date: Wed, 7 Dec 2022 21:32:30 +0100 Subject: [PATCH 11/20] Remove impossible test --- components/grid/__tests__/index.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index ebd458afccc9..e5e0c6a11427 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -3,7 +3,7 @@ import { Col, Row } from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import useBreakpoint from '../hooks/useBreakpoint'; -import { render, act } from '../../../tests/utils'; +import { render } from '../../../tests/utils'; describe('Grid', () => { mountTest(Row); From 4c6bbcfa0efae309806b36d0fb555fa87e7926aa Mon Sep 17 00:00:00 2001 From: azro Date: Thu, 8 Dec 2022 08:40:24 +0100 Subject: [PATCH 12/20] Fix token.screenXSMax --- components/_util/responsiveObserve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 7c208789c5b9..578ca865189b 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -9,7 +9,7 @@ export type ScreenSizeMap = Partial>; export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ - xs: `(max-width: ${token.screenXS}px)`, + xs: `(max-width: ${token.screenXSMax}px)`, sm: `(min-width: ${token.screenSM}px)`, md: `(min-width: ${token.screenMD}px)`, lg: `(min-width: ${token.screenLG}px)`, From b34561e1efba3f98451a1a76b09e34eebb628491 Mon Sep 17 00:00:00 2001 From: azro Date: Thu, 8 Dec 2022 09:03:14 +0100 Subject: [PATCH 13/20] Try to put test back as token.screenXSMax is fixed --- components/grid/__tests__/index.test.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index e5e0c6a11427..e3b9825e048b 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -2,8 +2,9 @@ import React from 'react'; import { Col, Row } from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import useResponsiveObserve from '../../_util/responsiveObserve'; import useBreakpoint from '../hooks/useBreakpoint'; -import { render } from '../../../tests/utils'; +import { render, act } from '../../../tests/utils'; describe('Grid', () => { mountTest(Row); @@ -83,6 +84,22 @@ describe('Grid', () => { expect(asFragment().firstChild).toMatchSnapshot(); }); + it('ResponsiveObserve.unsubscribe should be called when unmounted', () => { + let responsiveObserveRef: any; + const Demo = () => { + const responsiveObserve = useResponsiveObserve(); + responsiveObserveRef = responsiveObserve; + return null; + }; + render(); + const Unmount = jest.spyOn(responsiveObserveRef, 'unsubscribe'); + const { unmount } = render(); + act(() => { + unmount(); + }); + expect(Unmount).toHaveBeenCalled(); + }); + it('should work correct when gutter is object', () => { const { container } = render(); expect(container.querySelector('div')!.style.marginLeft).toEqual('-10px'); From a849bf3654aa450ed2d92a8b54cf61953a50be36 Mon Sep 17 00:00:00 2001 From: azro352 <35503478+azro352@users.noreply.github.com> Date: Thu, 8 Dec 2022 10:14:42 +0100 Subject: [PATCH 14/20] Remove impossible test now --- components/grid/__tests__/index.test.tsx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index e3b9825e048b..e5e0c6a11427 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Col, Row } from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; -import useResponsiveObserve from '../../_util/responsiveObserve'; import useBreakpoint from '../hooks/useBreakpoint'; -import { render, act } from '../../../tests/utils'; +import { render } from '../../../tests/utils'; describe('Grid', () => { mountTest(Row); @@ -84,22 +83,6 @@ describe('Grid', () => { expect(asFragment().firstChild).toMatchSnapshot(); }); - it('ResponsiveObserve.unsubscribe should be called when unmounted', () => { - let responsiveObserveRef: any; - const Demo = () => { - const responsiveObserve = useResponsiveObserve(); - responsiveObserveRef = responsiveObserve; - return null; - }; - render(); - const Unmount = jest.spyOn(responsiveObserveRef, 'unsubscribe'); - const { unmount } = render(); - act(() => { - unmount(); - }); - expect(Unmount).toHaveBeenCalled(); - }); - it('should work correct when gutter is object', () => { const { container } = render(); expect(container.querySelector('div')!.style.marginLeft).toEqual('-10px'); From e34464a927b5a2d280710991b676f258af5c55d5 Mon Sep 17 00:00:00 2001 From: azro352 <35503478+azro352@users.noreply.github.com> Date: Mon, 12 Dec 2022 09:22:09 +0100 Subject: [PATCH 15/20] Subscribers, subuid and screen are no longer static --- components/_util/responsiveObserve.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 578ca865189b..7454c41af3a3 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -18,13 +18,15 @@ const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ }); type SubscribeFunc = (screens: ScreenMap) => void; -const subscribers = new Map(); -let subUid = -1; -let screens = {}; export default function useResponsiveObserve() { const [, token] = useToken(); const responsiveMap: BreakpointMap = getResponsiveMap(token); + + const subscribers = new Map(); + let subUid = -1; + let screens = {}; + return { matchHandlers: {} as { [prop: string]: { @@ -77,4 +79,4 @@ export default function useResponsiveObserve() { }, responsiveMap, }; -} +} \ No newline at end of file From e2a738abf6fe83929809bb31a836f788cdb6ce11 Mon Sep 17 00:00:00 2001 From: azro Date: Mon, 12 Dec 2022 21:02:56 +0100 Subject: [PATCH 16/20] reorganize def --- components/_util/responsiveObserve.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 7454c41af3a3..952e27af9c83 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -7,6 +7,7 @@ export type ScreenMap = Partial>; export type ScreenSizeMap = Partial>; export const responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; +type SubscribeFunc = (screens: ScreenMap) => void; const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ xs: `(max-width: ${token.screenXSMax}px)`, @@ -17,8 +18,6 @@ const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ xxl: `(min-width: ${token.screenXXL}px)`, }); -type SubscribeFunc = (screens: ScreenMap) => void; - export default function useResponsiveObserve() { const [, token] = useToken(); const responsiveMap: BreakpointMap = getResponsiveMap(token); @@ -79,4 +78,4 @@ export default function useResponsiveObserve() { }, responsiveMap, }; -} \ No newline at end of file +} From 6ec354f1709c70fc68cdacb968afb9de276c4200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 15 Dec 2022 10:31:03 +0800 Subject: [PATCH 17/20] chore: not affect no-related file --- components/calendar/locale/eu_ES.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/calendar/locale/eu_ES.tsx b/components/calendar/locale/eu_ES.tsx index 7ff3a6aeecec..1512a9b62a8e 100644 --- a/components/calendar/locale/eu_ES.tsx +++ b/components/calendar/locale/eu_ES.tsx @@ -1,3 +1,3 @@ import euES from '../../date-picker/locale/eu_ES'; -export default euES; +export default euES; \ No newline at end of file From c9349d0183d7f8064b179af71eb662479981beea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 15 Dec 2022 10:34:09 +0800 Subject: [PATCH 18/20] chore: not affect no-related file --- components/float-button/FloatButtonGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/float-button/FloatButtonGroup.tsx b/components/float-button/FloatButtonGroup.tsx index 57aa47e2691d..d67e3a6edf95 100644 --- a/components/float-button/FloatButtonGroup.tsx +++ b/components/float-button/FloatButtonGroup.tsx @@ -42,7 +42,7 @@ const FloatButtonGroup: React.FC = (props) => { const [open, setOpen] = useMergedState(false, { value: props.open }); const floatButtonGroupRef = useRef(null); - const floatButtonRef = useRef(null); + const floatButtonRef = useRef(null); const hoverAction = useMemo(() => { const hoverTypeAction = { From f49630a3a1b6fbe5800ce9619e3777706343277c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 15 Dec 2022 11:16:52 +0800 Subject: [PATCH 19/20] test: update test case --- components/_util/responsiveObserve.ts | 111 ++++++++++++----------- components/grid/__tests__/index.test.tsx | 40 ++++++++ 2 files changed, 97 insertions(+), 54 deletions(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index 952e27af9c83..bbc5adf45e80 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -1,3 +1,4 @@ +import React from 'react'; import type { GlobalToken } from '../theme/interface'; import { useToken } from '../theme/internal'; @@ -18,64 +19,66 @@ const getResponsiveMap = (token: GlobalToken): BreakpointMap => ({ xxl: `(min-width: ${token.screenXXL}px)`, }); -export default function useResponsiveObserve() { +export default function useResponsiveObserver() { const [, token] = useToken(); const responsiveMap: BreakpointMap = getResponsiveMap(token); - const subscribers = new Map(); - let subUid = -1; - let screens = {}; + return React.useMemo(() => { + const subscribers = new Map(); + let subUid = -1; + let screens = {}; - return { - matchHandlers: {} as { - [prop: string]: { - mql: MediaQueryList; - listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; - }; - }, - dispatch(pointMap: ScreenMap) { - screens = pointMap; - subscribers.forEach((func) => func(screens)); - return subscribers.size >= 1; - }, - subscribe(func: SubscribeFunc): number { - if (!subscribers.size) this.register(); - subUid += 1; - subscribers.set(subUid, func); - func(screens); - return subUid; - }, - unsubscribe(paramToken: number) { - subscribers.delete(paramToken); - if (!subscribers.size) this.unregister(); - }, - unregister() { - Object.keys(responsiveMap).forEach((screen: Breakpoint) => { - const matchMediaQuery = responsiveMap[screen]; - const handler = this.matchHandlers[matchMediaQuery]; - handler?.mql.removeListener(handler?.listener); - }); - subscribers.clear(); - }, - register() { - Object.keys(responsiveMap).forEach((screen: Breakpoint) => { - const matchMediaQuery = responsiveMap[screen]; - const listener = ({ matches }: { matches: boolean }) => { - this.dispatch({ - ...screens, - [screen]: matches, - }); - }; - const mql = window.matchMedia(matchMediaQuery); - mql.addListener(listener); - this.matchHandlers[matchMediaQuery] = { - mql, - listener, + return { + matchHandlers: {} as { + [prop: string]: { + mql: MediaQueryList; + listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null; }; + }, + dispatch(pointMap: ScreenMap) { + screens = pointMap; + subscribers.forEach((func) => func(screens)); + return subscribers.size >= 1; + }, + subscribe(func: SubscribeFunc): number { + if (!subscribers.size) this.register(); + subUid += 1; + subscribers.set(subUid, func); + func(screens); + return subUid; + }, + unsubscribe(paramToken: number) { + subscribers.delete(paramToken); + if (!subscribers.size) this.unregister(); + }, + unregister() { + Object.keys(responsiveMap).forEach((screen: Breakpoint) => { + const matchMediaQuery = responsiveMap[screen]; + const handler = this.matchHandlers[matchMediaQuery]; + handler?.mql.removeListener(handler?.listener); + }); + subscribers.clear(); + }, + register() { + Object.keys(responsiveMap).forEach((screen: Breakpoint) => { + const matchMediaQuery = responsiveMap[screen]; + const listener = ({ matches }: { matches: boolean }) => { + this.dispatch({ + ...screens, + [screen]: matches, + }); + }; + const mql = window.matchMedia(matchMediaQuery); + mql.addListener(listener); + this.matchHandlers[matchMediaQuery] = { + mql, + listener, + }; - listener(mql); - }); - }, - responsiveMap, - }; + listener(mql); + }); + }, + responsiveMap, + }; + }, []); } diff --git a/components/grid/__tests__/index.test.tsx b/components/grid/__tests__/index.test.tsx index e5e0c6a11427..5f35715888cc 100644 --- a/components/grid/__tests__/index.test.tsx +++ b/components/grid/__tests__/index.test.tsx @@ -5,6 +5,34 @@ import rtlTest from '../../../tests/shared/rtlTest'; import useBreakpoint from '../hooks/useBreakpoint'; import { render } from '../../../tests/utils'; +// Mock for `responsiveObserve` to test `unsubscribe` call +jest.mock('../../_util/responsiveObserve', () => { + const modules = jest.requireActual('../../_util/responsiveObserve'); + const originHook = modules.default; + + const useMockResponsiveObserver = (...args: any[]) => { + const entity = originHook(...args); + if (!entity.unsubscribe.mocked) { + const originUnsubscribe = entity.unsubscribe; + entity.unsubscribe = (...uArgs: any[]) => { + const inst = global as any; + inst.unsubscribeCnt = (inst.unsubscribeCnt || 0) + 1; + + originUnsubscribe.call(entity, ...uArgs); + }; + entity.unsubscribe.mocked = true; + } + + return entity; + }; + + return { + ...modules, + __esModule: true, + default: useMockResponsiveObserver, + }; +}); + describe('Grid', () => { mountTest(Row); mountTest(Col); @@ -12,6 +40,10 @@ describe('Grid', () => { rtlTest(Row); rtlTest(Col); + beforeEach(() => { + (global as any).unsubscribeCnt = 0; + }); + it('should render Col', () => { const { asFragment } = render(); expect(asFragment().firstChild).toMatchSnapshot(); @@ -83,6 +115,14 @@ describe('Grid', () => { expect(asFragment().firstChild).toMatchSnapshot(); }); + it('useResponsiveObserve.unsubscribe should be called when unmounted', () => { + const { unmount } = render(); + const called: number = (global as any).unsubscribeCnt; + + unmount(); + expect((global as any).unsubscribeCnt).toEqual(called + 1); + }); + it('should work correct when gutter is object', () => { const { container } = render(); expect(container.querySelector('div')!.style.marginLeft).toEqual('-10px'); From c5e91b8b13ab59f53a7ddecfe50f7bae2aee9607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 15 Dec 2022 11:18:32 +0800 Subject: [PATCH 20/20] chore: adjust memo logic --- components/_util/responsiveObserve.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/_util/responsiveObserve.ts b/components/_util/responsiveObserve.ts index bbc5adf45e80..d353b251a6d4 100644 --- a/components/_util/responsiveObserve.ts +++ b/components/_util/responsiveObserve.ts @@ -23,6 +23,7 @@ export default function useResponsiveObserver() { const [, token] = useToken(); const responsiveMap: BreakpointMap = getResponsiveMap(token); + // To avoid repeat create instance, we add `useMemo` here. return React.useMemo(() => { const subscribers = new Map(); let subUid = -1; @@ -80,5 +81,5 @@ export default function useResponsiveObserver() { }, responsiveMap, }; - }, []); + }, [token]); }