分离ContextMenu的菜单体。

This commit is contained in:
徐涛 2025-03-31 21:55:20 +08:00
parent 036b9fead6
commit 56ba55a4ca

View File

@ -1,7 +1,16 @@
import { SwatchEntry } from 'color-module';
import { useAtomValue, useSetAtom } from 'jotai';
import { capitalize, size } from 'lodash-es';
import { FC, MouseEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
FC,
MouseEvent,
RefObject,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { MaterialDesign2SchemeSource } from '../material-2-scheme';
import {
MaterialDesign3DynamicSchemeSource,
@ -225,6 +234,45 @@ const Material3SchemeMenu: FC<ContextMenuItemProps> = ({ color, afterClick }) =>
);
};
interface ContextMenuBodyProps {
color: string;
afterClick?: () => void;
x?: number;
y?: number;
ref?: RefObject<HTMLDivElement>;
}
export const ContextMenuBody: FC<ContextMenuBodyProps> = ({ color, afterClick, x, y, ref }) => {
const activeScheme = useActiveScheme();
const schemeMenu = useMemo(() => {
const sharedProps: ContextMenuItemProps = {
color,
afterClick,
};
switch (activeScheme?.type) {
case 'q_scheme':
return <QSchemeMenu {...sharedProps} />;
case 'swatch_scheme':
return <SwatchSchemeMenu {...sharedProps} />;
case 'material_2':
return <Material2SchemeMenu {...sharedProps} />;
case 'material_3':
case 'material_3_dynamic':
return <Material3SchemeMenu {...sharedProps} />;
default:
return null;
}
}, [activeScheme, color, afterClick]);
return (
<div className={styles.menu_body} ref={ref} style={{ top: y, left: x }}>
<SetPickerMenu color={color} afterClick={afterClick} />
{schemeMenu}
</div>
);
};
interface ContextMenuProps {
color: string;
}
@ -236,7 +284,6 @@ const ContextMenu: FC<ContextMenuProps> = ({ color }) => {
const containerRef = useRef<HTMLDivElement>(null);
const triggerRef = useRef<HTMLButtonElement>(null);
const menuRef = useRef<HTMLDivElement>(null);
const activeScheme = useActiveScheme();
const handleOpenMenu = () => {
if (isOpen) {
@ -278,26 +325,6 @@ const ContextMenu: FC<ContextMenuProps> = ({ color }) => {
[handleCloseMenu, isOpen],
);
const schemeMenu = useMemo(() => {
const sharedProps: ContextMenuItemProps = {
color,
afterClick: handleCloseMenu,
};
switch (activeScheme?.type) {
case 'q_scheme':
return <QSchemeMenu {...sharedProps} />;
case 'swatch_scheme':
return <SwatchSchemeMenu {...sharedProps} />;
case 'material_2':
return <Material2SchemeMenu {...sharedProps} />;
case 'material_3':
case 'material_3_dynamic':
return <Material3SchemeMenu {...sharedProps} />;
default:
return null;
}
}, [activeScheme]);
useEffect(() => {
if (isOpen && menuRef.current && containerRef.current && triggerRef.current) {
const menuElemenet = menuRef.current;
@ -348,13 +375,13 @@ const ContextMenu: FC<ContextMenuProps> = ({ color }) => {
ref={triggerRef}
/>
{isOpen && (
<div
className={styles.menu_body}
<ContextMenuBody
color={color}
afterClick={handleCloseMenu}
x={renderPosition.x}
y={renderPosition.y}
ref={menuRef}
style={{ top: renderPosition.y, left: renderPosition.x }}>
<SetPickerMenu color={color} afterClick={handleCloseMenu} />
{schemeMenu}
</div>
/>
)}
</div>
);