From 8c8c248ef76303dbbc2b81a0227568cacd107f60 Mon Sep 17 00:00:00 2001
From: Joel Jeremy Marquez <joeljeremy.marquez@gmail.com>
Date: Tue, 10 Sep 2024 13:09:32 -0700
Subject: [PATCH] [React Aria Button] Filter buttons (#3401)

* vrt

* Fix account menu test

* Fix payee icons and category notes

* vrt

* vrt

* Fix notes button

* VRT

* VRT

* React Aria Button - All except filters and autocomplete

* Fix typecheck errors

* Fix typecheck error

* Update

* Fix typecheck error

* Fix border

* VRT

* Revert MobileForms and TransactionEdit

* VRT

* VRT

* Revert VRT

* React Aria Button - Filter buttons

* Release notes

* Revert CoverModal and TransferModal
---
 .../filters/CompactFiltersButton.tsx          |  6 +--
 .../components/filters/FilterExpression.tsx   | 10 ++--
 .../src/components/filters/FiltersButton.tsx  |  9 ++--
 .../src/components/filters/FiltersMenu.jsx    | 50 +++++++++----------
 .../src/components/filters/NameFilter.tsx     | 21 ++++----
 .../src/components/filters/OpButton.tsx       | 36 +++++++------
 .../filters/SavedFilterMenuButton.tsx         |  6 +--
 upcoming-release-notes/3401.md                |  6 +++
 8 files changed, 75 insertions(+), 69 deletions(-)
 create mode 100644 upcoming-release-notes/3401.md

diff --git a/packages/desktop-client/src/components/filters/CompactFiltersButton.tsx b/packages/desktop-client/src/components/filters/CompactFiltersButton.tsx
index 7da1dc8fa..a50c3162f 100644
--- a/packages/desktop-client/src/components/filters/CompactFiltersButton.tsx
+++ b/packages/desktop-client/src/components/filters/CompactFiltersButton.tsx
@@ -1,11 +1,11 @@
 import React from 'react';
 
 import { SvgFilter } from '../../icons/v1';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 
-export function CompactFiltersButton({ onClick }: { onClick: () => void }) {
+export function CompactFiltersButton({ onPress }: { onPress: () => void }) {
   return (
-    <Button type="bare" onClick={onClick}>
+    <Button variant="bare" onPress={onPress}>
       <SvgFilter width={15} height={15} />
     </Button>
   );
diff --git a/packages/desktop-client/src/components/filters/FilterExpression.tsx b/packages/desktop-client/src/components/filters/FilterExpression.tsx
index 34df7694a..11062c175 100644
--- a/packages/desktop-client/src/components/filters/FilterExpression.tsx
+++ b/packages/desktop-client/src/components/filters/FilterExpression.tsx
@@ -7,7 +7,7 @@ import { type RuleConditionEntity } from 'loot-core/src/types/models';
 
 import { SvgDelete } from '../../icons/v0';
 import { type CSSProperties, theme } from '../../style';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 import { Popover } from '../common/Popover';
 import { Text } from '../common/Text';
 import { View } from '../common/View';
@@ -59,9 +59,9 @@ export function FilterExpression<T extends RuleConditionEntity>({
     >
       <Button
         ref={triggerRef}
-        type="bare"
-        disabled={customName != null}
-        onClick={() => setEditing(true)}
+        variant="bare"
+        isDisabled={customName != null}
+        onPress={() => setEditing(true)}
       >
         <div style={{ paddingBlock: 1, paddingLeft: 5, paddingRight: 2 }}>
           {customName ? (
@@ -87,7 +87,7 @@ export function FilterExpression<T extends RuleConditionEntity>({
           )}
         </div>
       </Button>
-      <Button type="bare" onClick={onDelete} aria-label={t('Delete filter')}>
+      <Button variant="bare" onPress={onDelete} aria-label={t('Delete filter')}>
         <SvgDelete
           style={{
             width: 8,
diff --git a/packages/desktop-client/src/components/filters/FiltersButton.tsx b/packages/desktop-client/src/components/filters/FiltersButton.tsx
index 35be24986..595a4cb4f 100644
--- a/packages/desktop-client/src/components/filters/FiltersButton.tsx
+++ b/packages/desktop-client/src/components/filters/FiltersButton.tsx
@@ -1,14 +1,11 @@
 import React from 'react';
-import { useTranslation } from 'react-i18next';
 
 import { SvgFilter } from '../../icons/v1/Filter';
-import { Button } from '../common/Button';
-
-export function FiltersButton({ onClick }: { onClick: () => void }) {
-  const { t } = useTranslation();
+import { Button } from '../common/Button2';
 
+export function FiltersButton({ onPress }: { onPress: () => void }) {
   return (
-    <Button type="bare" onClick={onClick} title={t('Filters')}>
+    <Button variant="bare" onPress={onPress}>
       <SvgFilter style={{ width: 12, height: 12, marginRight: 5 }} /> Filter
     </Button>
   );
diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.jsx b/packages/desktop-client/src/components/filters/FiltersMenu.jsx
index 8baacffe9..30642fb7d 100644
--- a/packages/desktop-client/src/components/filters/FiltersMenu.jsx
+++ b/packages/desktop-client/src/components/filters/FiltersMenu.jsx
@@ -1,4 +1,5 @@
 import React, { useState, useRef, useEffect, useReducer } from 'react';
+import { Form } from 'react-aria-components';
 import { useHotkeys } from 'react-hotkeys-hook';
 import { Trans, useTranslation } from 'react-i18next';
 
@@ -24,7 +25,7 @@ import { titleFirst } from 'loot-core/src/shared/util';
 
 import { useDateFormat } from '../../hooks/useDateFormat';
 import { styles, theme } from '../../style';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 import { Menu } from '../common/Menu';
 import { Popover } from '../common/Popover';
 import { Select } from '../common/Select';
@@ -141,8 +142,8 @@ function ConfigureField({
             <OpButton
               key="true"
               op="true"
-              selected={value === true}
-              onClick={() => {
+              isSelected={value === true}
+              onPress={() => {
                 dispatch({ type: 'set-op', op: 'is' });
                 dispatch({ type: 'set-value', value: true });
               }}
@@ -150,8 +151,8 @@ function ConfigureField({
             <OpButton
               key="false"
               op="false"
-              selected={value === false}
-              onClick={() => {
+              isSelected={value === false}
+              onPress={() => {
                 dispatch({ type: 'set-op', op: 'is' });
                 dispatch({ type: 'set-value', value: false });
               }}
@@ -169,8 +170,8 @@ function ConfigureField({
                 <OpButton
                   key={currOp}
                   op={currOp}
-                  selected={currOp === op}
-                  onClick={() => dispatch({ type: 'set-op', op: currOp })}
+                  isSelected={currOp === op}
+                  onPress={() => dispatch({ type: 'set-op', op: currOp })}
                 />
               ))}
             </Stack>
@@ -184,8 +185,8 @@ function ConfigureField({
                 <OpButton
                   key={currOp}
                   op={currOp}
-                  selected={currOp === op}
-                  onClick={() => dispatch({ type: 'set-op', op: currOp })}
+                  isSelected={currOp === op}
+                  onPress={() => dispatch({ type: 'set-op', op: currOp })}
                 />
               ))}
             </Stack>
@@ -193,7 +194,17 @@ function ConfigureField({
         )}
       </Stack>
 
-      <form action="#">
+      <Form
+        onSubmit={e => {
+          e.preventDefault();
+          onApply({
+            field,
+            op,
+            value,
+            options: subfieldToOptions(field, subfield),
+          });
+        }}
+      >
         {type !== 'boolean' && (
           <GenericInput
             inputRef={inputRef}
@@ -224,22 +235,11 @@ function ConfigureField({
           style={{ marginTop: 15 }}
         >
           <View style={{ flex: 1 }} />
-          <Button
-            type="primary"
-            onClick={e => {
-              e.preventDefault();
-              onApply({
-                field,
-                op,
-                value,
-                options: subfieldToOptions(field, subfield),
-              });
-            }}
-          >
+          <Button variant="primary" type="submit">
             <Trans>Apply</Trans>
           </Button>
         </Stack>
-      </form>
+      </Form>
     </FocusScope>
   );
 }
@@ -347,10 +347,10 @@ export function FilterButton({ onApply, compact, hover, exclude }) {
         >
           {compact ? (
             <CompactFiltersButton
-              onClick={() => dispatch({ type: 'select-field' })}
+              onPress={() => dispatch({ type: 'select-field' })}
             />
           ) : (
-            <FiltersButton onClick={() => dispatch({ type: 'select-field' })} />
+            <FiltersButton onPress={() => dispatch({ type: 'select-field' })} />
           )}
         </Tooltip>
       </View>
diff --git a/packages/desktop-client/src/components/filters/NameFilter.tsx b/packages/desktop-client/src/components/filters/NameFilter.tsx
index b8ad19ac0..77fb85132 100644
--- a/packages/desktop-client/src/components/filters/NameFilter.tsx
+++ b/packages/desktop-client/src/components/filters/NameFilter.tsx
@@ -1,8 +1,9 @@
 import React, { useRef, useEffect } from 'react';
+import { Form } from 'react-aria-components';
 import { useTranslation } from 'react-i18next';
 
 import { theme } from '../../style';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 import { Input } from '../common/Input';
 import { Stack } from '../common/Stack';
 import { Text } from '../common/Text';
@@ -35,7 +36,12 @@ export function NameFilter({
   return (
     <>
       {menuItem !== 'update-filter' && (
-        <form>
+        <Form
+          onSubmit={e => {
+            e.preventDefault();
+            onAddUpdate();
+          }}
+        >
           <Stack
             direction="row"
             justify="flex-end"
@@ -55,18 +61,11 @@ export function NameFilter({
                 onChangeValue={setName}
               />
             </FormField>
-            <Button
-              type="primary"
-              style={{ marginTop: 18 }}
-              onClick={e => {
-                e.preventDefault();
-                onAddUpdate();
-              }}
-            >
+            <Button variant="primary" type="submit" style={{ marginTop: 18 }}>
               {adding ? t('Add') : t('Update')}
             </Button>
           </Stack>
-        </form>
+        </Form>
       )}
       {err && (
         <Stack direction="row" align="center" style={{ padding: 10 }}>
diff --git a/packages/desktop-client/src/components/filters/OpButton.tsx b/packages/desktop-client/src/components/filters/OpButton.tsx
index f061cb0c8..606149bad 100644
--- a/packages/desktop-client/src/components/filters/OpButton.tsx
+++ b/packages/desktop-client/src/components/filters/OpButton.tsx
@@ -1,34 +1,38 @@
 import React from 'react';
 
+import { css } from 'glamor';
+
 import { friendlyOp } from 'loot-core/src/shared/rules';
 
 import { type CSSProperties, theme } from '../../style';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 
 type OpButtonProps = {
   op: string;
-  selected: boolean;
-  onClick: () => void;
+  isSelected: boolean;
+  onPress: () => void;
   style?: CSSProperties;
 };
 
-export function OpButton({ op, selected, style, onClick }: OpButtonProps) {
+export function OpButton({ op, isSelected, style, onPress }: OpButtonProps) {
   return (
     <Button
-      type="bare"
-      style={{
-        backgroundColor: theme.pillBackground,
-        marginBottom: 5,
-        ...style,
-        ...(selected && {
-          color: theme.buttonNormalSelectedText,
-          '&,:hover,:active': {
-            backgroundColor: theme.buttonNormalSelectedBackground,
+      variant="bare"
+      style={style}
+      className={String(
+        css({
+          backgroundColor: theme.pillBackground,
+          marginBottom: 5,
+          ...(isSelected && {
             color: theme.buttonNormalSelectedText,
-          },
+            '&,:hover,:active': {
+              backgroundColor: theme.buttonNormalSelectedBackground,
+              color: theme.buttonNormalSelectedText,
+            },
+          }),
         }),
-      }}
-      onClick={onClick}
+      )}
+      onPress={onPress}
     >
       {friendlyOp(op)}
     </Button>
diff --git a/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx b/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx
index 3d4b3d701..bd42f61ea 100644
--- a/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx
+++ b/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx
@@ -6,7 +6,7 @@ import { type TransactionFilterEntity } from 'loot-core/types/models';
 import { type RuleConditionEntity } from 'loot-core/types/models/rule';
 
 import { SvgExpandArrow } from '../../icons/v0';
-import { Button } from '../common/Button';
+import { Button } from '../common/Button2';
 import { Popover } from '../common/Popover';
 import { Text } from '../common/Text';
 import { View } from '../common/View';
@@ -163,9 +163,9 @@ export function SavedFilterMenuButton({
       {conditions.length > 0 && (
         <Button
           ref={triggerRef}
-          type="bare"
+          variant="bare"
           style={{ marginTop: 10 }}
-          onClick={() => {
+          onPress={() => {
             setMenuOpen(true);
           }}
         >
diff --git a/upcoming-release-notes/3401.md b/upcoming-release-notes/3401.md
new file mode 100644
index 000000000..748b194dc
--- /dev/null
+++ b/upcoming-release-notes/3401.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [joel-jeremy]
+---
+
+Use react-aria-components' Button in filters.
-- 
GitLab