fix: make menus scrollable when there's not enough space
This commit is contained in:
@@ -31,13 +31,13 @@ const NotesContextMenu = observer(({ appState }: Props) => {
|
||||
return appState.notes.contextMenuOpen ? (
|
||||
<div
|
||||
ref={contextMenuRef}
|
||||
className="sn-dropdown max-w-80 flex flex-col py-2 absolute"
|
||||
style={{ ...appState.notes.contextMenuPosition }}
|
||||
className="sn-dropdown max-h-120 max-w-80 flex flex-col py-2 overflow-y-scroll fixed"
|
||||
style={{
|
||||
...appState.notes.contextMenuPosition,
|
||||
maxHeight: appState.notes.contextMenuMaxHeight,
|
||||
}}
|
||||
>
|
||||
<NotesOptions
|
||||
appState={appState}
|
||||
closeOnBlur={closeOnBlur}
|
||||
/>
|
||||
<NotesOptions appState={appState} closeOnBlur={closeOnBlur} />
|
||||
</div>
|
||||
) : null;
|
||||
});
|
||||
|
||||
@@ -19,11 +19,16 @@ type Props = {
|
||||
export const NotesOptions = observer(
|
||||
({ appState, closeOnBlur, onSubmenuChange }: Props) => {
|
||||
const [tagsMenuOpen, setTagsMenuOpen] = useState(false);
|
||||
const [tagsMenuPosition, setTagsMenuPosition] = useState({
|
||||
const [tagsMenuPosition, setTagsMenuPosition] = useState<{
|
||||
top: number;
|
||||
right?: number;
|
||||
left?: number;
|
||||
}>({
|
||||
top: 0,
|
||||
right: 0,
|
||||
});
|
||||
const [tagsMenuMaxHeight, setTagsMenuMaxHeight] = useState<number | 'auto'>('auto');
|
||||
const [tagsMenuMaxHeight, setTagsMenuMaxHeight] =
|
||||
useState<number | 'auto'>('auto');
|
||||
|
||||
const toggleOn = (condition: (note: SNNote) => boolean) => {
|
||||
const notesMatchingAttribute = notes.filter(condition);
|
||||
@@ -62,24 +67,27 @@ export const NotesOptions = observer(
|
||||
const defaultFontSize = window.getComputedStyle(
|
||||
document.documentElement
|
||||
).fontSize;
|
||||
const maxTagsMenuSize = parseFloat(defaultFontSize) * 20;
|
||||
const { clientWidth, clientHeight } = document.body;
|
||||
const maxTagsMenuSize = parseFloat(defaultFontSize) * 30;
|
||||
const { clientWidth, clientHeight } = document.documentElement;
|
||||
const buttonRect = tagsButtonRef.current.getBoundingClientRect();
|
||||
const { offsetTop, offsetWidth } = tagsButtonRef.current;
|
||||
const footerHeight = 32;
|
||||
|
||||
if (buttonRect.top + maxTagsMenuSize > clientHeight - footerHeight) {
|
||||
if ((buttonRect.top + maxTagsMenuSize) > (clientHeight - footerHeight)) {
|
||||
setTagsMenuMaxHeight(clientHeight - buttonRect.top - footerHeight - 2);
|
||||
}
|
||||
|
||||
setTagsMenuPosition({
|
||||
top: offsetTop,
|
||||
right:
|
||||
buttonRect.right + maxTagsMenuSize >
|
||||
clientWidth
|
||||
? offsetWidth
|
||||
: -offsetWidth,
|
||||
});
|
||||
if ((buttonRect.right + maxTagsMenuSize) > clientWidth) {
|
||||
setTagsMenuPosition({
|
||||
top: buttonRect.top,
|
||||
right: clientWidth - buttonRect.left,
|
||||
});
|
||||
} else {
|
||||
setTagsMenuPosition({
|
||||
top: buttonRect.top,
|
||||
left: buttonRect.right,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setTagsMenuOpen(!tagsMenuOpen);
|
||||
};
|
||||
@@ -127,10 +135,7 @@ export const NotesOptions = observer(
|
||||
</Switch>
|
||||
<div className="h-1px my-2 bg-border"></div>
|
||||
{appState.tags.tagsCount > 0 && (
|
||||
<Disclosure
|
||||
open={tagsMenuOpen}
|
||||
onChange={openTagsMenu}
|
||||
>
|
||||
<Disclosure open={tagsMenuOpen} onChange={openTagsMenu}>
|
||||
<DisclosureButton
|
||||
onKeyUp={(event) => {
|
||||
if (event.key === 'Escape') {
|
||||
@@ -145,10 +150,7 @@ export const NotesOptions = observer(
|
||||
<Icon type="hashtag" className={iconClass} />
|
||||
{'Add tag'}
|
||||
</div>
|
||||
<Icon
|
||||
type="chevron-right"
|
||||
className="color-neutral"
|
||||
/>
|
||||
<Icon type="chevron-right" className="color-neutral" />
|
||||
</DisclosureButton>
|
||||
<DisclosurePanel
|
||||
onKeyUp={(event) => {
|
||||
@@ -160,8 +162,9 @@ export const NotesOptions = observer(
|
||||
style={{
|
||||
...tagsMenuPosition,
|
||||
maxHeight: tagsMenuMaxHeight,
|
||||
position: 'fixed',
|
||||
}}
|
||||
className="sn-dropdown sn-dropdown-anchor-right flex flex-col py-2 max-h-80 absolute overflow-y-scroll"
|
||||
className="sn-dropdown flex flex-col py-2 max-h-120 max-w-80 fixed overflow-y-scroll"
|
||||
>
|
||||
{appState.tags.tags.map((tag) => (
|
||||
<button
|
||||
@@ -278,10 +281,7 @@ export const NotesOptions = observer(
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start">
|
||||
<Icon
|
||||
type="trash-sweep"
|
||||
className="color-danger mr-2"
|
||||
/>
|
||||
<Icon type="trash-sweep" className="color-danger mr-2" />
|
||||
<div className="flex-row">
|
||||
<div className="color-danger">Empty Trash</div>
|
||||
<div className="text-xs">
|
||||
|
||||
@@ -21,6 +21,7 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
||||
top: 0,
|
||||
right: 0,
|
||||
});
|
||||
const [maxHeight, setMaxHeight] = useState<number | 'auto'>('auto');
|
||||
const buttonRef = useRef<HTMLButtonElement>();
|
||||
const panelRef = useRef<HTMLDivElement>();
|
||||
const [closeOnBlur] = useCloseOnBlur(panelRef, setOpen);
|
||||
@@ -35,6 +36,9 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
||||
open={open}
|
||||
onChange={() => {
|
||||
const rect = buttonRef.current.getBoundingClientRect();
|
||||
const { clientHeight } = document.documentElement;
|
||||
const footerHeight = 32;
|
||||
setMaxHeight(clientHeight - rect.bottom - footerHeight - 2);
|
||||
setPosition({
|
||||
top: rect.bottom,
|
||||
right: document.body.clientWidth - rect.right,
|
||||
@@ -65,8 +69,9 @@ export const NotesOptionsPanel = observer(({ appState }: Props) => {
|
||||
ref={panelRef}
|
||||
style={{
|
||||
...position,
|
||||
maxHeight
|
||||
}}
|
||||
className="sn-dropdown flex flex-col py-2"
|
||||
className="sn-dropdown max-h-120 max-w-80 flex flex-col py-2 overflow-y-scroll fixed"
|
||||
>
|
||||
{open && (
|
||||
<NotesOptions
|
||||
|
||||
@@ -63,7 +63,7 @@ const SearchOptions = observer(({ appState }: Props) => {
|
||||
style={{
|
||||
top: optionsPanelTop,
|
||||
}}
|
||||
className="sn-dropdown sn-dropdown-anchor-right grid gap-2 py-2"
|
||||
className="sn-dropdown sn-dropdown-anchor-right absolute grid gap-2 py-2"
|
||||
>
|
||||
<Switch
|
||||
className="h-10"
|
||||
|
||||
Reference in New Issue
Block a user