ant-design/components/space/index.tsx
afc163 59ad48476b
refactor: add boime lint and fix lint errrors (#49536)
* chore: add boime lint

* fix lint

* use files ignore

* revert change

* ignore clarity.js

* fix some errors

* fix some errors

* fix some errors

* fix some errors

* add yml file

* Update clarity.js

Signed-off-by: afc163 <afc163@gmail.com>

* add npm run lint:biome

* add npm run lint:biome

* fix test case

* fix ts errors

* fix ts errors

* fix lint and add .lintstagedrc

* shorten prop name

* chore: update package.json

* update biome.json

* chore: remove stylelint

* chore: useOptionalChain

* fix lint

* biome format

* prettier all code

* prettier all code

* fix site test

---------

Signed-off-by: afc163 <afc163@gmail.com>
2024-06-22 21:59:12 +08:00

157 lines
4.1 KiB
TypeScript

import * as React from 'react';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import { isPresetSize, isValidGapNumber } from '../_util/gapSize';
import { ConfigContext } from '../config-provider';
import type { SizeType } from '../config-provider/SizeContext';
import Compact from './Compact';
import { SpaceContextProvider } from './context';
import type { SpaceContextType } from './context';
import Item from './Item';
import useStyle from './style';
export { SpaceContext } from './context';
export type SpaceSize = SizeType | number;
export interface SpaceProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
className?: string;
rootClassName?: string;
style?: React.CSSProperties;
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;
classNames?: { item: string };
styles?: { item: React.CSSProperties };
}
const InternalSpace = React.forwardRef<HTMLDivElement, SpaceProps>((props, ref) => {
const { getPrefixCls, space, direction: directionConfig } = React.useContext(ConfigContext);
const {
size = space?.size ?? 'small',
align,
className,
rootClassName,
children,
direction = 'horizontal',
prefixCls: customizePrefixCls,
split,
style,
wrap = false,
classNames: customClassNames,
styles,
...otherProps
} = props;
const [horizontalSize, verticalSize] = Array.isArray(size) ? size : ([size, size] as const);
const isPresetVerticalSize = isPresetSize(verticalSize);
const isPresetHorizontalSize = isPresetSize(horizontalSize);
const isValidVerticalSize = isValidGapNumber(verticalSize);
const isValidHorizontalSize = isValidGapNumber(horizontalSize);
const childNodes = toArray(children, { keepEmpty: true });
const mergedAlign = align === undefined && direction === 'horizontal' ? 'center' : align;
const prefixCls = getPrefixCls('space', customizePrefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
const cls = classNames(
prefixCls,
space?.className,
hashId,
`${prefixCls}-${direction}`,
{
[`${prefixCls}-rtl`]: directionConfig === 'rtl',
[`${prefixCls}-align-${mergedAlign}`]: mergedAlign,
[`${prefixCls}-gap-row-${verticalSize}`]: isPresetVerticalSize,
[`${prefixCls}-gap-col-${horizontalSize}`]: isPresetHorizontalSize,
},
className,
rootClassName,
cssVarCls,
);
const itemClassName = classNames(
`${prefixCls}-item`,
customClassNames?.item ?? space?.classNames?.item,
);
// Calculate latest one
let latestIndex = 0;
const nodes = childNodes.map<React.ReactNode>((child, i) => {
if (child !== null && child !== undefined) {
latestIndex = i;
}
const key = child?.key || `${itemClassName}-${i}`;
return (
<Item
className={itemClassName}
key={key}
index={i}
split={split}
style={styles?.item ?? space?.styles?.item}
>
{child}
</Item>
);
});
const spaceContext = React.useMemo<SpaceContextType>(() => ({ latestIndex }), [latestIndex]);
// =========================== Render ===========================
if (childNodes.length === 0) {
return null;
}
const gapStyle: React.CSSProperties = {};
if (wrap) {
gapStyle.flexWrap = 'wrap';
}
if (!isPresetHorizontalSize && isValidHorizontalSize) {
gapStyle.columnGap = horizontalSize;
}
if (!isPresetVerticalSize && isValidVerticalSize) {
gapStyle.rowGap = verticalSize;
}
return wrapCSSVar(
<div
ref={ref}
className={cls}
style={{ ...gapStyle, ...space?.style, ...style }}
{...otherProps}
>
<SpaceContextProvider value={spaceContext}>{nodes}</SpaceContextProvider>
</div>,
);
});
type CompoundedComponent = typeof InternalSpace & {
Compact: typeof Compact;
};
const Space = InternalSpace as CompoundedComponent;
Space.Compact = Compact;
if (process.env.NODE_ENV !== 'production') {
Space.displayName = 'Space';
}
export default Space;