diff --git a/components/space/Item.tsx b/components/space/Item.tsx index 51b45254a3..bb944efd1e 100644 --- a/components/space/Item.tsx +++ b/components/space/Item.tsx @@ -1,46 +1,44 @@ import * as React from 'react'; -import { LastIndexContext } from '.'; -import { SizeType } from '../config-provider/SizeContext'; - -const spaceSize = { - small: 8, - middle: 16, - large: 24, -}; +import { SpaceContext } from '.'; export interface ItemProps { className: string; children: React.ReactNode; index: number; direction?: 'horizontal' | 'vertical'; - size?: SizeType | number; marginDirection: 'marginLeft' | 'marginRight'; split?: string | React.ReactNode; + wrap?: boolean; } export default function Item({ className, direction, index, - size, marginDirection, children, split, + wrap, }: ItemProps) { - const latestIndex = React.useContext(LastIndexContext); + const { horizontalSize, verticalSize, latestIndex } = React.useContext(SpaceContext); + + let style: React.CSSProperties = {}; + + if (direction === 'vertical') { + if (index < latestIndex) { + style = { marginBottom: horizontalSize / (split ? 2 : 1) }; + } + } else { + style = { + ...(index < latestIndex && { [marginDirection]: horizontalSize / (split ? 2 : 1) }), + ...(wrap && { paddingBottom: verticalSize }), + }; + } if (children === null || children === undefined) { return null; } - const style = - index >= latestIndex - ? {} - : { - [direction === 'vertical' ? 'marginBottom' : marginDirection]: - ((typeof size === 'string' ? spaceSize[size] : size) ?? 0) / (split ? 2 : 1), - }; - return ( <>
diff --git a/components/space/__tests__/__snapshots__/demo.test.js.snap b/components/space/__tests__/__snapshots__/demo.test.js.snap index fc42a9c486..7eb5974539 100644 --- a/components/space/__tests__/__snapshots__/demo.test.js.snap +++ b/components/space/__tests__/__snapshots__/demo.test.js.snap @@ -657,3 +657,271 @@ exports[`renders ./components/space/demo/vertical.md correctly 1`] = `
`; + +exports[`renders ./components/space/demo/wrap.md correctly 1`] = ` +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+`; diff --git a/components/space/demo/wrap.md b/components/space/demo/wrap.md new file mode 100644 index 0000000000..2db8366326 --- /dev/null +++ b/components/space/demo/wrap.md @@ -0,0 +1,31 @@ +--- +order: 98 +title: + zh-CN: 自动换行 + en-US: Wrap +--- + +## zh-CN + +自动换行。 + +## en-US + +Auto wrap line. + +```jsx +import { Space, Button } from 'antd'; + +const Demo = () => { + return ( + + {new Array(20).fill(null).map((_, index) => ( + // eslint-disable-next-line react/no-array-index-key + + ))} + + ); +}; + +ReactDOM.render(, mountNode); +``` diff --git a/components/space/index.en-US.md b/components/space/index.en-US.md index 510602a0ca..2a2e6f1264 100644 --- a/components/space/index.en-US.md +++ b/components/space/index.en-US.md @@ -18,5 +18,10 @@ Avoid components clinging together and set a unified space. | --- | --- | --- | --- | --- | | align | Align items | `start` \| `end` \|`center` \|`baseline` | - | 4.2.0 | | direction | The space direction | `vertical` \| `horizontal` | `horizontal` | 4.1.0 | -| size | The space size | `small` \| `middle` \| `large` \| number | `small` | 4.1.0 | +| size | The space size | [Size](#Size) \| [Size\[\]](#Size) | `small` | 4.1.0 \| Array: 4.9.0 | | split | Set split | ReactNode | - | 4.7.0 | +| wrap | Auto wrap line, when `horizontal` effective | boolean | false | 4.9.0 | + +### Size + +`'small' | 'middle' | 'large' | number` diff --git a/components/space/index.tsx b/components/space/index.tsx index a13f1cfca1..0bbb714246 100644 --- a/components/space/index.tsx +++ b/components/space/index.tsx @@ -5,17 +5,34 @@ import { ConfigContext } from '../config-provider'; import { SizeType } from '../config-provider/SizeContext'; import Item from './Item'; -export const LastIndexContext = React.createContext(0); +export const SpaceContext = React.createContext({ + latestIndex: 0, + horizontalSize: 0, + verticalSize: 0, +}); + +export type SpaceSize = SizeType | number; export interface SpaceProps { prefixCls?: string; className?: string; style?: React.CSSProperties; - size?: SizeType | number; + size?: SpaceSize | [SpaceSize, SpaceSize]; direction?: 'horizontal' | 'vertical'; // No `stretch` since many components do not support that. align?: 'start' | 'end' | 'center' | 'baseline'; split?: React.ReactNode; + wrap?: boolean; +} + +const spaceSize = { + small: 8, + middle: 16, + large: 24, +}; + +function getNumberSize(size: SpaceSize) { + return typeof size === 'string' ? spaceSize[size] : size || 0; } const Space: React.FC = props => { @@ -29,9 +46,19 @@ const Space: React.FC = props => { direction = 'horizontal', prefixCls: customizePrefixCls, split, + style, + wrap = false, ...otherProps } = props; + const [horizontalSize, verticalSize] = React.useMemo( + () => + ((Array.isArray(size) ? size : [size, size]) as [SpaceSize, SpaceSize]).map(item => + getNumberSize(item), + ), + [size], + ); + const childNodes = toArray(children, { keepEmpty: true }); if (childNodes.length === 0) { @@ -67,10 +94,10 @@ const Space: React.FC = props => { className={itemClassName} key={`${itemClassName}-${i}`} direction={direction} - size={size} index={i} marginDirection={marginDirection} split={split} + wrap={wrap} > {child} @@ -79,8 +106,17 @@ const Space: React.FC = props => { }); return ( -
- {nodes} +
+ + {nodes} +
); }; diff --git a/components/space/index.zh-CN.md b/components/space/index.zh-CN.md index d9b08cb69a..0dc81f9690 100644 --- a/components/space/index.zh-CN.md +++ b/components/space/index.zh-CN.md @@ -22,5 +22,10 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/wc6%263gJ0Y8/Space.svg | --- | --- | --- | --- | --- | | align | 对齐方式 | `start` \| `end` \|`center` \|`baseline` | - | 4.2.0 | | direction | 间距方向 | `vertical` \| `horizontal` | `horizontal` | 4.1.0 | -| size | 间距大小 | `small` \| `middle` \| `large` \| number | `small` | 4.1.0 | +| size | 间距大小 | [Size](#Size) \| [Size\[\]](#Size) | `small` | 4.1.0 \| Array: 4.9.0 | | split | 设置拆分 | ReactNode | - | 4.7.0 | +| wrap | 是否自动换行,仅在 `horizontal` 时有效 | boolean | false | 4.9.0 | + +### Size + +`'small' | 'middle' | 'large' | number`