This commit is contained in:
Ngô Đức Trí 2025-06-04 12:07:42 +08:00 committed by GitHub
commit 8861315a7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 55 additions and 7 deletions

View File

@ -11,7 +11,7 @@ import { ConfigContext } from '../config-provider/context';
import DisabledContext from '../config-provider/DisabledContext';
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
import useSize from '../config-provider/hooks/useSize';
import { FormItemInputContext } from '../form/context';
import { FormItemPopupContext, FormItemInputContext } from '../form/context';
import type { PopoverProps } from '../popover';
import Popover from '../popover';
import { useCompactItemContext } from '../space/Compact';
@ -66,6 +66,8 @@ const ColorPicker: CompoundedComponent = (props) => {
} = props;
const { getPrefixCls, direction, colorPicker } = useContext<ConfigConsumerProps>(ConfigContext);
const { popupOpen: popupOpenContext, setPopupOpen: setPopupOpenContext } =
useContext(FormItemPopupContext);
const contextDisabled = useContext(DisabledContext);
const mergedDisabled = disabled ?? contextDisabled;
@ -80,6 +82,8 @@ const ColorPicker: CompoundedComponent = (props) => {
onChange: onFormatChange,
});
const mergedOpen = popupOpen || popupOpenContext;
const prefixCls = getPrefixCls('color-picker', customizePrefixCls);
// ================== Value & Mode =================
@ -205,7 +209,7 @@ const ColorPicker: CompoundedComponent = (props) => {
}
const popoverProps: PopoverProps = {
open: popupOpen,
open: mergedOpen,
trigger,
placement,
arrow,
@ -226,6 +230,7 @@ const ColorPicker: CompoundedComponent = (props) => {
onOpenChange={(visible) => {
if (!visible || !mergedDisabled) {
setPopupOpen(visible);
!visible && setPopupOpenContext(false);
}
}}
content={
@ -259,8 +264,8 @@ const ColorPicker: CompoundedComponent = (props) => {
>
{children || (
<ColorTrigger
activeIndex={popupOpen ? activeIndex : -1}
open={popupOpen}
activeIndex={mergedOpen ? activeIndex : -1}
open={mergedOpen}
className={mergedCls}
style={mergedStyle}
prefixCls={prefixCls}

View File

@ -0,0 +1,21 @@
import * as React from 'react';
import { FormItemPopupContext } from '../context';
interface PopupProviderProps {
children?: React.ReactNode;
}
export default function PopupProvider({ children }: PopupProviderProps) {
const [popupOpen, setPopupOpen] = React.useState(false);
const value = React.useMemo(
() => ({
popupOpen,
setPopupOpen,
}),
[popupOpen],
);
return <FormItemPopupContext.Provider value={value}>{children}</FormItemPopupContext.Provider>;
}

View File

@ -21,6 +21,7 @@ import useFrameState from '../hooks/useFrameState';
import useItemRef from '../hooks/useItemRef';
import useStyle from '../style';
import { getFieldId, toArray } from '../util';
import PopupProvider from './PopupProvider';
import type { ItemHolderProps } from './ItemHolder';
import ItemHolder from './ItemHolder';
import StatusProvider from './StatusProvider';
@ -283,8 +284,12 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
);
}
function popupDecorator(children: React.ReactNode): React.ReactNode {
return <PopupProvider>{children}</PopupProvider>;
}
if (!hasName && !isRenderProps && !dependencies) {
return wrapCSSVar(renderLayout(mergedChildren) as JSX.Element);
return wrapCSSVar(popupDecorator(renderLayout(mergedChildren)) as JSX.Element);
}
let variables: Record<string, string> = {};
@ -442,7 +447,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
childNode = mergedChildren as React.ReactNode;
}
return renderLayout(childNode, fieldId, isRequired);
return popupDecorator(renderLayout(childNode, fieldId, isRequired));
}}
</Field>,
);

View File

@ -10,7 +10,7 @@ import defaultLocale from '../locale/en_US';
import type { TooltipProps } from '../tooltip';
import Tooltip from '../tooltip';
import type { FormContextProps } from './context';
import { FormContext } from './context';
import { FormContext, FormItemPopupContext } from './context';
import type { RequiredMark } from './Form';
import type { FormLabelAlign } from './interface';
@ -48,6 +48,12 @@ const FormItemLabel: React.FC<FormItemLabelProps & { required?: boolean; prefixC
}) => {
const [formLocale] = useLocale('Form');
const { setPopupOpen } = React.useContext(FormItemPopupContext);
const onClick = () => {
setPopupOpen(true);
};
const {
labelAlign: contextLabelAlign,
labelCol: contextLabelCol,
@ -150,6 +156,7 @@ const FormItemLabel: React.FC<FormItemLabelProps & { required?: boolean; prefixC
htmlFor={htmlFor}
className={labelClassName}
title={typeof label === 'string' ? label : ''}
onClick={onClick}
>
{labelChildren}
</label>

View File

@ -100,3 +100,13 @@ export const NoFormStyle: React.FC<NoFormStyleProps> = ({ children, status, over
};
export const VariantContext = React.createContext<Variant | undefined>(undefined);
interface FormItemPopupContextProps {
popupOpen?: boolean;
setPopupOpen: React.Dispatch<React.SetStateAction<boolean>>;
}
export const FormItemPopupContext = React.createContext<FormItemPopupContextProps>({
popupOpen: false,
setPopupOpen: () => {},
});