ant-design/components/space/Compact.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

132 lines
3.9 KiB
TypeScript

import * as React from 'react';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import type { DirectionType } from '../config-provider';
import { ConfigContext } from '../config-provider';
import useSize from '../config-provider/hooks/useSize';
import type { SizeType } from '../config-provider/SizeContext';
import useStyle from './style';
export interface SpaceCompactItemContextType {
compactSize?: SizeType;
compactDirection?: 'horizontal' | 'vertical';
isFirstItem?: boolean;
isLastItem?: boolean;
}
export const SpaceCompactItemContext = React.createContext<SpaceCompactItemContextType | null>(
null,
);
export const useCompactItemContext = (prefixCls: string, direction: DirectionType) => {
const compactItemContext = React.useContext(SpaceCompactItemContext);
const compactItemClassnames = React.useMemo<string>(() => {
if (!compactItemContext) {
return '';
}
const { compactDirection, isFirstItem, isLastItem } = compactItemContext;
const separator = compactDirection === 'vertical' ? '-vertical-' : '-';
return classNames(`${prefixCls}-compact${separator}item`, {
[`${prefixCls}-compact${separator}first-item`]: isFirstItem,
[`${prefixCls}-compact${separator}last-item`]: isLastItem,
[`${prefixCls}-compact${separator}item-rtl`]: direction === 'rtl',
});
}, [prefixCls, direction, compactItemContext]);
return {
compactSize: compactItemContext?.compactSize,
compactDirection: compactItemContext?.compactDirection,
compactItemClassnames,
};
};
export const NoCompactStyle: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => (
<SpaceCompactItemContext.Provider value={null}>{children}</SpaceCompactItemContext.Provider>
);
export interface SpaceCompactProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
size?: SizeType;
direction?: 'horizontal' | 'vertical';
block?: boolean;
rootClassName?: string;
}
const CompactItem: React.FC<React.PropsWithChildren<SpaceCompactItemContextType>> = ({
children,
...otherProps
}) => (
<SpaceCompactItemContext.Provider value={otherProps}>{children}</SpaceCompactItemContext.Provider>
);
const Compact: React.FC<SpaceCompactProps> = (props) => {
const { getPrefixCls, direction: directionConfig } = React.useContext(ConfigContext);
const {
size,
direction,
block,
prefixCls: customizePrefixCls,
className,
rootClassName,
children,
...restProps
} = props;
const mergedSize = useSize((ctx) => size ?? ctx);
const prefixCls = getPrefixCls('space-compact', customizePrefixCls);
const [wrapCSSVar, hashId] = useStyle(prefixCls);
const clx = classNames(
prefixCls,
hashId,
{
[`${prefixCls}-rtl`]: directionConfig === 'rtl',
[`${prefixCls}-block`]: block,
[`${prefixCls}-vertical`]: direction === 'vertical',
},
className,
rootClassName,
);
const compactItemContext = React.useContext(SpaceCompactItemContext);
const childNodes = toArray(children);
const nodes = React.useMemo(
() =>
childNodes.map((child, i) => {
const key = child?.key || `${prefixCls}-item-${i}`;
return (
<CompactItem
key={key}
compactSize={mergedSize}
compactDirection={direction}
isFirstItem={i === 0 && (!compactItemContext || compactItemContext?.isFirstItem)}
isLastItem={
i === childNodes.length - 1 && (!compactItemContext || compactItemContext?.isLastItem)
}
>
{child}
</CompactItem>
);
}),
[size, childNodes, compactItemContext],
);
// =========================== Render ===========================
if (childNodes.length === 0) {
return null;
}
return wrapCSSVar(
<div className={clx} {...restProps}>
{nodes}
</div>,
);
};
export default Compact;