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
+19
View File
@@ -0,0 +1,19 @@
import * as React from 'react';
import type { PopoverProps, PopoverSemanticClassNames, PopoverSemanticStyles } from '.';
interface OverlayProps {
prefixCls?: string;
title?: React.ReactNode;
content?: React.ReactNode;
classNames?: PopoverSemanticClassNames;
styles?: PopoverSemanticStyles;
}
export declare const Overlay: React.FC<OverlayProps>;
export interface PurePanelProps extends Omit<PopoverProps, 'children'> {
children?: React.ReactNode;
}
interface RawPurePanelProps extends PopoverProps {
hashId: string;
}
export declare const RawPurePanel: React.FC<RawPurePanelProps>;
declare const PurePanel: React.FC<PurePanelProps>;
export default PurePanel;
+89
View File
@@ -0,0 +1,89 @@
"use client";
import * as React from 'react';
import { Popup } from '@rc-component/tooltip';
import { clsx } from 'clsx';
import { getRenderPropValue } from '../_util/getRenderPropValue';
import { useMergeSemantic } from '../_util/hooks';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
export const Overlay = props => {
const {
title,
content,
prefixCls,
classNames,
styles
} = props;
if (!title && !content) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, title && (/*#__PURE__*/React.createElement("div", {
className: clsx(`${prefixCls}-title`, classNames?.title),
style: styles?.title
}, title)), content && (/*#__PURE__*/React.createElement("div", {
className: clsx(`${prefixCls}-content`, classNames?.content),
style: styles?.content
}, content)));
};
export const RawPurePanel = props => {
const {
hashId,
prefixCls,
className,
style,
placement = 'top',
title,
content,
children,
classNames,
styles
} = props;
const titleNode = getRenderPropValue(title);
const contentNode = getRenderPropValue(content);
const mergedProps = {
...props,
placement
};
const [mergedClassNames, mergedStyles] = useMergeSemantic([classNames], [styles], {
props: mergedProps
});
const rootClassName = clsx(hashId, prefixCls, `${prefixCls}-pure`, `${prefixCls}-placement-${placement}`, className);
return /*#__PURE__*/React.createElement("div", {
className: rootClassName,
style: style
}, /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-arrow`
}), /*#__PURE__*/React.createElement(Popup, {
...props,
className: hashId,
prefixCls: prefixCls,
classNames: mergedClassNames,
styles: mergedStyles
}, children || (/*#__PURE__*/React.createElement(Overlay, {
prefixCls: prefixCls,
title: titleNode,
content: contentNode,
classNames: mergedClassNames,
styles: mergedStyles
}))));
};
const PurePanel = props => {
const {
prefixCls: customizePrefixCls,
className,
...restProps
} = props;
const {
getPrefixCls
} = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('popover', customizePrefixCls);
const [hashId, cssVarCls] = useStyle(prefixCls);
return /*#__PURE__*/React.createElement(RawPurePanel, {
...restProps,
prefixCls: prefixCls,
hashId: hashId,
className: clsx(className, cssVarCls)
});
};
export default PurePanel;
+29
View File
@@ -0,0 +1,29 @@
import * as React from 'react';
import type { RenderFunction } from '../_util/getRenderPropValue';
import type { SemanticClassNamesType, SemanticStylesType } from '../_util/hooks';
import type { AbstractTooltipProps, TooltipRef, TooltipSemanticClassNames, TooltipSemanticStyles } from '../tooltip';
import PurePanel from './PurePanel';
export type PopoverSemanticName = keyof PopoverSemanticClassNames & keyof PopoverSemanticStyles;
export type PopoverSemanticClassNames = TooltipSemanticClassNames & {
title?: string;
content?: string;
};
export type PopoverSemanticStyles = TooltipSemanticStyles & {
title?: React.CSSProperties;
content?: React.CSSProperties;
};
export type PopoverClassNamesType = SemanticClassNamesType<PopoverProps, PopoverSemanticClassNames>;
export type PopoverStylesType = SemanticStylesType<PopoverProps, PopoverSemanticStyles>;
export interface PopoverProps extends AbstractTooltipProps {
title?: React.ReactNode | RenderFunction;
content?: React.ReactNode | RenderFunction;
onOpenChange?: (open: boolean) => void;
classNames?: PopoverClassNamesType;
styles?: PopoverStylesType;
}
declare const InternalPopover: React.ForwardRefExoticComponent<PopoverProps & React.RefAttributes<TooltipRef>>;
type CompoundedComponent = typeof InternalPopover & {
_InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel;
};
declare const Popover: CompoundedComponent;
export default Popover;
+120
View File
@@ -0,0 +1,120 @@
"use client";
import * as React from 'react';
import { useControlledState } from '@rc-component/util';
import { clsx } from 'clsx';
import { getRenderPropValue } from '../_util/getRenderPropValue';
import { useMergeSemantic } from '../_util/hooks';
import { getTransitionName } from '../_util/motion';
import { devUseWarning } from '../_util/warning';
import { useComponentConfig } from '../config-provider/context';
import Tooltip from '../tooltip';
import useMergedArrow from '../tooltip/hook/useMergedArrow';
import PurePanel, { Overlay } from './PurePanel';
// CSSINJS
import useStyle from './style';
const InternalPopover = /*#__PURE__*/React.forwardRef((props, ref) => {
const {
prefixCls: customizePrefixCls,
title,
content,
overlayClassName,
placement = 'top',
trigger,
children,
mouseEnterDelay = 0.1,
mouseLeaveDelay = 0.1,
onOpenChange,
overlayStyle = {},
styles,
classNames,
motion,
arrow: popoverArrow,
...restProps
} = props;
const {
getPrefixCls,
className: contextClassName,
style: contextStyle,
classNames: contextClassNames,
styles: contextStyles,
arrow: contextArrow,
trigger: contextTrigger
} = useComponentConfig('popover');
const prefixCls = getPrefixCls('popover', customizePrefixCls);
const [hashId, cssVarCls] = useStyle(prefixCls);
const rootPrefixCls = getPrefixCls();
const mergedArrow = useMergedArrow(popoverArrow, contextArrow);
const mergedTrigger = trigger || contextTrigger || 'hover';
// ========================== Warning ===========================
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Popover');
process.env.NODE_ENV !== "production" ? warning(!onOpenChange || onOpenChange.length <= 1, 'usage', 'The second `onOpenChange` parameter is internal and unsupported. Please lock to a previous version if needed.') : void 0;
}
// ============================= Styles =============================
const mergedProps = {
...props,
placement,
trigger: mergedTrigger,
mouseEnterDelay,
mouseLeaveDelay,
overlayStyle,
styles,
classNames
};
const [mergedClassNames, mergedStyles] = useMergeSemantic([contextClassNames, classNames], [contextStyles, styles], {
props: mergedProps
});
const rootClassNames = clsx(overlayClassName, hashId, cssVarCls, contextClassName, mergedClassNames.root);
const [open, setOpen] = useControlledState(props.defaultOpen ?? false, props.open);
const settingOpen = value => {
setOpen(value);
onOpenChange?.(value);
};
const titleNode = getRenderPropValue(title);
const contentNode = getRenderPropValue(content);
return /*#__PURE__*/React.createElement(Tooltip, {
unique: false,
arrow: mergedArrow,
placement: placement,
trigger: mergedTrigger,
mouseEnterDelay: mouseEnterDelay,
mouseLeaveDelay: mouseLeaveDelay,
...restProps,
prefixCls: prefixCls,
classNames: {
root: rootClassNames,
container: mergedClassNames.container,
arrow: mergedClassNames.arrow
},
styles: {
root: {
...mergedStyles.root,
...contextStyle,
...overlayStyle
},
container: mergedStyles.container,
arrow: mergedStyles.arrow
},
ref: ref,
open: open,
onOpenChange: settingOpen,
overlay: titleNode || contentNode ? (/*#__PURE__*/React.createElement(Overlay, {
prefixCls: prefixCls,
title: titleNode,
content: contentNode,
classNames: mergedClassNames,
styles: mergedStyles
})) : null,
motion: {
motionName: getTransitionName(rootPrefixCls, 'zoom-big', typeof motion?.motionName === 'string' ? motion?.motionName : undefined)
},
"data-popover-inject": true
}, children);
});
const Popover = InternalPopover;
Popover._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
if (process.env.NODE_ENV !== 'production') {
Popover.displayName = 'Popover';
}
export default Popover;
+46
View File
@@ -0,0 +1,46 @@
import type { ArrowOffsetToken } from '../../style/placementArrow';
import type { ArrowToken } from '../../style/roundedArrow';
import type { FullToken, GetDefaultToken } from '../../theme/internal';
export interface ComponentToken extends ArrowToken, ArrowOffsetToken {
/**
* @deprecated Please use `titleMinWidth` instead
* @desc 气泡卡片宽度
* @descEN Width of Popover
*/
width?: number | string;
/**
* @deprecated Please use `titleMinWidth` instead
* @desc 气泡卡片最小宽度
* @descEN Min width of Popover
*/
minWidth?: number | string;
/**
* @desc 气泡卡片标题最小宽度
* @descEN Min width of Popover title
*/
titleMinWidth: number | string;
/**
* @desc 气泡卡片 z-index
* @descEN z-index of Popover
*/
zIndexPopup: number;
}
/**
* @desc Popover 组件的 Token
* @descEN Token for Popover component
*/
export type PopoverToken = FullToken<'Popover'> & {
/**
* @desc 气泡卡片背景色
* @descEN Background color of Popover
*/
popoverBg: string;
/**
* @desc 气泡卡片文字颜色
* @descEN Text color of Popover
*/
popoverColor: string;
};
export declare const prepareComponentToken: GetDefaultToken<'Popover'>;
declare const _default: (prefixCls: string, rootCls?: string) => readonly [string, string];
export default _default;
+162
View File
@@ -0,0 +1,162 @@
import { resetComponent } from '../../style';
import { initZoomMotion } from '../../style/motion';
import getArrowStyle, { getArrowOffsetToken } from '../../style/placementArrow';
import { getArrowToken } from '../../style/roundedArrow';
import { genStyleHooks, mergeToken, PresetColors } from '../../theme/internal';
import { genCssVar } from '../../theme/util/genStyleUtils';
const FALL_BACK_ORIGIN = '50%';
const genBaseStyle = token => {
const {
componentCls,
popoverColor,
titleMinWidth,
fontWeightStrong,
innerPadding,
boxShadowSecondary,
colorTextHeading,
borderRadiusLG,
zIndexPopup,
titleMarginBottom,
colorBgElevated,
popoverBg,
titleBorderBottom,
innerContentPadding,
titlePadding,
antCls
} = token;
const [varName, varRef] = genCssVar(antCls, 'tooltip');
return [{
[componentCls]: {
...resetComponent(token),
position: 'absolute',
top: 0,
// use `left` to fix https://github.com/ant-design/ant-design/issues/39195
left: {
_skip_check_: true,
value: 0
},
zIndex: zIndexPopup,
fontWeight: 'normal',
whiteSpace: 'normal',
textAlign: 'start',
cursor: 'auto',
userSelect: 'text',
// When use `autoArrow`, origin will follow the arrow position
[varName('valid-offset-x')]: varRef('arrow-offset-x', 'var(--arrow-x)'),
transformOrigin: [varRef('valid-offset-x', FALL_BACK_ORIGIN), `var(--arrow-y, ${FALL_BACK_ORIGIN})`].join(' '),
[varName('arrow-background-color')]: colorBgElevated,
width: 'max-content',
maxWidth: '100vw',
'&-rtl': {
direction: 'rtl'
},
'&-hidden': {
display: 'none'
},
[`${componentCls}-content`]: {
position: 'relative'
},
[`${componentCls}-container`]: {
backgroundColor: popoverBg,
backgroundClip: 'padding-box',
borderRadius: borderRadiusLG,
boxShadow: boxShadowSecondary,
padding: innerPadding
},
[`${componentCls}-title`]: {
minWidth: titleMinWidth,
marginBottom: titleMarginBottom,
color: colorTextHeading,
fontWeight: fontWeightStrong,
borderBottom: titleBorderBottom,
padding: titlePadding
},
[`${componentCls}-content`]: {
color: popoverColor,
padding: innerContentPadding
}
}
},
// Arrow Style
getArrowStyle(token, varRef('arrow-background-color')),
// Pure Render
{
[`${componentCls}-pure`]: {
position: 'relative',
maxWidth: 'none',
margin: token.sizePopupArrow,
display: 'inline-block'
}
}];
};
const genColorStyle = token => {
const {
componentCls,
antCls
} = token;
const [varName] = genCssVar(antCls, 'tooltip');
return {
[componentCls]: PresetColors.map(colorKey => {
const lightColor = token[`${colorKey}6`];
return {
[`&${componentCls}-${colorKey}`]: {
[varName('arrow-background-color')]: lightColor,
[`${componentCls}-inner`]: {
backgroundColor: lightColor
},
[`${componentCls}-arrow`]: {
background: 'transparent'
}
}
};
})
};
};
export const prepareComponentToken = token => {
const {
lineWidth,
controlHeight,
fontHeight,
padding,
wireframe,
zIndexPopupBase,
borderRadiusLG,
marginXS,
lineType,
colorSplit,
paddingSM
} = token;
const titlePaddingBlockDist = controlHeight - fontHeight;
const popoverTitlePaddingBlockTop = titlePaddingBlockDist / 2;
const popoverTitlePaddingBlockBottom = titlePaddingBlockDist / 2 - lineWidth;
const popoverPaddingHorizontal = padding;
return {
titleMinWidth: 177,
zIndexPopup: zIndexPopupBase + 30,
...getArrowToken(token),
...getArrowOffsetToken({
contentRadius: borderRadiusLG,
limitVerticalRadius: true
}),
// internal
innerPadding: wireframe ? 0 : 12,
titleMarginBottom: wireframe ? 0 : marginXS,
titlePadding: wireframe ? `${popoverTitlePaddingBlockTop}px ${popoverPaddingHorizontal}px ${popoverTitlePaddingBlockBottom}px` : 0,
titleBorderBottom: wireframe ? `${lineWidth}px ${lineType} ${colorSplit}` : 'none',
innerContentPadding: wireframe ? `${paddingSM}px ${popoverPaddingHorizontal}px` : 0
};
};
export default genStyleHooks('Popover', token => {
const {
colorBgElevated,
colorText
} = token;
const popoverToken = mergeToken(token, {
popoverBg: colorBgElevated,
popoverColor: colorText
});
return [genBaseStyle(popoverToken), genColorStyle(popoverToken), initZoomMotion(popoverToken, 'zoom-big')];
}, prepareComponentToken, {
resetStyle: false,
deprecatedTokens: [['width', 'titleMinWidth'], ['minWidth', 'titleMinWidth']]
});