feat: add useNiceDropdownMaxHeight

This commit is contained in:
Zeke Zhang 2024-01-18 12:28:49 +08:00
parent e7e47f90fd
commit 9fdd88c479
3 changed files with 36 additions and 13 deletions

View File

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

View 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;
};

View File

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