feat: use improved style calculation for change editor submenu (#899)
This commit is contained in:
@@ -1,10 +1,6 @@
|
||||
import { KeyboardKey } from '@/services/ioService';
|
||||
import { WebApplication } from '@/ui_models/application';
|
||||
import { AppState } from '@/ui_models/app_state';
|
||||
import {
|
||||
MENU_MARGIN_FROM_APP_BORDER,
|
||||
MAX_MENU_SIZE_MULTIPLIER,
|
||||
} from '@/constants';
|
||||
import {
|
||||
Disclosure,
|
||||
DisclosureButton,
|
||||
@@ -21,6 +17,10 @@ import { useEffect, useRef, useState } from 'preact/hooks';
|
||||
import { Icon } from '../Icon';
|
||||
import { createEditorMenuGroups } from './changeEditor/createEditorMenuGroups';
|
||||
import { ChangeEditorMenu } from './changeEditor/ChangeEditorMenu';
|
||||
import {
|
||||
calculateSubmenuStyle,
|
||||
SubmenuStyle,
|
||||
} from '@/utils/calculateSubmenuStyle';
|
||||
|
||||
type ChangeEditorOptionProps = {
|
||||
appState: AppState;
|
||||
@@ -44,92 +44,6 @@ export type EditorMenuItem = {
|
||||
|
||||
export type EditorMenuGroup = AccordionMenuGroup<EditorMenuItem>;
|
||||
|
||||
type MenuPositionStyle = {
|
||||
top?: number | 'auto';
|
||||
right?: number | 'auto';
|
||||
bottom: number | 'auto';
|
||||
left?: number | 'auto';
|
||||
visibility?: 'hidden' | 'visible';
|
||||
};
|
||||
|
||||
const calculateMenuPosition = (
|
||||
button: HTMLButtonElement | null,
|
||||
menu?: HTMLDivElement | null
|
||||
): MenuPositionStyle | undefined => {
|
||||
const defaultFontSize = window.getComputedStyle(
|
||||
document.documentElement
|
||||
).fontSize;
|
||||
|
||||
const maxChangeEditorMenuSize =
|
||||
parseFloat(defaultFontSize) * MAX_MENU_SIZE_MULTIPLIER;
|
||||
|
||||
const { clientWidth, clientHeight } = document.documentElement;
|
||||
|
||||
const buttonRect = button?.getBoundingClientRect();
|
||||
|
||||
const buttonParentRect = button?.parentElement?.getBoundingClientRect();
|
||||
|
||||
const menuBoundingRect = menu?.getBoundingClientRect();
|
||||
|
||||
const footerElementRect = document
|
||||
.getElementById('footer-bar')
|
||||
?.getBoundingClientRect();
|
||||
|
||||
const footerHeightInPx = footerElementRect?.height ?? 0;
|
||||
|
||||
let position: MenuPositionStyle = {
|
||||
bottom: 'auto',
|
||||
};
|
||||
|
||||
if (buttonRect && buttonParentRect) {
|
||||
let positionBottom =
|
||||
clientHeight - buttonRect.bottom - buttonRect.height / 2;
|
||||
|
||||
if (positionBottom < footerHeightInPx) {
|
||||
positionBottom = footerHeightInPx + MENU_MARGIN_FROM_APP_BORDER;
|
||||
}
|
||||
|
||||
if (buttonRect.right + maxChangeEditorMenuSize > clientWidth) {
|
||||
position = {
|
||||
bottom: positionBottom,
|
||||
right: clientWidth - buttonRect.left,
|
||||
visibility: 'hidden',
|
||||
};
|
||||
} else {
|
||||
position = {
|
||||
bottom: positionBottom,
|
||||
left: buttonRect.right,
|
||||
visibility: 'hidden',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (menuBoundingRect && menuBoundingRect.height && buttonRect) {
|
||||
if (menuBoundingRect.y < MENU_MARGIN_FROM_APP_BORDER) {
|
||||
if (
|
||||
buttonRect.right + maxChangeEditorMenuSize >
|
||||
document.documentElement.clientWidth
|
||||
) {
|
||||
return {
|
||||
...position,
|
||||
top: MENU_MARGIN_FROM_APP_BORDER + buttonRect.top - buttonRect.height,
|
||||
bottom: 'auto',
|
||||
visibility: 'visible',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...position,
|
||||
top: MENU_MARGIN_FROM_APP_BORDER,
|
||||
bottom: 'auto',
|
||||
visibility: 'visible',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
};
|
||||
|
||||
export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
application,
|
||||
closeOnBlur,
|
||||
@@ -137,14 +51,11 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
}) => {
|
||||
const [changeEditorMenuOpen, setChangeEditorMenuOpen] = useState(false);
|
||||
const [changeEditorMenuVisible, setChangeEditorMenuVisible] = useState(false);
|
||||
const [changeEditorMenuMaxHeight, setChangeEditorMenuMaxHeight] = useState<
|
||||
number | 'auto'
|
||||
>('auto');
|
||||
const [changeEditorMenuPosition, setChangeEditorMenuPosition] =
|
||||
useState<MenuPositionStyle>({
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
});
|
||||
const [menuStyle, setMenuStyle] = useState<SubmenuStyle>({
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
maxHeight: 'auto',
|
||||
});
|
||||
const changeEditorMenuRef = useRef<HTMLDivElement>(null);
|
||||
const changeEditorButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const [editors] = useState<SNComponent[]>(() =>
|
||||
@@ -171,9 +82,9 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
|
||||
const toggleChangeEditorMenu = () => {
|
||||
if (!changeEditorMenuOpen) {
|
||||
const menuPosition = calculateMenuPosition(changeEditorButtonRef.current);
|
||||
if (menuPosition) {
|
||||
setChangeEditorMenuPosition(menuPosition);
|
||||
const menuStyle = calculateSubmenuStyle(changeEditorButtonRef.current);
|
||||
if (menuStyle) {
|
||||
setMenuStyle(menuStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,32 +94,13 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
useEffect(() => {
|
||||
if (changeEditorMenuOpen) {
|
||||
setTimeout(() => {
|
||||
const newMenuPosition = calculateMenuPosition(
|
||||
const newMenuStyle = calculateSubmenuStyle(
|
||||
changeEditorButtonRef.current,
|
||||
changeEditorMenuRef.current
|
||||
);
|
||||
|
||||
if (newMenuPosition) {
|
||||
const { clientHeight } = document.documentElement;
|
||||
const footerElementRect = document
|
||||
.getElementById('footer-bar')
|
||||
?.getBoundingClientRect();
|
||||
const footerHeightInPx = footerElementRect?.height;
|
||||
|
||||
if (
|
||||
footerHeightInPx &&
|
||||
newMenuPosition.top &&
|
||||
newMenuPosition.top !== 'auto'
|
||||
) {
|
||||
setChangeEditorMenuMaxHeight(
|
||||
clientHeight -
|
||||
newMenuPosition.top -
|
||||
footerHeightInPx -
|
||||
MENU_MARGIN_FROM_APP_BORDER
|
||||
);
|
||||
}
|
||||
|
||||
setChangeEditorMenuPosition(newMenuPosition);
|
||||
if (newMenuStyle) {
|
||||
setMenuStyle(newMenuStyle);
|
||||
setChangeEditorMenuVisible(true);
|
||||
}
|
||||
});
|
||||
@@ -242,8 +134,7 @@ export const ChangeEditorOption: FunctionComponent<ChangeEditorOptionProps> = ({
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
...changeEditorMenuPosition,
|
||||
maxHeight: changeEditorMenuMaxHeight,
|
||||
...menuStyle,
|
||||
position: 'fixed',
|
||||
}}
|
||||
className="sn-dropdown flex flex-col max-h-120 min-w-68 fixed overflow-y-auto"
|
||||
|
||||
Reference in New Issue
Block a user