mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-04 21:18:01 +08:00
fix: Use flex gap of space (#30023)
* fix: use flex gap when supported * test: update snapshot * refactor: Use single hooks
This commit is contained in:
parent
a42fc02746
commit
ebd60df124
@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { detectFlexGapSupported } from '../../_util/styleChecker';
|
import { detectFlexGapSupported } from '../styleChecker';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [flexible, setFlexible] = React.useState(false);
|
const [flexible, setFlexible] = React.useState(false);
|
@ -8,7 +8,7 @@ import ResponsiveObserve, {
|
|||||||
ScreenMap,
|
ScreenMap,
|
||||||
responsiveArray,
|
responsiveArray,
|
||||||
} from '../_util/responsiveObserve';
|
} from '../_util/responsiveObserve';
|
||||||
import useFlexGapSupport from './hooks/useFlexGapSupport';
|
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
|
||||||
|
|
||||||
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
const RowAligns = tuple('top', 'middle', 'bottom', 'stretch');
|
||||||
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
const RowJustify = tuple('start', 'end', 'center', 'space-around', 'space-between');
|
||||||
|
@ -20,19 +20,23 @@ export default function Item({
|
|||||||
split,
|
split,
|
||||||
wrap,
|
wrap,
|
||||||
}: ItemProps) {
|
}: ItemProps) {
|
||||||
const { horizontalSize, verticalSize, latestIndex } = React.useContext(SpaceContext);
|
const { horizontalSize, verticalSize, latestIndex, supportFlexGap } = React.useContext(
|
||||||
|
SpaceContext,
|
||||||
|
);
|
||||||
|
|
||||||
let style: React.CSSProperties = {};
|
let style: React.CSSProperties = {};
|
||||||
|
|
||||||
if (direction === 'vertical') {
|
if (!supportFlexGap) {
|
||||||
if (index < latestIndex) {
|
if (direction === 'vertical') {
|
||||||
style = { marginBottom: horizontalSize / (split ? 2 : 1) };
|
if (index < latestIndex) {
|
||||||
|
style = { marginBottom: horizontalSize / (split ? 2 : 1) };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
style = {
|
||||||
|
...(index < latestIndex && { [marginDirection]: horizontalSize / (split ? 2 : 1) }),
|
||||||
|
...(wrap && { paddingBottom: verticalSize }),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
style = {
|
|
||||||
...(index < latestIndex && { [marginDirection]: horizontalSize / (split ? 2 : 1) }),
|
|
||||||
...(wrap && { paddingBottom: verticalSize }),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (children === null || children === undefined) {
|
if (children === null || children === undefined) {
|
||||||
|
@ -408,6 +408,61 @@ exports[`renders ./components/space/demo/debug.md correctly 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/space/demo/gap-in-line.md correctly 1`] = `
|
||||||
|
Array [
|
||||||
|
<button
|
||||||
|
aria-checked="false"
|
||||||
|
class="ant-switch"
|
||||||
|
role="switch"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-switch-handle"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="ant-switch-inner"
|
||||||
|
/>
|
||||||
|
</button>,
|
||||||
|
<div
|
||||||
|
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||||
|
style="flex-wrap:wrap;margin-bottom:-8px;width:310px;background:blue"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="margin-right:8px;padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="ant-space-item"
|
||||||
|
style="padding-bottom:8px"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="width:150px;height:100px;background:red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`renders ./components/space/demo/size.md correctly 1`] = `
|
exports[`renders ./components/space/demo/size.md correctly 1`] = `
|
||||||
Array [
|
Array [
|
||||||
<div
|
<div
|
||||||
|
48
components/space/demo/gap-in-line.md
Normal file
48
components/space/demo/gap-in-line.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
order: 99
|
||||||
|
title:
|
||||||
|
zh-CN: Flex gap 样式
|
||||||
|
en-US: Flex gap style
|
||||||
|
debug: true
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
Debug usage
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
Debug usage
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Space, Switch } from 'antd';
|
||||||
|
|
||||||
|
const style: React.CSSProperties = {
|
||||||
|
width: 150,
|
||||||
|
height: 100,
|
||||||
|
background: 'red',
|
||||||
|
};
|
||||||
|
|
||||||
|
const Demo = () => {
|
||||||
|
const [singleCol, setSingleCol] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Switch
|
||||||
|
checked={singleCol}
|
||||||
|
onChange={() => {
|
||||||
|
setSingleCol(!singleCol);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Space style={{ width: singleCol ? 307 : 310, background: 'blue' }} size={[8, 8]} wrap>
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
<div style={style} />
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(<Demo />, mountNode);
|
||||||
|
```
|
@ -4,11 +4,13 @@ import toArray from 'rc-util/lib/Children/toArray';
|
|||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import { SizeType } from '../config-provider/SizeContext';
|
import { SizeType } from '../config-provider/SizeContext';
|
||||||
import Item from './Item';
|
import Item from './Item';
|
||||||
|
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
|
||||||
|
|
||||||
export const SpaceContext = React.createContext({
|
export const SpaceContext = React.createContext({
|
||||||
latestIndex: 0,
|
latestIndex: 0,
|
||||||
horizontalSize: 0,
|
horizontalSize: 0,
|
||||||
verticalSize: 0,
|
verticalSize: 0,
|
||||||
|
supportFlexGap: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type SpaceSize = SizeType | number;
|
export type SpaceSize = SizeType | number;
|
||||||
@ -51,6 +53,8 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const supportFlexGap = useFlexGapSupport();
|
||||||
|
|
||||||
const [horizontalSize, verticalSize] = React.useMemo(
|
const [horizontalSize, verticalSize] = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
((Array.isArray(size) ? size : [size, size]) as [SpaceSize, SpaceSize]).map(item =>
|
((Array.isArray(size) ? size : [size, size]) as [SpaceSize, SpaceSize]).map(item =>
|
||||||
@ -61,10 +65,6 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
|
|
||||||
const childNodes = toArray(children, { keepEmpty: true });
|
const childNodes = toArray(children, { keepEmpty: true });
|
||||||
|
|
||||||
if (childNodes.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
|
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
|
||||||
const prefixCls = getPrefixCls('space', customizePrefixCls);
|
const prefixCls = getPrefixCls('space', customizePrefixCls);
|
||||||
const cn = classNames(
|
const cn = classNames(
|
||||||
@ -105,18 +105,33 @@ const Space: React.FC<SpaceProps> = props => {
|
|||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const spaceContext = React.useMemo(
|
||||||
|
() => ({ horizontalSize, verticalSize, latestIndex, supportFlexGap }),
|
||||||
|
[horizontalSize, verticalSize, latestIndex, supportFlexGap],
|
||||||
|
);
|
||||||
|
|
||||||
|
// =========================== Render ===========================
|
||||||
|
if (childNodes.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gapStyle: React.CSSProperties = {};
|
||||||
|
if (supportFlexGap) {
|
||||||
|
gapStyle.columnGap = horizontalSize;
|
||||||
|
gapStyle.rowGap = verticalSize;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn}
|
className={cn}
|
||||||
style={{
|
style={{
|
||||||
|
...gapStyle,
|
||||||
...(wrap && { flexWrap: 'wrap', marginBottom: -verticalSize }),
|
...(wrap && { flexWrap: 'wrap', marginBottom: -verticalSize }),
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
>
|
>
|
||||||
<SpaceContext.Provider value={{ horizontalSize, verticalSize, latestIndex }}>
|
<SpaceContext.Provider value={spaceContext}>{nodes}</SpaceContext.Provider>
|
||||||
{nodes}
|
|
||||||
</SpaceContext.Provider>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user