Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance: context menu budget page positioning #3775

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions packages/desktop-client/src/components/budget/SidebarCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export function SidebarCategory({
const triggerRef = useRef(null);
const contextMenusEnabled = useFeatureFlag('contextMenus');

const [crossOffset, setCrossOffset] = useState(0);
const [offset, setOffset] = useState(0);

const displayed = (
<View
style={{
Expand All @@ -70,6 +73,9 @@ export function SidebarCategory({
if (!contextMenusEnabled) return;
e.preventDefault();
setMenuOpen(true);
const rect = e.currentTarget.getBoundingClientRect();
setCrossOffset(e.clientX - rect.left);
setOffset(e.clientY - rect.bottom);
}}
>
<div
Expand All @@ -88,7 +94,11 @@ export function SidebarCategory({
variant="bare"
className="hover-visible"
style={{ color: 'currentColor', padding: 3 }}
onPress={() => setMenuOpen(true)}
onPress={() => {
setOffset(0);
setCrossOffset(0);
setMenuOpen(true);
}}
>
<SvgCheveronDown
width={14}
Expand All @@ -102,8 +112,10 @@ export function SidebarCategory({
placement="bottom start"
isOpen={menuOpen}
onOpenChange={() => setMenuOpen(false)}
style={{ width: 200 }}
style={{ width: 200, margin: 1 }}
isNonModal
offset={offset}
crossOffset={crossOffset}
>
<Menu
onMenuSelect={type => {
Expand Down
16 changes: 14 additions & 2 deletions packages/desktop-client/src/components/budget/SidebarGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export function SidebarGroup({
const triggerRef = useRef(null);
const contextMenusEnabled = useFeatureFlag('contextMenus');

const [crossOffset, setCrossOffset] = useState(0);
const [offset, setOffset] = useState(0);

const displayed = (
<View
style={{
Expand All @@ -76,6 +79,9 @@ export function SidebarGroup({
if (!contextMenusEnabled) return;
e.preventDefault();
setMenuOpen(true);
const rect = e.currentTarget.getBoundingClientRect();
setCrossOffset(e.clientX - rect.left);
setOffset(e.clientY - rect.bottom);
}}
>
{!dragPreview && (
Expand Down Expand Up @@ -108,7 +114,11 @@ export function SidebarGroup({
<Button
variant="bare"
className="hover-visible"
onPress={() => setMenuOpen(true)}
onPress={() => {
setOffset(0);
setCrossOffset(0);
setMenuOpen(true);
}}
style={{ padding: 3 }}
>
<SvgCheveronDown width={14} height={14} />
Expand All @@ -119,8 +129,10 @@ export function SidebarGroup({
placement="bottom start"
isOpen={menuOpen}
onOpenChange={() => setMenuOpen(false)}
style={{ width: 200 }}
style={{ width: 200, margin: 1 }}
isNonModal
offset={offset}
crossOffset={crossOffset}
>
<Menu
onMenuSelect={type => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
const { showUndoNotification } = useUndo();
const contextMenusEnabled = useFeatureFlag('contextMenus');

const [crossOffset, setCrossOffset] = useState(0);
const [offset, setOffset] = useState(0);

return (
<View
style={{
Expand All @@ -236,6 +239,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
}}
>
<View
ref={budgetMenuTriggerRef}
style={{
flex: 1,
flexDirection: 'row',
Expand All @@ -245,6 +249,9 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
if (editing) return;
e.preventDefault();
setBudgetMenuOpen(true);
const rect = e.currentTarget.getBoundingClientRect();
setCrossOffset(e.clientX - rect.left);
setOffset(e.clientY - rect.bottom);
}}
>
{!editing && (
Expand All @@ -261,9 +268,12 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
}}
>
<Button
ref={budgetMenuTriggerRef}
variant="bare"
onPress={() => setBudgetMenuOpen(true)}
onPress={() => {
setOffset(-4);
setCrossOffset(2);
setBudgetMenuOpen(true);
}}
style={{
padding: 3,
}}
Expand All @@ -278,11 +288,13 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({

<Popover
triggerRef={budgetMenuTriggerRef}
placement="bottom start"
placement="bottom left"
isOpen={budgetMenuOpen}
onOpenChange={() => setBudgetMenuOpen(false)}
style={{ width: 200 }}
isNonModal
offset={offset}
crossOffset={crossOffset}
>
<BudgetMenu
onCopyLastMonthAverage={() => {
Expand Down Expand Up @@ -392,17 +404,24 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
</span>
</Field>
<Field
ref={balanceMenuTriggerRef}
name="balance"
width="flex"
style={{ paddingRight: styles.monthRightPadding, textAlign: 'right' }}
>
<span
ref={balanceMenuTriggerRef}
onClick={() => setBalanceMenuOpen(true)}
onClick={() => {
setOffset(-4);
setCrossOffset(-6);
setBalanceMenuOpen(true);
}}
onContextMenu={e => {
if (!contextMenusEnabled) return;
e.preventDefault();
setBalanceMenuOpen(true);
const rect = e.currentTarget.getBoundingClientRect();
setCrossOffset(e.clientX - rect.right + 200 - 8);
setOffset(e.clientY - rect.bottom - 8);
}}
>
<BalanceWithCarryover
Expand All @@ -419,8 +438,10 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
placement="bottom end"
isOpen={balanceMenuOpen}
onOpenChange={() => setBalanceMenuOpen(false)}
style={{ width: 200 }}
style={{ width: 200, margin: 1 }}
isNonModal
offset={offset}
crossOffset={crossOffset}
>
<BalanceMovementMenu
categoryId={category.id}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {
useRef,
useState,
type CSSProperties,
useCallback,
useRef,
useState,
} from 'react';

import { envelopeBudget } from 'loot-core/src/client/queries';
Expand Down Expand Up @@ -43,13 +43,12 @@ export function ToBudget({
if (menu) ref.current?.focus();
_setMenuOpen(menu);
},
[ref],
[ref, _setMenuOpen],
);
const sheetValue = useEnvelopeSheetValue({
const availableValue = useEnvelopeSheetValue({
name: envelopeBudget.toBudget,
value: 0,
});
const availableValue = sheetValue;
if (typeof availableValue !== 'number' && availableValue !== null) {
throw new Error(
'Expected availableValue to be a number but got ' + availableValue,
Expand All @@ -58,11 +57,20 @@ export function ToBudget({
const isMenuOpen = Boolean(menuOpen);
const contextMenusEnabled = useFeatureFlag('contextMenus');

const [crossOffset, setCrossOffset] = useState(0);
const [offset, setOffset] = useState(0);
const [contextMenuOpen, setContextMenuOpen] = useState(false);

return (
<>
<View ref={triggerRef}>
<ToBudgetAmount
onClick={() => setMenuOpen('actions')}
onClick={() => {
setOffset(0);
setCrossOffset(0);
setContextMenuOpen(false);
setMenuOpen('actions');
}}
prevMonthName={prevMonthName}
style={style}
amountStyle={amountStyle}
Expand All @@ -71,17 +79,23 @@ export function ToBudget({
if (!contextMenusEnabled) return;
e.preventDefault();
setMenuOpen('actions');
const rect = e.currentTarget.getBoundingClientRect();
setCrossOffset(e.clientX - rect.left);
setOffset(e.clientY - rect.bottom);
setContextMenuOpen(true);
}}
/>
</View>

<Popover
triggerRef={triggerRef}
placement="bottom"
placement={contextMenuOpen ? 'bottom start' : 'bottom'}
isOpen={isMenuOpen}
onOpenChange={() => setMenuOpen(null)}
style={{ width: 200 }}
style={{ width: 200, margin: 1 }}
isNonModal
crossOffset={crossOffset}
offset={offset}
>
<span tabIndex={-1} ref={ref}>
{menuOpen === 'actions' && (
Expand Down
1 change: 1 addition & 0 deletions packages/desktop-client/src/components/common/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const Popover = ({
...styles.tooltip,
...styles.lightScrollbar,
padding: 0,
userSelect: 'none',
...style,
})}
shouldCloseOnInteractOutside={element => {
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/3775.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [UnderKoen]
---

Position context menu's on the to budget page to the cursor, and make popovers non selectable.