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:
二货机器人 2021-04-06 11:38:36 +08:00 committed by GitHub
parent a42fc02746
commit ebd60df124
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 140 additions and 18 deletions

View File

@ -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);

View File

@ -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');

View File

@ -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) {

View File

@ -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

View 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);
```

View File

@ -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>
); );
}; };