RolePicker: Improve overlay positioning (#92590)

* RolePicker: Improve overlay positioning

* Fix vertical position

* More fixes
pull/92622/head^2
Alex Khomenko 9 months ago committed by GitHub
parent 3111f23bf1
commit 3d6c938e59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 56
      public/app/core/components/RolePicker/RolePicker.tsx

@ -5,7 +5,12 @@ import { Role, OrgRole } from 'app/types';
import { RolePickerInput } from './RolePickerInput'; import { RolePickerInput } from './RolePickerInput';
import { RolePickerMenu } from './RolePickerMenu'; import { RolePickerMenu } from './RolePickerMenu';
import { MENU_MAX_HEIGHT, ROLE_PICKER_MAX_MENU_WIDTH, ROLE_PICKER_WIDTH } from './constants'; import {
MENU_MAX_HEIGHT,
ROLE_PICKER_MAX_MENU_WIDTH,
ROLE_PICKER_MENU_MAX_WIDTH,
ROLE_PICKER_WIDTH,
} from './constants';
export interface Props { export interface Props {
basicRole?: OrgRole; basicRole?: OrgRole;
@ -79,39 +84,38 @@ export const RolePicker = ({
return {}; return {};
} }
const { bottom, top, left, right } = dimensions; const { bottom, top, left, right } = dimensions;
const spaceBelow = window.innerHeight - bottom;
const spaceAbove = top;
const spaceRight = window.innerWidth - right;
const spaceLeft = left;
let horizontal = left; let horizontal = left;
let vertical = bottom;
let menuToLeft = false; let menuToLeft = false;
let menuToTop = false;
const distance = window.innerHeight - bottom; // Check vertical space
let vertical = bottom + 5; if (spaceBelow < MENU_MAX_HEIGHT && spaceAbove > spaceBelow) {
let ToTheSide = false; vertical = top - MENU_MAX_HEIGHT;
if (distance < MENU_MAX_HEIGHT + 20) { menuToTop = true;
// move the menu above the input if there is not enough space below
vertical = top - MENU_MAX_HEIGHT - 50;
}
// check if there is enough space above the input field
if (top < MENU_MAX_HEIGHT + 50) {
// if not, reset the vertical position
vertical = top;
// move the menu to the right edge of the input field
horizontal = right + 5;
// flag to align the menu to the right or left edge of the input field
ToTheSide = true;
} }
/* // Check horizontal space
* This expression calculates whether there is enough place if (spaceRight < ROLE_PICKER_MENU_MAX_WIDTH && spaceLeft < ROLE_PICKER_MENU_MAX_WIDTH) {
* on the right of the RolePicker input to show/fit the role picker menu and its sub menu AND horizontal = right - ROLE_PICKER_MENU_MAX_WIDTH;
* whether there is enough place under the RolePicker input to show/fit
* both (the role picker menu and its sub menu) aligned to the left edge of the input.
* Otherwise, it aligns the role picker menu to the right.
*/
if (horizontal + ROLE_PICKER_MAX_MENU_WIDTH > window.innerWidth) {
horizontal = window.innerWidth - (ToTheSide ? left : right);
menuToLeft = true; menuToLeft = true;
} else {
horizontal = Math.max(0, left + (dimensions.width - ROLE_PICKER_MENU_MAX_WIDTH) / 2);
} }
// Ensure the menu stays within the viewport
horizontal = Math.max(0, Math.min(horizontal, window.innerWidth - ROLE_PICKER_MAX_MENU_WIDTH));
vertical = Math.max(0, Math.min(vertical, window.innerHeight - MENU_MAX_HEIGHT));
if (menuToTop) {
// Adjust vertical position to align with the input
vertical -= 48;
}
return { horizontal, vertical, menuToLeft }; return { horizontal, vertical, menuToLeft };
}; };

Loading…
Cancel
Save