fix: make context menu scrollable when there's not enough space

This commit is contained in:
Antonella Sgarlatta
2021-05-20 13:29:59 -03:00
parent eea4f98928
commit f9f2959ad5
3 changed files with 51 additions and 9 deletions

View File

@@ -31,8 +31,8 @@ const NotesContextMenu = observer(({ appState }: Props) => {
return appState.notes.contextMenuOpen ? (
<div
ref={contextMenuRef}
className="sn-dropdown max-w-80 flex flex-col py-2"
style={{ position: 'absolute', ...appState.notes.contextMenuPosition }}
className="sn-dropdown max-w-80 flex flex-col py-2 overflow-y-scroll absolute"
style={{ ...appState.notes.contextMenuPosition, maxHeight: appState.notes.contextMenuMaxHeight }}
>
<NotesOptions
appState={appState}

View File

@@ -27,6 +27,7 @@ export class NotesState {
top: 0,
left: 0,
};
contextMenuMaxHeight: number | 'auto' = 'auto';
showProtectedWarning = false;
constructor(
@@ -45,6 +46,7 @@ export class NotesState {
setContextMenuOpen: action,
setContextMenuPosition: action,
setContextMenuMaxHeight: action,
setShowProtectedWarning: action,
unselectNotes: action,
});
@@ -181,6 +183,10 @@ export class NotesState {
this.contextMenuPosition = position;
}
setContextMenuMaxHeight(height: number | 'auto'): void {
this.contextMenuMaxHeight = height;
}
async changeSelectedNotes(
mutate: (mutator: NoteMutator) => void
): Promise<void> {

View File

@@ -313,18 +313,54 @@ class NotesViewCtrl extends PureViewCtrl<unknown, NotesCtrlState> {
document.documentElement
).fontSize;
const maxContextMenuHeight = parseFloat(defaultFontSize) * 20;
if (e.clientY > clientHeight - maxContextMenuHeight) {
this.application.getAppState().notes.setContextMenuPosition({
bottom: clientHeight - e.clientY,
left: e.clientX,
});
const footerHeight = 32;
// Open up-bottom is default behavior
let openUpBottom = true;
const bottomSpace = clientHeight - footerHeight - e.clientY;
const upSpace = e.clientY;
// If not enough space to open up-bottom
if (maxContextMenuHeight > bottomSpace) {
// If there's enough space, open bottom-up
if (upSpace > maxContextMenuHeight) {
openUpBottom = false;
this.appState.notes.setContextMenuMaxHeight(
'auto'
);
// Else, reduce max height (menu will be scrollable) and open in whichever direction there's more space
} else {
if (upSpace > bottomSpace) {
this.appState.notes.setContextMenuMaxHeight(
upSpace - 2
);
openUpBottom = false;
} else {
this.appState.notes.setContextMenuMaxHeight(
bottomSpace - 2
);
}
}
} else {
this.application.getAppState().notes.setContextMenuPosition({
this.appState.notes.setContextMenuMaxHeight(
'auto'
);
}
if (openUpBottom) {
this.appState.notes.setContextMenuPosition({
top: e.clientY,
left: e.clientX,
});
} else {
this.appState.notes.setContextMenuPosition({
bottom: clientHeight - e.clientY,
left: e.clientX,
});
}
this.application.getAppState().notes.setContextMenuOpen(true);
this.appState.notes.setContextMenuOpen(true);
}
}