mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
fix(console): set height limit to language dropdown (#3752)
This commit is contained in:
parent
5581f64768
commit
e665d5990c
2 changed files with 40 additions and 6 deletions
|
@ -29,14 +29,14 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -4px;
|
top: -4px;
|
||||||
right: calc(100% + 5px);
|
right: calc(100% + 5px);
|
||||||
display: none;
|
visibility: hidden;
|
||||||
background: var(--color-float);
|
background: var(--color-float);
|
||||||
border: 1px solid var(--color-divider);
|
border: 1px solid var(--color-divider);
|
||||||
border-radius: _.unit(2);
|
border-radius: _.unit(2);
|
||||||
box-shadow: var(--shadow-2);
|
box-shadow: var(--shadow-2);
|
||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
display: block;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import type { AdminConsoleKey } from '@logto/phrases';
|
import type { AdminConsoleKey } from '@logto/phrases';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { ReactNode } from 'react';
|
import { type ReactNode, useCallback, useEffect, useState, useRef } from 'react';
|
||||||
import { useState, useRef } from 'react';
|
|
||||||
|
|
||||||
import ArrowRight from '@/assets/images/arrow-right.svg';
|
import ArrowRight from '@/assets/images/arrow-right.svg';
|
||||||
import Tick from '@/assets/images/tick.svg';
|
import Tick from '@/assets/images/tick.svg';
|
||||||
import { DropdownItem } from '@/components/Dropdown';
|
import { DropdownItem } from '@/components/Dropdown';
|
||||||
import DynamicT from '@/components/DynamicT';
|
import DynamicT from '@/components/DynamicT';
|
||||||
|
import OverlayScrollbar from '@/components/OverlayScrollbar';
|
||||||
import type { Option } from '@/components/Select';
|
import type { Option } from '@/components/Select';
|
||||||
import Spacer from '@/components/Spacer';
|
import Spacer from '@/components/Spacer';
|
||||||
import { onKeyDownHandler } from '@/utils/a11y';
|
import { onKeyDownHandler } from '@/utils/a11y';
|
||||||
|
@ -23,6 +23,11 @@ type Props<T> = {
|
||||||
onItemClick: (value: T) => void;
|
onItemClick: (value: T) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const menuItemHeight = 40;
|
||||||
|
const menuItemMargin = 4;
|
||||||
|
const menuBorderSize = 1;
|
||||||
|
const menuBottomPadding = 16;
|
||||||
|
|
||||||
function SubMenu<T extends string>({
|
function SubMenu<T extends string>({
|
||||||
className,
|
className,
|
||||||
menuItemClassName,
|
menuItemClassName,
|
||||||
|
@ -36,6 +41,32 @@ function SubMenu<T extends string>({
|
||||||
const [showMenu, setShowMenu] = useState(false);
|
const [showMenu, setShowMenu] = useState(false);
|
||||||
const mouseEnterTimeoutRef = useRef(0);
|
const mouseEnterTimeoutRef = useRef(0);
|
||||||
const mouseLeaveTimeoutRef = useRef(0);
|
const mouseLeaveTimeoutRef = useRef(0);
|
||||||
|
const [menuHeight, setMenuHeight] = useState<number>();
|
||||||
|
|
||||||
|
const calculateDropdownHeight = useCallback(() => {
|
||||||
|
if (anchorRef.current) {
|
||||||
|
const anchorRect = anchorRef.current.getBoundingClientRect();
|
||||||
|
const originalMenuHeight =
|
||||||
|
options.length * menuItemHeight +
|
||||||
|
(options.length + 1) * menuItemMargin +
|
||||||
|
2 * menuBorderSize;
|
||||||
|
const availableHeight = window.innerHeight - anchorRect.top - menuBottomPadding;
|
||||||
|
|
||||||
|
setMenuHeight(Math.min(originalMenuHeight, availableHeight));
|
||||||
|
}
|
||||||
|
}, [options.length]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
calculateDropdownHeight();
|
||||||
|
|
||||||
|
window.addEventListener('resize', calculateDropdownHeight);
|
||||||
|
window.addEventListener('scroll', calculateDropdownHeight);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', calculateDropdownHeight);
|
||||||
|
window.removeEventListener('scroll', calculateDropdownHeight);
|
||||||
|
};
|
||||||
|
}, [calculateDropdownHeight]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -71,7 +102,10 @@ function SubMenu<T extends string>({
|
||||||
</span>
|
</span>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<ArrowRight className={styles.icon} />
|
<ArrowRight className={styles.icon} />
|
||||||
<div className={classNames(styles.menu, showMenu && styles.visible)}>
|
<OverlayScrollbar
|
||||||
|
className={classNames(styles.menu, showMenu && styles.visible)}
|
||||||
|
style={{ maxHeight: menuHeight }}
|
||||||
|
>
|
||||||
{options.map(({ value, title }) => {
|
{options.map(({ value, title }) => {
|
||||||
const selected = value === selectedOption;
|
const selected = value === selectedOption;
|
||||||
|
|
||||||
|
@ -92,7 +126,7 @@ function SubMenu<T extends string>({
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</OverlayScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue