Files
standardnotes-app-web/app/assets/javascripts/utils/calculateSubmenuStyle.tsx

78 lines
2.2 KiB
TypeScript

import {
MAX_MENU_SIZE_MULTIPLIER,
MENU_MARGIN_FROM_APP_BORDER,
} from '@/constants';
export type SubmenuStyle = {
top?: number | 'auto';
right?: number | 'auto';
bottom: number | 'auto';
left?: number | 'auto';
visibility?: 'hidden' | 'visible';
maxHeight: number | 'auto';
};
export const calculateSubmenuStyle = (
button: HTMLButtonElement | null,
menu?: HTMLDivElement | null
): SubmenuStyle | 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: SubmenuStyle = {
bottom: 'auto',
maxHeight: 'auto',
};
if (buttonRect && buttonParentRect) {
let positionBottom =
clientHeight - buttonRect.bottom - buttonRect.height / 2;
if (positionBottom < footerHeightInPx) {
positionBottom = footerHeightInPx + MENU_MARGIN_FROM_APP_BORDER;
}
position = {
bottom: positionBottom,
visibility: 'hidden',
maxHeight: 'auto',
};
if (buttonRect.right + maxChangeEditorMenuSize > clientWidth) {
position.right = clientWidth - buttonRect.left;
} else {
position.left = buttonRect.right;
}
}
if (menuBoundingRect?.height && buttonRect && position.bottom !== 'auto') {
position.visibility = 'visible';
if (menuBoundingRect.y < MENU_MARGIN_FROM_APP_BORDER) {
position.bottom =
position.bottom + menuBoundingRect.y - MENU_MARGIN_FROM_APP_BORDER * 2;
}
if (footerElementRect && menuBoundingRect.height > footerElementRect.y) {
position.bottom = footerElementRect.height + MENU_MARGIN_FROM_APP_BORDER;
position.maxHeight =
clientHeight -
footerElementRect.height -
MENU_MARGIN_FROM_APP_BORDER * 2;
}
}
return position;
};