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

Fixes #2885 - Focus ring getting stuck on last column of /accounts/budgeted #3571

Merged
merged 8 commits into from
Nov 12, 2024

Conversation

The-Firexx
Copy link
Contributor

This pull request is to allow a user to use TAB to reach the Cancel and Add button, which cause a better user experience.
This fixes #2885

The changes I made are minimal, however if it is necessary to create/edit tests or other things please let me know.
Also, I'm not very used to React, so any "bad practice" please also report.

Thank you.

@actual-github-bot actual-github-bot bot changed the title Fixes #2885 - Focus ring getting stuck on last column of /accounts/budgeted [WIP] Fixes #2885 - Focus ring getting stuck on last column of /accounts/budgeted Oct 4, 2024
Copy link
Contributor

coderabbitai bot commented Oct 4, 2024

Walkthrough

The pull request introduces updates to the Button2.tsx and TransactionsTable.jsx components. In Button2.tsx, two new hooks, useProperFocus and useMergedRefs, are integrated to enhance focus management and ref handling for the button component. The ButtonProps type is modified to include a new optional property, focused, which allows the button to manage its focus state. In TransactionsTable.jsx, the NewTransaction component is updated to utilize the useProperFocus hook for managing focus on "Add" and "Cancel" buttons, improving accessibility. Additionally, the getFields function is refactored into two distinct functions, enhancing code clarity regarding the fields available for new versus existing transactions.

Changes

File Path Change Summary
packages/desktop-client/src/components/common/Button2.tsx Added useProperFocus and useMergedRefs hooks, updated ButtonProps to include focused, modified function signature to accept buttonRef.
packages/desktop-client/src/components/transactions/TransactionsTable.jsx Updated NewTransaction to manage focus for buttons, refactored getFields into getFieldsNewTransaction and getFieldsTableTransaction.

Assessment against linked issues

