mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 14:26:36 +00:00
feat: add useNiceDropdownMaxHeight
This commit is contained in:
parent
e7e47f90fd
commit
9fdd88c479
@ -3,6 +3,7 @@ import { ConfigProvider, Popover, theme } from 'antd';
|
||||
import React, { ComponentType, useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { css } from '@emotion/css';
|
||||
import { useNiceDropdownMaxHeight } from '../../../common/useNiceDropdownHeight';
|
||||
import { useFlag } from '../../../flag-provider';
|
||||
import { useDesignable } from '../../../schema-component';
|
||||
import { useSchemaInitializerStyles } from '../components/style';
|
||||
@ -45,6 +46,7 @@ export function withInitializer<T>(C: ComponentType<T>) {
|
||||
const { wrapSSR, hashId, componentCls } = useSchemaInitializerStyles();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { token } = theme.useToken();
|
||||
const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]);
|
||||
|
||||
const cProps = useMemo(
|
||||
() => ({
|
||||
@ -90,9 +92,8 @@ export function withInitializer<T>(C: ComponentType<T>) {
|
||||
<div
|
||||
className={`${componentCls} ${hashId}`}
|
||||
style={{
|
||||
maxHeight: 'calc(50vh - 50px)',
|
||||
maxHeight: dropdownMaxHeight,
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
}}
|
||||
>
|
||||
<ConfigProvider
|
||||
|
30
packages/core/client/src/common/useNiceDropdownHeight.ts
Normal file
30
packages/core/client/src/common/useNiceDropdownHeight.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
/**
|
||||
* 通过鼠标的位置计算出最佳的 dropdown 的高度,以尽量避免出现滚动条
|
||||
* @param deps 类似于 useEffect 的第二个参数,如果不传则默认为 []
|
||||
*/
|
||||
export const useNiceDropdownMaxHeight = (deps: any[] = []) => {
|
||||
const [maxHeight, setMaxHeight] = useState(0);
|
||||
const heightRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e: MouseEvent) => {
|
||||
const { clientY } = e;
|
||||
const h = Math.max(clientY, window.innerHeight - clientY);
|
||||
heightRef.current = h;
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', handler);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', handler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setMaxHeight(heightRef.current);
|
||||
}, deps);
|
||||
|
||||
return maxHeight - 40;
|
||||
};
|
@ -76,6 +76,7 @@ import {
|
||||
} from '../block-provider/hooks';
|
||||
import { useCollectionFilterOptionsV2 } from '../collection-manager/action-hooks';
|
||||
import { SelectWithTitle, SelectWithTitleProps } from '../common/SelectWithTitle';
|
||||
import { useNiceDropdownMaxHeight } from '../common/useNiceDropdownHeight';
|
||||
import {
|
||||
FilterBlockType,
|
||||
getSupportFieldsByAssociation,
|
||||
@ -156,12 +157,9 @@ export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = (props) =>
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { Component, getMenuItems } = useMenuItem();
|
||||
const [, startTransition] = useReactTransition();
|
||||
const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]);
|
||||
|
||||
const changeMenu: DropdownProps['onOpenChange'] = (nextOpen: boolean, info) => {
|
||||
// 在 antd v5.8.6 版本中,点击菜单项不会触发菜单关闭,但是升级到 v5.12.2 后会触发关闭。查阅文档发现
|
||||
// 在 v5.11.0 版本中增加了一个 info.source,可以通过这个来判断一下,如果是点击的是菜单项就不关闭菜单,
|
||||
// 这样就可以和之前的行为保持一致了。
|
||||
// 下面是模仿官方文档示例做的修改:https://ant.design/components/dropdown-cn
|
||||
if (info.source === 'trigger' || nextOpen) {
|
||||
// 当鼠标快速滑过时,终止菜单的渲染,防止卡顿
|
||||
startTransition(() => {
|
||||
@ -180,13 +178,7 @@ export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = (props) =>
|
||||
onOpenChange={(open, info) => {
|
||||
changeMenu(open, info);
|
||||
}}
|
||||
overlayClassName={css`
|
||||
.ant-dropdown-menu-item-group-list {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`}
|
||||
menu={{ items }}
|
||||
menu={{ items, style: { maxHeight: dropdownMaxHeight, overflowY: 'auto' } }}
|
||||
>
|
||||
<div data-testid={props['data-testid']}>{typeof title === 'string' ? <span>{title}</span> : title}</div>
|
||||
</Dropdown>
|
||||
|
Loading…
Reference in New Issue
Block a user