mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 10:17:00 +00:00
fix: fix the drop-down menu does not disapper (#2109)
* fix: should delay show menu to avoid the menu not hidden
* fix(mouseEnterDelay): change default value from 100 to 150
* chore: upgrade types for react
* fix: fix the drop-down menu does not disapper
* Revert "chore: upgrade types for react"
This reverts commit 7991d1c569
.
* chore: ignore types check to avoid build error
This commit is contained in:
parent
55b3681bba
commit
73f3929b4f
@ -3,7 +3,8 @@ import { ISchema, observer, useForm } from '@formily/react';
|
||||
import { error, isString } from '@nocobase/utils/client';
|
||||
import { Button, Dropdown, MenuProps, Switch } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
||||
// @ts-ignore
|
||||
import React, { createContext, useCallback, useContext, useMemo, useRef, useState, useTransition } from 'react';
|
||||
import { useCollectMenuItem, useMenuItem } from '../hooks/useMenuItem';
|
||||
import { Icon } from '../icon';
|
||||
import { SchemaComponent, useActionContext } from '../schema-component';
|
||||
@ -22,6 +23,12 @@ const overlayClassName = css`
|
||||
overflow: auto;
|
||||
}
|
||||
`;
|
||||
/**
|
||||
* 用于去除菜单的消失动画,优化操作体验
|
||||
*/
|
||||
const hidden = css`
|
||||
display: none;
|
||||
`;
|
||||
|
||||
const defaultWrap = (s: ISchema) => s;
|
||||
|
||||
@ -56,22 +63,21 @@ SchemaInitializer.Button = observer(
|
||||
const { insertAdjacent, findComponent, designable } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { Component: CollectionComponent, getMenuItem, clean } = useMenuItem();
|
||||
const [shouldRender, setShouldRender] = useState(false);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const menuItems = useRef([]);
|
||||
|
||||
const changeMenu = (v: boolean) => {
|
||||
startTransition(() => {
|
||||
setVisible(v);
|
||||
});
|
||||
};
|
||||
|
||||
if (!designable && props.designable !== true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const buttonDom = (
|
||||
<div
|
||||
style={{ display: 'inline-block' }}
|
||||
onMouseEnter={() => {
|
||||
setShouldRender(true);
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
{component ? (
|
||||
const buttonDom = component ? (
|
||||
component
|
||||
) : (
|
||||
<Button
|
||||
@ -86,12 +92,7 @@ SchemaInitializer.Button = observer(
|
||||
>
|
||||
{compile(props.children || props.title)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
if (!shouldRender || !items.length) {
|
||||
return buttonDom;
|
||||
}
|
||||
|
||||
const insertSchema = (schema) => {
|
||||
if (insert) {
|
||||
@ -169,12 +170,14 @@ SchemaInitializer.Button = observer(
|
||||
});
|
||||
};
|
||||
|
||||
if (visible) {
|
||||
clean();
|
||||
const menuItems = renderItems(items);
|
||||
menuItems.current = renderItems(items);
|
||||
}
|
||||
|
||||
return (
|
||||
<SchemaInitializerButtonContext.Provider value={{ visible, setVisible, searchValue, setSearchValue }}>
|
||||
<CollectionComponent />
|
||||
{visible ? <CollectionComponent /> : null}
|
||||
<Dropdown
|
||||
className={classNames('nb-schema-initializer-button')}
|
||||
openClassName={`nb-schema-initializer-button-open`}
|
||||
@ -183,15 +186,15 @@ SchemaInitializer.Button = observer(
|
||||
onOpenChange={() => {
|
||||
// 如果不清空输入框的值,那么下次打开的时候会出现上次输入的值
|
||||
setSearchValue('');
|
||||
setShouldRender(false);
|
||||
setVisible(false);
|
||||
changeMenu(!visible);
|
||||
}}
|
||||
menu={{
|
||||
style: {
|
||||
maxHeight: '60vh',
|
||||
overflowY: 'auto',
|
||||
},
|
||||
items: menuItems,
|
||||
className: classNames({ [hidden]: !visible }),
|
||||
items: menuItems.current,
|
||||
}}
|
||||
{...dropdown}
|
||||
>
|
||||
|
@ -20,7 +20,17 @@ import {
|
||||
} from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import _, { cloneDeep } from 'lodash';
|
||||
import React, { ReactNode, createContext, useCallback, useContext, useMemo, useState } from 'react';
|
||||
import React, {
|
||||
ReactNode,
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
// @ts-ignore
|
||||
useTransition as useReactTransition,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
@ -75,6 +85,13 @@ interface SchemaSettingsContextProps {
|
||||
|
||||
const SchemaSettingsContext = createContext<SchemaSettingsContextProps>(null);
|
||||
|
||||
/**
|
||||
* 用于去除菜单的消失动画,优化操作体验
|
||||
*/
|
||||
const hidden = css`
|
||||
display: none;
|
||||
`;
|
||||
|
||||
export const useSchemaSettings = () => {
|
||||
return useContext(SchemaSettingsContext);
|
||||
};
|
||||
@ -131,31 +148,28 @@ export const SchemaSettings: React.FC<SchemaSettingsProps> & SchemaSettingsNeste
|
||||
const { title, dn, ...others } = props;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { Component, getMenuItems } = useMenuItem();
|
||||
const [shouldRender, setShouldRender] = useState(false);
|
||||
const menuItems = useRef([]);
|
||||
const [isPending, startTransition] = useReactTransition();
|
||||
|
||||
if (!shouldRender) {
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={() => {
|
||||
setShouldRender(true);
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
{typeof title === 'string' ? <span>{title}</span> : title}
|
||||
</div>
|
||||
);
|
||||
const changeMenu = (v: boolean) => {
|
||||
startTransition(() => {
|
||||
setVisible(v);
|
||||
});
|
||||
};
|
||||
|
||||
if (visible) {
|
||||
menuItems.current = getMenuItems(() => props.children);
|
||||
}
|
||||
|
||||
const dropdownMenu = () => (
|
||||
<>
|
||||
<Component />
|
||||
{visible ? <Component /> : null}
|
||||
<Dropdown
|
||||
open={visible}
|
||||
onOpenChange={() => {
|
||||
setShouldRender(false);
|
||||
setVisible(false);
|
||||
changeMenu(!visible);
|
||||
}}
|
||||
menu={{ items: getMenuItems(() => props.children) }}
|
||||
menu={{ items: menuItems.current, className: classNames({ [hidden]: !visible }) }}
|
||||
overlayClassName={overlayClassName}
|
||||
>
|
||||
{typeof title === 'string' ? <span>{title}</span> : title}
|
||||
|
Loading…
Reference in New Issue
Block a user