Objective Addressed Explanation
Improve focus management on the /accounts/budgeted screen (Issue #2885)

Possibly related PRs

Suggested labels

::sparkles: Merged

Suggested reviewers

  • joel-jeremy

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Oct 4, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit a352a10
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/67325b9691524800087d6d0e
😎 Deploy Preview https://deploy-preview-3571.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (3)
packages/desktop-client/src/components/transactions/TransactionsTable.jsx (3)

2113-2116: Improve readability by formatting function arguments over multiple lines

For better readability and to comply with coding style guidelines, consider formatting the arguments of useTableNavigator over multiple lines.

Suggested change:

 const newNavigator = useTableNavigator(
+  newTransactions,
+  getFieldsNewTransaction
 );
 const tableNavigator = useTableNavigator(
   transactionsWithExpandedSplits,
+  getFieldsTableTransaction
 );
🧰 Tools
🪛 GitHub Check: lint

[warning] 2113-2113:
Replace newTransactions,·getFieldsNewTransaction with ⏎····newTransactions,⏎····getFieldsNewTransaction,⏎··


2181-2181: Remove unnecessary line break before function declaration

There is an unnecessary line break before the function declaration. Placing the function keyword and the function name on the same line improves code consistency.

Suggested change:

-function
+function 
 getFieldsNewTransaction(item){
🧰 Tools
🪛 GitHub Check: lint

[warning] 2181-2181:
Replace ⏎··function·getFieldsNewTransaction(item) with ··function·getFieldsNewTransaction(item)·


2194-2194: Add a trailing comma after the last element in the array

Adding a trailing comma after the last element in an array enhances diffs in version control and aligns with style guidelines.

Suggested change:

   'add'
+  ,
🧰 Tools
🪛 GitHub Check: lint

[warning] 2194-2194:
Insert ,

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a28fb93 and 3b49d5e.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/3571.md is excluded by !**/*.md
📒 Files selected for processing (2)
  • packages/desktop-client/src/components/common/Button2.tsx (4 hunks)
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx (5 hunks)
🧰 Additional context used
🪛 GitHub Check: lint
packages/desktop-client/src/components/common/Button2.tsx

[warning] 19-19:
../../hooks/useProperFocus import should occur before import of ../../icons/AnimatedLoading


[warning] 20-20:
../../hooks/useMergedRefs import should occur before import of ../../icons/AnimatedLoading


[warning] 147-147:
Replace ·children,·variant·=·'normal',·bounce·=·true,·focused·=·false,·...restProps with ⏎······children,⏎······variant·=·'normal',⏎······bounce·=·true,⏎······focused·=·false,⏎······...restProps⏎···


[warning] 151-151:
Delete ····

packages/desktop-client/src/components/transactions/TransactionsTable.jsx

[warning] 2113-2113:
Replace newTransactions,·getFieldsNewTransaction with ⏎····newTransactions,⏎····getFieldsNewTransaction,⏎··


[warning] 2181-2181:
Replace ⏎··function·getFieldsNewTransaction(item) with ··function·getFieldsNewTransaction(item)·


[warning] 2194-2194:
Insert ,


[warning] 2200-2200:
Insert ·

🔇 Additional comments (5)
packages/desktop-client/src/components/common/Button2.tsx (4)

4-4: Import useRef to manage local refs

Adding useRef is appropriate for managing local refs within the component.


140-140: Add focused prop to ButtonProps

The addition of the optional focused prop enhances the Button component's ability to manage focus state based on this prop.


146-152: Implement focus handling correctly with refs

The use of useRef, useProperFocus, and useMergedRefs correctly implements focus management and ref forwarding within the Button component.

🧰 Tools
🪛 GitHub Check: lint

[warning] 147-147:
Replace ·children,·variant·=·'normal',·bounce·=·true,·focused·=·false,·...restProps with ⏎······children,⏎······variant·=·'normal',⏎······bounce·=·true,⏎······focused·=·false,⏎······...restProps⏎···


[warning] 151-151:
Delete ····


186-186: Pass mergedRef to ReactAriaButton for proper ref handling

Passing mergedRef to ReactAriaButton ensures that both internal and external refs are properly handled.

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (1)

1734-1734: The 'focused' prop is correctly added to 'Cancel' and 'Add' buttons

The focused prop is appropriately set for the 'Cancel' and 'Add' buttons, enabling proper focus handling during tab navigation. This change aligns with the PR objective to fix the focus ring navigation issue.

Also applies to: 1754-1754


const ref = useRef<HTMLButtonElement>(null);
useProperFocus(ref, focused);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unnecessary whitespace

There is unnecessary whitespace on line 151. Please remove it to maintain code cleanliness.

Apply this diff to remove the whitespace:

-        
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
🧰 Tools
🪛 GitHub Check: lint

[warning] 151-151:
Delete ····

(props, ref) => {
const { children, variant = 'normal', bounce = true, ...restProps } = props;
(props, buttonRef) => {
const { children, variant = 'normal', bounce = true, focused = false, ...restProps } = props;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Format destructured props for better readability

For improved readability, format the destructured props over multiple lines as suggested by the linter.

Apply this diff to format the code:

         const {
-          children, variant = 'normal', bounce = true, focused = false, ...restProps
+          children,
+          variant = 'normal',
+          bounce = true,
+          focused = false,
+          ...restProps
         } = props;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { children, variant = 'normal', bounce = true, focused = false, ...restProps } = props;
const {
children,
variant = 'normal',
bounce = true,
focused = false,
...restProps
} = props;
🧰 Tools
🪛 GitHub Check: lint

[warning] 147-147:
Replace ·children,·variant·=·'normal',·bounce·=·true,·focused·=·false,·...restProps with ⏎······children,⏎······variant·=·'normal',⏎······bounce·=·true,⏎······focused·=·false,⏎······...restProps⏎···

Comment on lines 19 to 20
import { useProperFocus } from '../../hooks/useProperFocus';
import { useMergedRefs } from '../../hooks/useMergedRefs';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Reorder imports to satisfy linting rules

The imports of useProperFocus and useMergedRefs should occur before the import of ../../icons/AnimatedLoading to comply with the project's import order conventions.

Apply this diff to fix the import order:

 import React, {
   forwardRef,
   useMemo,
+  useRef,
   type ComponentPropsWithoutRef,
   type ReactNode,
 } from 'react';
 
 import { css } from 'glamor';

+import { useProperFocus } from '../../hooks/useProperFocus';
+import { useMergedRefs } from '../../hooks/useMergedRefs';
 
 import { AnimatedLoading } from '../../icons/AnimatedLoading';
 
 import { type CSSProperties, styles, theme } from '../../style';
 
 import { View } from './View';

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 GitHub Check: lint

[warning] 19-19:
../../hooks/useProperFocus import should occur before import of ../../icons/AnimatedLoading


[warning] 20-20:
../../hooks/useMergedRefs import should occur before import of ../../icons/AnimatedLoading

return getFields(item, fields);
}

function getFieldsTableTransaction(item){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Insert a space between 'function' keyword and function name

There should be a space between the function keyword and getFieldsTableTransaction to prevent syntax errors and improve readability.

Suggested change:

-functiongetFieldsTableTransaction(item){
+function getFieldsTableTransaction(item){

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 GitHub Check: lint

[warning] 2200-2200:
Insert ·

Copy link
Contributor

github-actions bot commented Oct 4, 2024

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
10 5.35 MB → 5.35 MB (+693 B) +0.01%
Changeset
File Δ Size
src/components/transactions/TransactionsTable.jsx 📈 +693 B (+1.02%) 66.39 kB → 67.07 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/wide.js 239.86 kB → 240.54 kB (+693 B) +0.28%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
static/js/workbox-window.prod.es5.js 5.69 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/narrow.js 83.03 kB 0%
static/js/usePreviewTransactions.js 1.64 kB 0%
static/js/AppliedFilters.js 21.3 kB 0%
static/js/ReportRouter.js 1.5 MB 0%
static/js/index.js 3.35 MB 0%

Copy link
Contributor

github-actions bot commented Oct 4, 2024

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.27 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.27 MB 0%

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
packages/desktop-client/src/components/common/Button2.tsx (2)

146-157: LGTM: Enhanced focus management in Button component

The changes to the Button component implementation significantly improve its focus management capabilities:

  • The use of useRef for local ref creation is appropriate.
  • The useProperFocus hook enhances focus control.
  • Merging refs with useMergedRefs allows for both internal management and external access.

These changes align with React best practices and improve the component's functionality.

Consider formatting the destructured props for better readability:

   const {
-      children,
-      variant = 'normal',
-      bounce = true,
-      focused = false,
-      ...restProps
+    children,
+    variant = 'normal',
+    bounce = true,
+    focused = false,
+    ...restProps
   } = props;

Line range hint 1-253: Summary: Improved focus management addresses PR objectives

The changes made to the Button component successfully address the issue described in the PR objectives. By implementing proper focus management using custom hooks and ref merging, the component now allows for better control of the focus state, which should resolve the problem of the focus ring getting stuck on the last column of the /accounts/budgeted screen.

Key improvements:

  1. Added focused prop for external focus control.
  2. Implemented useProperFocus hook for internal focus management.
  3. Used useMergedRefs to combine internal and external refs.

These changes enhance the user experience by allowing proper tabbing to the Cancel and Add buttons, as requested in the PR summary.

Regarding the author's request for feedback on potential bad practices:

  • The implementation follows React best practices.
  • The use of custom hooks and ref management is appropriate and well-executed.
  • The changes are minimal and focused on addressing the specific issue.

Consider adding unit tests to verify the new focus management behavior, especially testing the tabbing functionality between different UI elements.

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (2)

2113-2121: Improved separation of concerns for transaction fields

The separation of field definitions for new transactions and table transactions is a good practice. It allows for more flexibility and potentially different behaviors for each type.

Consider adding a brief comment explaining the purpose of each function for better code documentation:

// Define fields for new transactions
const newNavigator = useTableNavigator(
  newTransactions,
  getFieldsNewTransaction,
);

// Define fields for existing table transactions
const tableNavigator = useTableNavigator(
  transactionsWithExpandedSplits,
  getFieldsTableTransaction,
);

Line range hint 2185-2217: Well-structured field definitions for different transaction types

The separation of field definitions for new and existing transactions provides flexibility and maintainability. The inclusion of 'cancel' and 'add' fields in getFieldsNewTransaction aligns well with the UI changes.

To reduce code duplication, consider extracting the common fields into a constant:

const commonFields = [
  'select', 'date', 'account', 'payee', 'notes', 'category', 'debit', 'credit', 'cleared'
];

function getFieldsNewTransaction(item) {
  return getFields(item, [...commonFields, 'cancel', 'add']);
}

function getFieldsTableTransaction(item) {
  return getFields(item, commonFields);
}

This approach makes it easier to maintain the common fields and clearly shows the difference between the two functions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3b49d5e and fa939a6.

📒 Files selected for processing (2)
  • packages/desktop-client/src/components/common/Button2.tsx (4 hunks)
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx (5 hunks)
🔇 Additional comments (6)
packages/desktop-client/src/components/common/Button2.tsx (4)

4-4: LGTM: useRef import added

The addition of useRef to the React import is appropriate and necessary for the changes made in the Button component implementation.


15-16: LGTM: New hook imports added and correctly ordered

The addition of useMergedRefs and useProperFocus imports is appropriate for the enhanced functionality in the Button component. The import order now satisfies the linting rules, resolving the issue mentioned in a previous review comment.


140-140: LGTM: 'focused' prop added to ButtonProps

The addition of the optional focused prop to ButtonProps is appropriate and consistent with the changes in the Button component implementation. This allows for external control of the button's focus state.


191-191: LGTM: Updated ref prop in ReactAriaButton

The use of mergedRef as the ref for ReactAriaButton is consistent with the earlier changes and allows the button to work seamlessly with both internal focus management and any external ref passed to the component.

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (2)

1734-1737: Improved UI and accessibility for new transaction input

The addition of 'Cancel' and 'Add' buttons with the 'focused' prop enhances the user interface and improves accessibility by allowing keyboard navigation. This change aligns well with the PR objectives.

Also applies to: 1754-1757


Line range hint 1-2641: Summary of changes and their impact

The modifications in this PR successfully address the issue of focus getting stuck on the last column of the /accounts/budgeted screen. The key improvements include:

  1. Addition of 'Cancel' and 'Add' buttons to the new transaction input UI, enhancing usability and accessibility.
  2. Separation of field definitions for new and existing transactions, improving code organization and flexibility.
  3. Implementation of the 'focused' prop for new buttons, enabling proper keyboard navigation.

These changes align well with the PR objectives and enhance the overall user experience. The code structure remains clean and maintainable.

Some minor suggestions for improvement have been made in previous comments, but overall, this is a solid contribution to the codebase.

@The-Firexx The-Firexx changed the title [WIP] Fixes #2885 - Focus ring getting stuck on last column of /accounts/budgeted Fixes #2885 - Focus ring getting stuck on last column of /accounts/budgeted Oct 4, 2024
@joel-jeremy
Copy link
Contributor

I'm wondering if FocusScope would be able to help with this.

} = props;

const ref = useRef<HTMLButtonElement>(null);
useProperFocus(ref, focused);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use this hook on the TransactionsTable and just pass the ref to the Add and Cancel button instead of doing it directly in the Button component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the source code to avoid messing with Button2, can you check? Thank you

@youngcw youngcw added this to the v24.11.0 milestone Oct 15, 2024
@matt-fidd matt-fidd requested a review from joel-jeremy October 18, 2024 14:09
Copy link
Contributor

@joel-jeremy joel-jeremy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few minor comments. Other than that LGTM!

@@ -1670,6 +1671,11 @@ function NewTransaction({
);
const emptyChildTransactions = childTransactions.filter(t => t.amount === 0);

const addRef = useRef(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const addRef = useRef(null);
const addButtonRef = useRef(null);

@@ -1670,6 +1671,11 @@ function NewTransaction({
);
const emptyChildTransactions = childTransactions.filter(t => t.amount === 0);

const addRef = useRef(null);
useProperFocus(addRef, focusedField === 'add');
const cancelRef = useRef(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const cancelRef = useRef(null);
const cancelButtonRef = useRef(null);

@@ -1731,6 +1737,7 @@ function NewTransaction({
style={{ marginRight: 10, padding: '4px 10px' }}
onPress={() => onClose()}
data-testid="cancel-button"
ref={cancelRef}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ref={cancelRef}
ref={cancelButtonRef}

@@ -1750,6 +1757,7 @@ function NewTransaction({
style={{ padding: '4px 10px' }}
onPress={onAdd}
data-testid="add-button"
ref={addRef}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ref={addRef}
ref={addButtonRef}

@youngcw youngcw modified the milestones: v24.11.0, v24.12.0 Oct 23, 2024
@The-Firexx
Copy link
Contributor Author

Sorry for the very long delay.
Already made the changes requested.

@joel-jeremy joel-jeremy merged commit d132440 into actualbudget:master Nov 12, 2024
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: focus ring gets "stuck" on last column of /accounts/budgeted screen.
3 participants