mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-05 23:46:28 +08:00
refactor(grid): useContext and improve code (#27127)
This commit is contained in:
parent
c7e51aba13
commit
f6769e3e94
@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import RowContext from './RowContext';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/14324
|
||||
type ColSpanType = number | string;
|
||||
@ -46,93 +46,89 @@ function parseFlex(flex: FlexType): string {
|
||||
}
|
||||
|
||||
const Col = React.forwardRef<HTMLDivElement, ColProps>((props, ref) => {
|
||||
const renderCol = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
span,
|
||||
order,
|
||||
offset,
|
||||
push,
|
||||
pull,
|
||||
className,
|
||||
children,
|
||||
flex,
|
||||
style,
|
||||
...others
|
||||
} = props;
|
||||
const prefixCls = getPrefixCls('col', customizePrefixCls);
|
||||
let sizeClassObj = {};
|
||||
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].forEach(size => {
|
||||
let sizeProps: ColSize = {};
|
||||
const propSize = (props as any)[size];
|
||||
if (typeof propSize === 'number') {
|
||||
sizeProps.span = propSize;
|
||||
} else if (typeof propSize === 'object') {
|
||||
sizeProps = propSize || {};
|
||||
}
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const { gutter } = React.useContext(RowContext);
|
||||
|
||||
delete (others as any)[size];
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
span,
|
||||
order,
|
||||
offset,
|
||||
push,
|
||||
pull,
|
||||
className,
|
||||
children,
|
||||
flex,
|
||||
style,
|
||||
...others
|
||||
} = props;
|
||||
|
||||
sizeClassObj = {
|
||||
...sizeClassObj,
|
||||
[`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
|
||||
[`${prefixCls}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0,
|
||||
[`${prefixCls}-${size}-offset-${sizeProps.offset}`]:
|
||||
sizeProps.offset || sizeProps.offset === 0,
|
||||
[`${prefixCls}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0,
|
||||
[`${prefixCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
};
|
||||
});
|
||||
const classes = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${span}`]: span !== undefined,
|
||||
[`${prefixCls}-order-${order}`]: order,
|
||||
[`${prefixCls}-offset-${offset}`]: offset,
|
||||
[`${prefixCls}-push-${push}`]: push,
|
||||
[`${prefixCls}-pull-${pull}`]: pull,
|
||||
},
|
||||
className,
|
||||
sizeClassObj,
|
||||
);
|
||||
const prefixCls = getPrefixCls('col', customizePrefixCls);
|
||||
|
||||
return (
|
||||
<RowContext.Consumer>
|
||||
{({ gutter }) => {
|
||||
let mergedStyle: React.CSSProperties = { ...style };
|
||||
if (gutter) {
|
||||
mergedStyle = {
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
paddingLeft: gutter[0]! / 2,
|
||||
paddingRight: gutter[0]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...(gutter[1]! > 0
|
||||
? {
|
||||
paddingTop: gutter[1]! / 2,
|
||||
paddingBottom: gutter[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...mergedStyle,
|
||||
};
|
||||
let sizeClassObj = {};
|
||||
(['xs', 'sm', 'md', 'lg', 'xl', 'xxl'] as const).forEach(size => {
|
||||
let sizeProps: ColSize = {};
|
||||
const propSize = props[size];
|
||||
if (typeof propSize === 'number') {
|
||||
sizeProps.span = propSize;
|
||||
} else if (typeof propSize === 'object') {
|
||||
sizeProps = propSize || {};
|
||||
}
|
||||
|
||||
delete others[size];
|
||||
|
||||
sizeClassObj = {
|
||||
...sizeClassObj,
|
||||
[`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
|
||||
[`${prefixCls}-${size}-order-${sizeProps.order}`]: sizeProps.order || sizeProps.order === 0,
|
||||
[`${prefixCls}-${size}-offset-${sizeProps.offset}`]:
|
||||
sizeProps.offset || sizeProps.offset === 0,
|
||||
[`${prefixCls}-${size}-push-${sizeProps.push}`]: sizeProps.push || sizeProps.push === 0,
|
||||
[`${prefixCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull || sizeProps.pull === 0,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
};
|
||||
});
|
||||
|
||||
const classes = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${span}`]: span !== undefined,
|
||||
[`${prefixCls}-order-${order}`]: order,
|
||||
[`${prefixCls}-offset-${offset}`]: offset,
|
||||
[`${prefixCls}-push-${push}`]: push,
|
||||
[`${prefixCls}-pull-${pull}`]: pull,
|
||||
},
|
||||
className,
|
||||
sizeClassObj,
|
||||
);
|
||||
|
||||
let mergedStyle: React.CSSProperties = { ...style };
|
||||
if (gutter) {
|
||||
mergedStyle = {
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
paddingLeft: gutter[0]! / 2,
|
||||
paddingRight: gutter[0]! / 2,
|
||||
}
|
||||
if (flex) {
|
||||
mergedStyle.flex = parseFlex(flex);
|
||||
: {}),
|
||||
...(gutter[1]! > 0
|
||||
? {
|
||||
paddingTop: gutter[1]! / 2,
|
||||
paddingBottom: gutter[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...mergedStyle,
|
||||
};
|
||||
}
|
||||
if (flex) {
|
||||
mergedStyle.flex = parseFlex(flex);
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...others} style={mergedStyle} className={classes} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</RowContext.Consumer>
|
||||
);
|
||||
};
|
||||
|
||||
return <ConfigConsumer>{renderCol}</ConfigConsumer>;
|
||||
return (
|
||||
<div {...others} style={mergedStyle} className={classes} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
Col.displayName = 'Col';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import RowContext from './RowContext';
|
||||
import { tuple } from '../_util/type';
|
||||
import ResponsiveObserve, {
|
||||
@ -21,6 +21,19 @@ export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
}
|
||||
|
||||
const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
justify,
|
||||
align,
|
||||
className,
|
||||
style,
|
||||
children,
|
||||
gutter = 0,
|
||||
...others
|
||||
} = props;
|
||||
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
|
||||
const [screens, setScreens] = React.useState<ScreenMap>({
|
||||
xs: true,
|
||||
sm: true,
|
||||
@ -29,8 +42,8 @@ const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
xl: true,
|
||||
xxl: true,
|
||||
});
|
||||
const gutterRef = React.useRef<Gutter | [Gutter, Gutter]>();
|
||||
gutterRef.current = props.gutter;
|
||||
|
||||
const gutterRef = React.useRef<Gutter | [Gutter, Gutter]>(gutter);
|
||||
|
||||
React.useEffect(() => {
|
||||
const token = ResponsiveObserve.subscribe(screen => {
|
||||
@ -43,14 +56,11 @@ const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
setScreens(screen);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
ResponsiveObserve.unsubscribe(token);
|
||||
};
|
||||
return () => ResponsiveObserve.unsubscribe(token);
|
||||
}, []);
|
||||
|
||||
const getGutter = (): [number, number] => {
|
||||
const results: [number, number] = [0, 0];
|
||||
const { gutter = 0 } = props;
|
||||
const normalizedGutter = Array.isArray(gutter) ? gutter : [gutter, 0];
|
||||
normalizedGutter.forEach((g, index) => {
|
||||
if (typeof g === 'object') {
|
||||
@ -68,55 +78,40 @@ const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
|
||||
return results;
|
||||
};
|
||||
|
||||
const renderRow = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
justify,
|
||||
align,
|
||||
className,
|
||||
style,
|
||||
children,
|
||||
...others
|
||||
} = props;
|
||||
const prefixCls = getPrefixCls('row', customizePrefixCls);
|
||||
const gutter = getGutter();
|
||||
const classes = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${justify}`]: justify,
|
||||
[`${prefixCls}-${align}`]: align,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
const rowStyle = {
|
||||
...(gutter[0]! > 0
|
||||
? {
|
||||
marginLeft: gutter[0]! / -2,
|
||||
marginRight: gutter[0]! / -2,
|
||||
}
|
||||
: {}),
|
||||
...(gutter[1]! > 0
|
||||
? {
|
||||
marginTop: gutter[1]! / -2,
|
||||
marginBottom: gutter[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...style,
|
||||
};
|
||||
const otherProps = { ...others };
|
||||
delete otherProps.gutter;
|
||||
|
||||
return (
|
||||
<RowContext.Provider value={{ gutter }}>
|
||||
<div {...otherProps} className={classes} style={rowStyle} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
</RowContext.Provider>
|
||||
);
|
||||
const prefixCls = getPrefixCls('row', customizePrefixCls);
|
||||
const gutters = getGutter();
|
||||
const classes = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${justify}`]: justify,
|
||||
[`${prefixCls}-${align}`]: align,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
);
|
||||
const rowStyle = {
|
||||
...(gutters[0]! > 0
|
||||
? {
|
||||
marginLeft: gutters[0]! / -2,
|
||||
marginRight: gutters[0]! / -2,
|
||||
}
|
||||
: {}),
|
||||
...(gutters[1]! > 0
|
||||
? {
|
||||
marginTop: gutters[1]! / -2,
|
||||
marginBottom: gutters[1]! / 2,
|
||||
}
|
||||
: {}),
|
||||
...style,
|
||||
};
|
||||
|
||||
return <ConfigConsumer>{renderRow}</ConfigConsumer>;
|
||||
return (
|
||||
<RowContext.Provider value={{ gutter: gutters }}>
|
||||
<div {...others} className={classes} style={rowStyle} ref={ref}>
|
||||
{children}
|
||||
</div>
|
||||
</RowContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
Row.displayName = 'Row';
|
||||
|
Loading…
Reference in New Issue
Block a user