This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
import React from 'react';
import type { InputStatus } from '../_util/statusUtils';
import type { Variant } from '../config-provider';
export interface SpaceCompactCellProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
prefixCls?: string;
variant?: Variant;
disabled?: boolean;
status?: InputStatus;
}
declare const SpaceAddon: React.ForwardRefExoticComponent<SpaceCompactCellProps & React.RefAttributes<HTMLDivElement>>;
export default SpaceAddon;
+42
View File
@@ -0,0 +1,42 @@
"use client";
import React from 'react';
import { clsx } from 'clsx';
import { getStatusClassNames } from '../_util/statusUtils';
import { ConfigContext } from '../config-provider';
import { useCompactItemContext } from './Compact';
import useStyle from './style/addon';
const SpaceAddon = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
className,
children,
style,
prefixCls: customizePrefixCls,
variant = 'outlined',
disabled,
status,
...restProps
} = props;
const {
getPrefixCls,
direction: directionConfig
} = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('space-addon', customizePrefixCls);
const [hashId, cssVarCls] = useStyle(prefixCls);
const {
compactItemClassnames,
compactSize
} = useCompactItemContext(prefixCls, directionConfig);
const statusCls = getStatusClassNames(prefixCls, status);
const classes = clsx(prefixCls, hashId, compactItemClassnames, cssVarCls, `${prefixCls}-variant-${variant}`, statusCls, {
[`${prefixCls}-${compactSize}`]: compactSize,
[`${prefixCls}-disabled`]: disabled
}, className);
return /*#__PURE__*/React.createElement("div", {
ref: ref,
className: classes,
style: style,
...restProps
}, children);
});
export default SpaceAddon;
+29
View File
@@ -0,0 +1,29 @@
import * as React from 'react';
import type { Orientation } from '../_util/hooks';
import type { DirectionType } from '../config-provider';
import type { SizeType } from '../config-provider/SizeContext';
export interface SpaceCompactItemContextType {
compactSize?: SizeType;
compactDirection?: 'horizontal' | 'vertical';
isFirstItem?: boolean;
isLastItem?: boolean;
}
export declare const SpaceCompactItemContext: React.Context<SpaceCompactItemContextType | null>;
export declare const useCompactItemContext: (prefixCls: string, direction: DirectionType) => {
compactSize: SizeType;
compactDirection: "horizontal" | "vertical" | undefined;
compactItemClassnames: string;
};
export declare const NoCompactStyle: React.FC<Readonly<React.PropsWithChildren>>;
export interface SpaceCompactProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
size?: SizeType;
/** @deprecated please use `orientation` instead */
direction?: Orientation;
orientation?: Orientation;
vertical?: boolean;
block?: boolean;
rootClassName?: string;
}
declare const Compact: React.FC<SpaceCompactProps>;
export default Compact;
+105
View File
@@ -0,0 +1,105 @@
"use client";
import * as React from 'react';
import { toArray } from '@rc-component/util';
import { clsx } from 'clsx';
import { useOrientation } from '../_util/hooks';
import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import useSize from '../config-provider/hooks/useSize';
import useStyle from './style/compact';
export const SpaceCompactItemContext = /*#__PURE__*/React.createContext(null);
export const useCompactItemContext = (prefixCls, direction) => {
const compactItemContext = React.useContext(SpaceCompactItemContext);
const compactItemClassnames = React.useMemo(() => {
if (!compactItemContext) {
return '';
}
const {
compactDirection,
isFirstItem,
isLastItem
} = compactItemContext;
const separator = compactDirection === 'vertical' ? '-vertical-' : '-';
return clsx(`${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 = props => {
const {
children
} = props;
return /*#__PURE__*/React.createElement(SpaceCompactItemContext.Provider, {
value: null
}, children);
};
const CompactItem = props => {
const {
children,
...others
} = props;
return /*#__PURE__*/React.createElement(SpaceCompactItemContext.Provider, {
value: React.useMemo(() => others, [others])
}, children);
};
const Compact = props => {
const {
getPrefixCls,
direction: directionConfig
} = React.useContext(ConfigContext);
const {
size,
direction,
orientation,
block,
prefixCls: customizePrefixCls,
className,
rootClassName,
children,
vertical,
...restProps
} = props;
// ======================== Warning ==========================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Space.Compact');
warning.deprecated(!direction, 'direction', 'orientation');
}
const [mergedOrientation, mergedVertical] = useOrientation(orientation, vertical, direction);
const mergedSize = useSize(ctx => size ?? ctx);
const prefixCls = getPrefixCls('space-compact', customizePrefixCls);
const [hashId] = useStyle(prefixCls);
const clx = clsx(prefixCls, hashId, {
[`${prefixCls}-rtl`]: directionConfig === 'rtl',
[`${prefixCls}-block`]: block,
[`${prefixCls}-vertical`]: mergedVertical
}, 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 /*#__PURE__*/React.createElement(CompactItem, {
key: key,
compactSize: mergedSize,
compactDirection: mergedOrientation,
isFirstItem: i === 0 && (!compactItemContext || compactItemContext?.isFirstItem),
isLastItem: i === childNodes.length - 1 && (!compactItemContext || compactItemContext?.isLastItem)
}, child);
}), [childNodes, compactItemContext, mergedOrientation, mergedSize, prefixCls]);
// =========================== Render ===========================
if (childNodes.length === 0) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
className: clx,
...restProps
}, nodes);
};
export default Compact;
+17
View File
@@ -0,0 +1,17 @@
import * as React from 'react';
export interface ItemProps {
className: string;
children: React.ReactNode;
prefix: string;
index: number;
separator?: React.ReactNode;
style?: React.CSSProperties;
classNames?: {
separator?: string;
};
styles?: {
separator?: React.CSSProperties;
};
}
declare const Item: React.FC<ItemProps>;
export default Item;
+32
View File
@@ -0,0 +1,32 @@
"use client";
import * as React from 'react';
import { clsx } from 'clsx';
import { isNonNullable } from '../_util/is';
import { SpaceContext } from './context';
const Item = props => {
const {
className,
prefix,
index,
children,
separator,
style,
classNames,
styles
} = props;
const {
latestIndex
} = React.useContext(SpaceContext);
if (!isNonNullable(children)) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: className,
style: style
}, children), index < latestIndex && separator && (/*#__PURE__*/React.createElement("span", {
className: clsx(`${prefix}-item-separator`, classNames?.separator),
style: styles?.separator
}, separator)));
};
export default Item;
+6
View File
@@ -0,0 +1,6 @@
import React from 'react';
export interface SpaceContextType {
latestIndex: number;
}
export declare const SpaceContext: React.Context<SpaceContextType>;
export declare const SpaceContextProvider: React.Provider<SpaceContextType>;
+5
View File
@@ -0,0 +1,5 @@
import React from 'react';
export const SpaceContext = /*#__PURE__*/React.createContext({
latestIndex: 0
});
export const SpaceContextProvider = SpaceContext.Provider;
+45
View File
@@ -0,0 +1,45 @@
import * as React from 'react';
import type { Orientation, SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { SizeType } from '../config-provider/SizeContext';
import Addon from './Addon';
import Compact from './Compact';
export { SpaceContext } from './context';
export type SpaceSize = SizeType | number;
export type SpaceSemanticName = keyof SpaceSemanticClassNames & keyof SpaceSemanticStyles;
export type SpaceSemanticClassNames = {
root?: string;
item?: string;
separator?: string;
};
export type SpaceSemanticStyles = {
root?: React.CSSProperties;
item?: React.CSSProperties;
separator?: React.CSSProperties;
};
export type SpaceClassNamesType = SemanticClassNamesType<SpaceProps, SpaceSemanticClassNames>;
export type SpaceStylesType = SemanticStylesType<SpaceProps, SpaceSemanticStyles>;
export interface SpaceProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
className?: string;
rootClassName?: string;
style?: React.CSSProperties;
size?: SpaceSize | [SpaceSize, SpaceSize];
/** @deprecated please use `orientation` instead */
direction?: Orientation;
vertical?: boolean;
orientation?: Orientation;
align?: 'start' | 'end' | 'center' | 'baseline';
/** @deprecated please use `separator` instead */
split?: React.ReactNode;
separator?: React.ReactNode;
wrap?: boolean;
classNames?: SpaceClassNamesType;
styles?: SpaceStylesType;
}
declare const InternalSpace: React.ForwardRefExoticComponent<SpaceProps & React.RefAttributes<HTMLDivElement>>;
type CompoundedComponent = typeof InternalSpace & {
Compact: typeof Compact;
Addon: typeof Addon;
};
declare const Space: CompoundedComponent;
export default Space;
+136
View File
@@ -0,0 +1,136 @@
"use client";
import * as React from 'react';
import { toArray } from '@rc-component/util';
import { clsx } from 'clsx';
import { isPresetSize, isValidGapNumber } from '../_util/gapSize';
import { useMergeSemantic, useOrientation } from '../_util/hooks';
import { isNonNullable } from '../_util/is';
import { devUseWarning } from '../_util/warning';
import { useComponentConfig } from '../config-provider/context';
import Addon from './Addon';
import Compact from './Compact';
import { SpaceContextProvider } from './context';
import Item from './Item';
import useStyle from './style';
export { SpaceContext } from './context';
const InternalSpace = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
getPrefixCls,
direction: directionConfig,
size: contextSize,
className: contextClassName,
style: contextStyle,
classNames: contextClassNames,
styles: contextStyles
} = useComponentConfig('space');
const {
size = contextSize ?? 'small',
align,
className,
rootClassName,
children,
direction,
orientation,
prefixCls: customizePrefixCls,
split,
separator,
style,
vertical,
wrap = false,
classNames,
styles,
...restProps
} = props;
const [horizontalSize, verticalSize] = Array.isArray(size) ? size : [size, size];
const isPresetVerticalSize = isPresetSize(verticalSize);
const isPresetHorizontalSize = isPresetSize(horizontalSize);
const isValidVerticalSize = isValidGapNumber(verticalSize);
const isValidHorizontalSize = isValidGapNumber(horizontalSize);
const childNodes = toArray(children, {
keepEmpty: true
});
const [mergedOrientation, mergedVertical] = useOrientation(orientation, vertical, direction);
const mergedAlign = align === undefined && !mergedVertical ? 'center' : align;
const mergedSeparator = separator ?? split;
const prefixCls = getPrefixCls('space', customizePrefixCls);
const [hashId, cssVarCls] = useStyle(prefixCls);
// =========== Merged Props for Semantic ==========
const mergedProps = {
...props,
size,
orientation: mergedOrientation,
align: mergedAlign
};
const [mergedClassNames, mergedStyles] = useMergeSemantic([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
});
const rootClassNames = clsx(prefixCls, contextClassName, hashId, `${prefixCls}-${mergedOrientation}`, {
[`${prefixCls}-rtl`]: directionConfig === 'rtl',
[`${prefixCls}-align-${mergedAlign}`]: mergedAlign,
[`${prefixCls}-gap-row-${verticalSize}`]: isPresetVerticalSize,
[`${prefixCls}-gap-col-${horizontalSize}`]: isPresetHorizontalSize
}, className, rootClassName, cssVarCls, mergedClassNames.root);
const itemClassName = clsx(`${prefixCls}-item`, mergedClassNames.item);
// Calculate latest one
const renderedItems = childNodes.map((child, i) => {
const key = child?.key || `${itemClassName}-${i}`;
return /*#__PURE__*/React.createElement(Item, {
prefix: prefixCls,
classNames: mergedClassNames,
styles: mergedStyles,
className: itemClassName,
key: key,
index: i,
separator: mergedSeparator,
style: mergedStyles.item
}, child);
});
// ======================== Warning ==========================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Space');
[['direction', 'orientation'], ['split', 'separator']].forEach(([deprecatedName, newName]) => {
warning.deprecated(!(deprecatedName in props), deprecatedName, newName);
});
}
const memoizedSpaceContext = React.useMemo(() => {
const calcLatestIndex = childNodes.reduce((latest, child, i) => isNonNullable(child) ? i : latest, 0);
return {
latestIndex: calcLatestIndex
};
}, [childNodes]);
// =========================== Render ===========================
if (childNodes.length === 0) {
return null;
}
const gapStyle = {};
if (wrap) {
gapStyle.flexWrap = 'wrap';
}
if (!isPresetHorizontalSize && isValidHorizontalSize) {
gapStyle.columnGap = horizontalSize;
}
if (!isPresetVerticalSize && isValidVerticalSize) {
gapStyle.rowGap = verticalSize;
}
return /*#__PURE__*/React.createElement("div", {
ref: ref,
className: rootClassNames,
style: {
...gapStyle,
...mergedStyles.root,
...contextStyle,
...style
},
...restProps
}, /*#__PURE__*/React.createElement(SpaceContextProvider, {
value: memoizedSpaceContext
}, renderedItems));
});
const Space = InternalSpace;
Space.Compact = Compact;
Space.Addon = Addon;
if (process.env.NODE_ENV !== 'production') {
Space.displayName = 'Space';
}
export default Space;
+5
View File
@@ -0,0 +1,5 @@
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
}
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+124
View File
@@ -0,0 +1,124 @@
import { genCompactItemStyle } from '../../style/compact-item';
import { genStyleHooks } from '../../theme/internal';
import { genCssVar } from '../../theme/util/genStyleUtils';
const genSpaceAddonStyle = token => {
const {
componentCls,
borderRadius,
paddingSM,
colorBorder,
paddingXS,
fontSizeLG,
fontSizeSM,
borderRadiusLG,
borderRadiusSM,
colorBgContainerDisabled,
lineWidth,
antCls
} = token;
const [varName, varRef] = genCssVar(antCls, 'space');
return {
[componentCls]: [
// ==========================================================
// == Base ==
// ==========================================================
{
display: 'inline-flex',
alignItems: 'center',
gap: 0,
whiteSpace: 'nowrap',
paddingInline: paddingSM,
margin: 0,
borderWidth: lineWidth,
borderStyle: 'solid',
borderRadius,
'&:hover': {
zIndex: 0
},
[`&${componentCls}-disabled`]: {
color: token.colorTextDisabled
},
'&-large': {
fontSize: fontSizeLG,
borderRadius: borderRadiusLG
},
'&-small': {
paddingInline: paddingXS,
borderRadius: borderRadiusSM,
fontSize: fontSizeSM
},
'&-compact-last-item': {
borderEndStartRadius: 0,
borderStartStartRadius: 0
},
'&-compact-first-item': {
borderEndEndRadius: 0,
borderStartEndRadius: 0
},
'&-compact-item:not(:first-child):not(:last-child)': {
borderRadius: 0
},
'&-compact-item:not(:last-child)': {
borderInlineEndWidth: 0
},
'&-compact-item:not(:first-child)': {
borderInlineStartWidth: 0
}
},
// ==========================================================
// == Variants ==
// ==========================================================
{
[varName('addon-border-color')]: colorBorder,
[varName('addon-background')]: colorBgContainerDisabled,
// Filled
[varName('addon-border-color-outlined')]: colorBorder,
[varName('addon-background-filled')]: colorBgContainerDisabled,
borderColor: varRef('addon-border-color'),
background: varRef('addon-background'),
// ======================= Outlined =======================
'&-variant-outlined': {
[varName('addon-border-color')]: varRef('addon-border-color-outlined')
},
// ======================== Filled ========================
'&-variant-filled': {
[varName('addon-border-color')]: 'transparent',
[varName('addon-background')]: varRef('addon-background-filled'),
// Disabled
[`&${componentCls}-disabled`]: {
[varName('addon-border-color')]: colorBorder,
[varName('addon-background')]: colorBgContainerDisabled
}
},
// ====================== Borderless ======================
'&-variant-borderless': {
border: 'none',
background: 'transparent'
},
// ====================== Underlined ======================
'&-variant-underlined': {
border: 'none',
background: 'transparent'
}
},
// ==========================================================
// == Status ==
// ==========================================================
{
'&-status-error': {
[varName('addon-border-color-outlined')]: token.colorError,
[varName('addon-background-filled')]: token.colorErrorBg,
color: token.colorError
},
'&-status-warning': {
[varName('addon-border-color-outlined')]: token.colorWarning,
[varName('addon-background-filled')]: token.colorWarningBg,
color: token.colorWarning
}
}]
};
};
// ============================== Export ==============================
export default genStyleHooks(['Space', 'Addon'], token => [genSpaceAddonStyle(token), genCompactItemStyle(token, {
focus: false
})]);
+5
View File
@@ -0,0 +1,5 @@
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
}
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+27
View File
@@ -0,0 +1,27 @@
import { genStyleHooks } from '../../theme/internal';
const genSpaceCompactStyle = token => {
const {
componentCls
} = token;
return {
[componentCls]: {
display: 'inline-flex',
'&-block': {
display: 'flex',
width: '100%'
},
'&-vertical': {
flexDirection: 'column'
},
'&-rtl': {
direction: 'rtl'
}
}
};
};
// ============================== Export ==============================
export default genStyleHooks(['Space', 'Compact'], genSpaceCompactStyle, () => ({}), {
// Space component don't apply extra font style
// https://github.com/ant-design/ant-design/issues/40315
resetStyle: false
});
+7
View File
@@ -0,0 +1,7 @@
import type { GetDefaultToken } from '../../theme/internal';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
}
export declare const prepareComponentToken: GetDefaultToken<'Space'>;
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+81
View File
@@ -0,0 +1,81 @@
import { genStyleHooks, mergeToken } from '../../theme/internal';
const genSpaceStyle = token => {
const {
componentCls,
antCls
} = token;
return {
[componentCls]: {
display: 'inline-flex',
'&-rtl': {
direction: 'rtl'
},
'&-vertical': {
flexDirection: 'column'
},
'&-align': {
flexDirection: 'column',
'&-center': {
alignItems: 'center'
},
'&-start': {
alignItems: 'flex-start'
},
'&-end': {
alignItems: 'flex-end'
},
'&-baseline': {
alignItems: 'baseline'
}
},
[`${componentCls}-item:empty`]: {
display: 'none'
},
// https://github.com/ant-design/ant-design/issues/47875
[`${componentCls}-item > ${antCls}-badge-not-a-wrapper:only-child`]: {
display: 'block'
}
}
};
};
const genSpaceGapStyle = token => {
const {
componentCls
} = token;
return {
[componentCls]: {
'&-gap-row-small': {
rowGap: token.spaceGapSmallSize
},
'&-gap-row-medium, &-gap-row-middle': {
rowGap: token.spaceGapMiddleSize
},
'&-gap-row-large': {
rowGap: token.spaceGapLargeSize
},
'&-gap-col-small': {
columnGap: token.spaceGapSmallSize
},
'&-gap-col-medium, &-gap-col-middle': {
columnGap: token.spaceGapMiddleSize
},
'&-gap-col-large': {
columnGap: token.spaceGapLargeSize
}
}
};
};
// ============================== Export ==============================
export const prepareComponentToken = () => ({});
export default genStyleHooks('Space', token => {
const spaceToken = mergeToken(token, {
spaceGapSmallSize: token.paddingXS,
spaceGapMiddleSize: token.padding,
spaceGapLargeSize: token.paddingLG
});
return [genSpaceStyle(spaceToken), genSpaceGapStyle(spaceToken)];
}, () => ({}), {
// Space component don't apply extra font style
// https://github.com/ant-design/ant-design/issues/40315
resetStyle: false
});