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 7991d1c569629a6f458a4d5145a8df3f581bb27d.

* chore: ignore types check to avoid build error
This commit is contained in:
被雨水过滤的空气-Rairn 2023-06-25 19:18:22 +08:00 committed by GitHub
parent 55b3681bba
commit 73f3929b4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 51 deletions

View File

@ -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,42 +63,36 @@ 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);
const buttonDom = component ? (
component
) : (
<Button
type={'dashed'}
style={{
borderColor: '#f18b62',
color: '#f18b62',
...style,
}}
{...others}
icon={typeof icon === 'string' ? <Icon type={icon as string} /> : icon}
>
{component ? (
component
) : (
<Button
type={'dashed'}
style={{
borderColor: '#f18b62',
color: '#f18b62',
...style,
}}
{...others}
icon={typeof icon === 'string' ? <Icon type={icon as string} /> : icon}
>
{compile(props.children || props.title)}
</Button>
)}
</div>
{compile(props.children || props.title)}
</Button>
);
if (!shouldRender || !items.length) {
return buttonDom;
}
const insertSchema = (schema) => {
if (insert) {
@ -169,12 +170,14 @@ SchemaInitializer.Button = observer(
});
};
clean();
const menuItems = renderItems(items);
if (visible) {
clean();
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}
>

View File

@ -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}