mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 03:32:54 -05:00
♻️ (tooltip) refactoring to react-aria (vol.6) (#2771)
* ♻️ (tooltip) refactoring to react-aria (vol.6)
* Release notes
This commit is contained in:
committed by
GitHub
parent
c92266fd7f
commit
0e86dea544
@@ -28,9 +28,9 @@ import { styles, theme } from '../../style';
|
||||
import { tokens } from '../../tokens';
|
||||
import { Button } from '../common/Button';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { Text } from '../common/Text';
|
||||
import { View } from '../common/View';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
function getFileDescription(file) {
|
||||
if (file.state === 'unknown') {
|
||||
@@ -84,11 +84,13 @@ function FileMenu({ onDelete, onClose }) {
|
||||
}
|
||||
|
||||
function FileMenuButton({ state, onDelete }) {
|
||||
const triggerRef = useRef(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
aria-label="Menu"
|
||||
onClick={e => {
|
||||
@@ -98,19 +100,18 @@ function FileMenuButton({ state, onDelete }) {
|
||||
>
|
||||
<SvgDotsHorizontalTriple style={{ width: 16, height: 16 }} />
|
||||
</Button>
|
||||
{menuOpen && (
|
||||
<Tooltip
|
||||
position="bottom-right"
|
||||
style={{ padding: 0 }}
|
||||
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<FileMenu
|
||||
state={state}
|
||||
onDelete={onDelete}
|
||||
onClose={() => setMenuOpen(false)}
|
||||
>
|
||||
<FileMenu
|
||||
state={state}
|
||||
onDelete={onDelete}
|
||||
onClose={() => setMenuOpen(false)}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</Popover>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { type ComponentProps, useState } from 'react';
|
||||
import React, { type ComponentProps, useRef, useState } from 'react';
|
||||
|
||||
import { type AccountEntity } from 'loot-core/types/models';
|
||||
|
||||
@@ -10,10 +10,10 @@ import { type CSSProperties, styles, theme } from '../../style';
|
||||
import { Button } from '../common/Button';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Modal, ModalTitle } from '../common/Modal';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { View } from '../common/View';
|
||||
import { type CommonModalProps } from '../Modals';
|
||||
import { Notes } from '../Notes';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
type AccountMenuModalProps = {
|
||||
modalProps: CommonModalProps;
|
||||
@@ -155,6 +155,7 @@ function AdditionalAccountMenu({
|
||||
onClose,
|
||||
onReopen,
|
||||
}: AdditionalAccountMenuProps) {
|
||||
const triggerRef = useRef(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const itemStyle: CSSProperties = {
|
||||
...styles.mediumText,
|
||||
@@ -169,6 +170,7 @@ function AdditionalAccountMenu({
|
||||
return (
|
||||
<View>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
aria-label="Menu"
|
||||
onClick={() => {
|
||||
@@ -180,47 +182,44 @@ function AdditionalAccountMenu({
|
||||
height={17}
|
||||
style={{ color: 'currentColor' }}
|
||||
/>
|
||||
{menuOpen && (
|
||||
<Tooltip
|
||||
position="bottom-left"
|
||||
style={{ padding: 0 }}
|
||||
onClose={() => {
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
placement="bottom start"
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
getItemStyle={getItemStyle}
|
||||
items={[
|
||||
account.closed
|
||||
? {
|
||||
name: 'reopen',
|
||||
text: 'Reopen account',
|
||||
icon: SvgLockOpen,
|
||||
iconSize: 15,
|
||||
}
|
||||
: {
|
||||
name: 'close',
|
||||
text: 'Close account',
|
||||
icon: SvgClose,
|
||||
iconSize: 15,
|
||||
},
|
||||
]}
|
||||
onMenuSelect={name => {
|
||||
setMenuOpen(false);
|
||||
switch (name) {
|
||||
case 'close':
|
||||
onClose?.(account.id);
|
||||
break;
|
||||
case 'reopen':
|
||||
onReopen?.(account.id);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unrecognized menu option: ${name}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
getItemStyle={getItemStyle}
|
||||
items={[
|
||||
account.closed
|
||||
? {
|
||||
name: 'reopen',
|
||||
text: 'Reopen account',
|
||||
icon: SvgLockOpen,
|
||||
iconSize: 15,
|
||||
}
|
||||
: {
|
||||
name: 'close',
|
||||
text: 'Close account',
|
||||
icon: SvgClose,
|
||||
iconSize: 15,
|
||||
},
|
||||
]}
|
||||
onMenuSelect={name => {
|
||||
setMenuOpen(false);
|
||||
switch (name) {
|
||||
case 'close':
|
||||
onClose?.(account.id);
|
||||
break;
|
||||
case 'reopen':
|
||||
onReopen?.(account.id);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unrecognized menu option: ${name}`);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</Popover>
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-strict-ignore
|
||||
import React, { type ComponentProps, useState } from 'react';
|
||||
import React, { type ComponentProps, useRef, useState } from 'react';
|
||||
|
||||
import { type CategoryGroupEntity } from 'loot-core/src/types/models';
|
||||
|
||||
@@ -11,10 +11,10 @@ import { type CSSProperties, styles, theme } from '../../style';
|
||||
import { Button } from '../common/Button';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Modal, ModalTitle } from '../common/Modal';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { View } from '../common/View';
|
||||
import { type CommonModalProps } from '../Modals';
|
||||
import { Notes } from '../Notes';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
type CategoryGroupMenuModalProps = {
|
||||
modalProps: CommonModalProps;
|
||||
@@ -155,6 +155,7 @@ export function CategoryGroupMenuModal({
|
||||
}
|
||||
|
||||
function AdditionalCategoryGroupMenu({ group, onDelete, onToggleVisibility }) {
|
||||
const triggerRef = useRef(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const itemStyle: CSSProperties = {
|
||||
...styles.mediumText,
|
||||
@@ -170,6 +171,7 @@ function AdditionalCategoryGroupMenu({ group, onDelete, onToggleVisibility }) {
|
||||
<View>
|
||||
{!group.is_income && (
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
aria-label="Menu"
|
||||
onClick={() => {
|
||||
@@ -181,52 +183,47 @@ function AdditionalCategoryGroupMenu({ group, onDelete, onToggleVisibility }) {
|
||||
height={17}
|
||||
style={{ color: 'currentColor' }}
|
||||
/>
|
||||
{menuOpen && (
|
||||
<Tooltip
|
||||
position="bottom-left"
|
||||
style={{ padding: 0 }}
|
||||
onClose={() => {
|
||||
setMenuOpen(false);
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
placement="bottom start"
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
style={{
|
||||
...styles.mediumText,
|
||||
color: theme.formLabelText,
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
style={{
|
||||
...styles.mediumText,
|
||||
color: theme.formLabelText,
|
||||
}}
|
||||
getItemStyle={getItemStyle}
|
||||
items={
|
||||
[
|
||||
getItemStyle={getItemStyle}
|
||||
items={
|
||||
[
|
||||
{
|
||||
name: 'toggleVisibility',
|
||||
text: group.hidden ? 'Show' : 'Hide',
|
||||
icon: group.hidden ? SvgViewShow : SvgViewHide,
|
||||
iconSize: 16,
|
||||
},
|
||||
...(!group.is_income && [
|
||||
Menu.line,
|
||||
{
|
||||
name: 'toggleVisibility',
|
||||
text: group.hidden ? 'Show' : 'Hide',
|
||||
icon: group.hidden ? SvgViewShow : SvgViewHide,
|
||||
iconSize: 16,
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
icon: SvgTrash,
|
||||
iconSize: 15,
|
||||
},
|
||||
...(!group.is_income && [
|
||||
Menu.line,
|
||||
{
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
icon: SvgTrash,
|
||||
iconSize: 15,
|
||||
},
|
||||
]),
|
||||
].filter(i => i != null) as ComponentProps<
|
||||
typeof Menu
|
||||
>['items']
|
||||
]),
|
||||
].filter(i => i != null) as ComponentProps<typeof Menu>['items']
|
||||
}
|
||||
onMenuSelect={itemName => {
|
||||
setMenuOpen(false);
|
||||
if (itemName === 'delete') {
|
||||
onDelete();
|
||||
} else if (itemName === 'toggleVisibility') {
|
||||
onToggleVisibility();
|
||||
}
|
||||
onMenuSelect={itemName => {
|
||||
setMenuOpen(false);
|
||||
if (itemName === 'delete') {
|
||||
onDelete();
|
||||
} else if (itemName === 'toggleVisibility') {
|
||||
onToggleVisibility();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
}}
|
||||
/>
|
||||
</Popover>
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-strict-ignore
|
||||
import React, { useState } from 'react';
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
import { type CategoryEntity } from 'loot-core/src/types/models';
|
||||
|
||||
@@ -12,10 +12,10 @@ import { type CSSProperties, styles, theme } from '../../style';
|
||||
import { Button } from '../common/Button';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Modal, ModalTitle } from '../common/Modal';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { View } from '../common/View';
|
||||
import { type CommonModalProps } from '../Modals';
|
||||
import { Notes } from '../Notes';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
type CategoryMenuModalProps = {
|
||||
modalProps: CommonModalProps;
|
||||
@@ -147,6 +147,7 @@ function AdditionalCategoryMenu({
|
||||
onDelete,
|
||||
onToggleVisibility,
|
||||
}) {
|
||||
const triggerRef = useRef(null);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const itemStyle: CSSProperties = {
|
||||
...styles.mediumText,
|
||||
@@ -161,6 +162,7 @@ function AdditionalCategoryMenu({
|
||||
return (
|
||||
<View>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
aria-label="Menu"
|
||||
onClick={() => {
|
||||
@@ -172,42 +174,39 @@ function AdditionalCategoryMenu({
|
||||
height={17}
|
||||
style={{ color: 'currentColor' }}
|
||||
/>
|
||||
{menuOpen && (
|
||||
<Tooltip
|
||||
position="bottom-left"
|
||||
style={{ padding: 0 }}
|
||||
onClose={() => {
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
placement="bottom start"
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
getItemStyle={getItemStyle}
|
||||
items={[
|
||||
!categoryGroup?.hidden && {
|
||||
name: 'toggleVisibility',
|
||||
text: category.hidden ? 'Show' : 'Hide',
|
||||
icon: category.hidden ? SvgViewShow : SvgViewHide,
|
||||
iconSize: 16,
|
||||
},
|
||||
!categoryGroup?.hidden && Menu.line,
|
||||
{
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
icon: SvgTrash,
|
||||
iconSize: 15,
|
||||
},
|
||||
]}
|
||||
onMenuSelect={itemName => {
|
||||
setMenuOpen(false);
|
||||
if (itemName === 'delete') {
|
||||
onDelete();
|
||||
} else if (itemName === 'toggleVisibility') {
|
||||
onToggleVisibility();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
getItemStyle={getItemStyle}
|
||||
items={[
|
||||
!categoryGroup?.hidden && {
|
||||
name: 'toggleVisibility',
|
||||
text: category.hidden ? 'Show' : 'Hide',
|
||||
icon: category.hidden ? SvgViewShow : SvgViewHide,
|
||||
iconSize: 16,
|
||||
},
|
||||
!categoryGroup?.hidden && Menu.line,
|
||||
{
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
icon: SvgTrash,
|
||||
iconSize: 15,
|
||||
},
|
||||
]}
|
||||
onMenuSelect={itemName => {
|
||||
setMenuOpen(false);
|
||||
if (itemName === 'delete') {
|
||||
onDelete();
|
||||
} else if (itemName === 'toggleVisibility') {
|
||||
onToggleVisibility();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
/>
|
||||
</Popover>
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -40,9 +40,9 @@ import { Modal } from '../common/Modal';
|
||||
import { Select } from '../common/Select';
|
||||
import { Stack } from '../common/Stack';
|
||||
import { Text } from '../common/Text';
|
||||
import { Tooltip } from '../common/Tooltip';
|
||||
import { View } from '../common/View';
|
||||
import { StatusBadge } from '../schedules/StatusBadge';
|
||||
import { Tooltip } from '../tooltips';
|
||||
import { SimpleTransactionsTable } from '../transactions/SimpleTransactionsTable';
|
||||
import { BetweenAmountInput } from '../util/AmountInput';
|
||||
import { DisplayId } from '../util/DisplayId';
|
||||
@@ -415,33 +415,29 @@ function ActionEditor({ action, editorStyle, onChange, onDelete, onAdd }) {
|
||||
}
|
||||
|
||||
function StageInfo() {
|
||||
const [open, setOpen] = useState();
|
||||
|
||||
return (
|
||||
<View style={{ position: 'relative', marginLeft: 5 }}>
|
||||
<View
|
||||
onMouseEnter={() => setOpen(true)}
|
||||
onMouseLeave={() => setOpen(false)}
|
||||
<Tooltip
|
||||
content={
|
||||
<>
|
||||
The stage of a rule allows you to force a specific order. Pre rules
|
||||
always run first, and post rules always run last. Within each stage
|
||||
rules are automatically ordered from least to most specific.
|
||||
</>
|
||||
}
|
||||
placement="bottom start"
|
||||
style={{
|
||||
...styles.tooltip,
|
||||
padding: 10,
|
||||
color: theme.pageTextLight,
|
||||
maxWidth: 450,
|
||||
lineHeight: 1.5,
|
||||
}}
|
||||
>
|
||||
<SvgInformationOutline
|
||||
style={{ width: 11, height: 11, color: theme.pageTextLight }}
|
||||
/>
|
||||
</View>
|
||||
{open && (
|
||||
<Tooltip
|
||||
position="bottom-left"
|
||||
style={{
|
||||
padding: 10,
|
||||
color: theme.pageTextLight,
|
||||
maxWidth: 450,
|
||||
lineHeight: 1.5,
|
||||
}}
|
||||
>
|
||||
The stage of a rule allows you to force a specific order. Pre rules
|
||||
always run first, and post rules always run last. Within each stage
|
||||
rules are automatically ordered from least to most specific.
|
||||
</Tooltip>
|
||||
)}
|
||||
</Tooltip>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ import { Link } from '../common/Link';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Modal } from '../common/Modal';
|
||||
import { Paragraph } from '../common/Paragraph';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { View } from '../common/View';
|
||||
import { FormField, FormLabel } from '../forms';
|
||||
import { type CommonModalProps } from '../Modals';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
import { COUNTRY_OPTIONS } from './countries';
|
||||
|
||||
@@ -103,6 +103,7 @@ export function GoCardlessExternalMsg({
|
||||
>(null);
|
||||
const [menuOpen, setMenuOpen] = useState<boolean>(false);
|
||||
const data = useRef<GoCardlessToken | null>(null);
|
||||
const triggerRef = useRef(null);
|
||||
|
||||
const {
|
||||
data: bankOptions,
|
||||
@@ -230,6 +231,7 @@ export function GoCardlessExternalMsg({
|
||||
Link bank in browser →
|
||||
</Button>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
onClick={() => setMenuOpen(true)}
|
||||
aria-label="Menu"
|
||||
@@ -239,28 +241,27 @@ export function GoCardlessExternalMsg({
|
||||
height={15}
|
||||
style={{ transform: 'rotateZ(90deg)' }}
|
||||
/>
|
||||
{menuOpen && (
|
||||
<Tooltip
|
||||
position="bottom-right"
|
||||
width={200}
|
||||
style={{ padding: 0 }}
|
||||
onClose={() => setMenuOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
onMenuSelect={item => {
|
||||
if (item === 'reconfigure') {
|
||||
onGoCardlessInit();
|
||||
}
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
name: 'reconfigure',
|
||||
text: 'Set new API secrets',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
style={{ width: 200 }}
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
onMenuSelect={item => {
|
||||
if (item === 'reconfigure') {
|
||||
onGoCardlessInit();
|
||||
}
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
name: 'reconfigure',
|
||||
text: 'Set new API secrets',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Popover>
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useStableCallback } from '../../hooks/useStableCallback';
|
||||
import { SvgExpandArrow } from '../../icons/v0';
|
||||
import { theme } from '../../style';
|
||||
import { Button } from '../common/Button';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { Search } from '../common/Search';
|
||||
import { View } from '../common/View';
|
||||
import { TableHeader, Cell, SelectCell, useTableNavigator } from '../table';
|
||||
@@ -102,6 +103,7 @@ export const ManagePayees = forwardRef(
|
||||
const [filter, setFilter] = useState('');
|
||||
const table = useRef(null);
|
||||
const scrollTo = useRef(null);
|
||||
const triggerRef = useRef(null);
|
||||
const resetAnimation = useRef(false);
|
||||
const [orphanedOnly, setOrphanedOnly] = useState(false);
|
||||
|
||||
@@ -233,6 +235,7 @@ export const ManagePayees = forwardRef(
|
||||
>
|
||||
<View style={{ flexShrink: 0 }}>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
style={{ marginRight: 10 }}
|
||||
disabled={buttonsDisabled}
|
||||
@@ -245,7 +248,14 @@ export const ManagePayees = forwardRef(
|
||||
plural(selected.items.size, 'payee', 'payees')}
|
||||
<SvgExpandArrow width={8} height={8} style={{ marginLeft: 5 }} />
|
||||
</Button>
|
||||
{menuOpen && (
|
||||
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={menuOpen}
|
||||
placement="bottom start"
|
||||
style={{ width: 250 }}
|
||||
onOpenChange={() => setMenuOpen(false)}
|
||||
>
|
||||
<PayeeMenu
|
||||
payeesById={payeesById}
|
||||
selectedPayees={selected.items}
|
||||
@@ -253,7 +263,7 @@ export const ManagePayees = forwardRef(
|
||||
onDelete={onDelete}
|
||||
onMerge={onMerge}
|
||||
/>
|
||||
)}
|
||||
</Popover>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
|
||||
@@ -4,7 +4,6 @@ import { SvgDelete, SvgMerge } from '../../icons/v0';
|
||||
import { theme } from '../../style';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { View } from '../common/View';
|
||||
import { Tooltip } from '../tooltips';
|
||||
|
||||
type PayeeMenuProps = {
|
||||
payeesById: Record<PayeeEntity['id'], PayeeEntity>;
|
||||
@@ -27,57 +26,50 @@ export function PayeeMenu({
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
position="bottom"
|
||||
width={250}
|
||||
style={{ padding: 0 }}
|
||||
onClose={onClose}
|
||||
>
|
||||
<Menu
|
||||
onMenuSelect={type => {
|
||||
onClose();
|
||||
switch (type) {
|
||||
case 'delete':
|
||||
onDelete();
|
||||
break;
|
||||
case 'merge':
|
||||
onMerge();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}}
|
||||
footer={
|
||||
<View
|
||||
style={{
|
||||
padding: 3,
|
||||
fontSize: 11,
|
||||
fontStyle: 'italic',
|
||||
color: theme.pageTextSubdued,
|
||||
}}
|
||||
>
|
||||
{[...selectedPayees]
|
||||
.slice(0, 4)
|
||||
.map(id => payeesById[id].name)
|
||||
.join(', ') + (selectedPayees.size > 4 ? ', and more' : '')}
|
||||
</View>
|
||||
<Menu
|
||||
onMenuSelect={type => {
|
||||
onClose();
|
||||
switch (type) {
|
||||
case 'delete':
|
||||
onDelete();
|
||||
break;
|
||||
case 'merge':
|
||||
onMerge();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
items={[
|
||||
{
|
||||
icon: SvgDelete,
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
disabled: isDisabled,
|
||||
},
|
||||
{
|
||||
icon: SvgMerge,
|
||||
iconSize: 9,
|
||||
name: 'merge',
|
||||
text: 'Merge',
|
||||
disabled: isDisabled || selectedPayees.size < 2,
|
||||
},
|
||||
Menu.line,
|
||||
]}
|
||||
/>
|
||||
</Tooltip>
|
||||
}}
|
||||
footer={
|
||||
<View
|
||||
style={{
|
||||
padding: 3,
|
||||
fontSize: 11,
|
||||
fontStyle: 'italic',
|
||||
color: theme.pageTextSubdued,
|
||||
}}
|
||||
>
|
||||
{[...selectedPayees]
|
||||
.slice(0, 4)
|
||||
.map(id => payeesById[id].name)
|
||||
.join(', ') + (selectedPayees.size > 4 ? ', and more' : '')}
|
||||
</View>
|
||||
}
|
||||
items={[
|
||||
{
|
||||
icon: SvgDelete,
|
||||
name: 'delete',
|
||||
text: 'Delete',
|
||||
disabled: isDisabled,
|
||||
},
|
||||
{
|
||||
icon: SvgMerge,
|
||||
iconSize: 9,
|
||||
name: 'merge',
|
||||
text: 'Merge',
|
||||
disabled: isDisabled || selectedPayees.size < 2,
|
||||
},
|
||||
Menu.line,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-strict-ignore
|
||||
import React, { useState, useMemo, type CSSProperties } from 'react';
|
||||
import React, { useRef, useState, useMemo, type CSSProperties } from 'react';
|
||||
|
||||
import {
|
||||
type ScheduleStatusType,
|
||||
@@ -18,11 +18,11 @@ import { SvgCheck } from '../../icons/v2';
|
||||
import { theme } from '../../style';
|
||||
import { Button } from '../common/Button';
|
||||
import { Menu } from '../common/Menu';
|
||||
import { Popover } from '../common/Popover';
|
||||
import { Text } from '../common/Text';
|
||||
import { View } from '../common/View';
|
||||
import { PrivacyFilter } from '../PrivacyFilter';
|
||||
import { Table, TableHeader, Row, Field, Cell } from '../table';
|
||||
import { Tooltip } from '../tooltips';
|
||||
import { DisplayId } from '../util/DisplayId';
|
||||
|
||||
import { StatusBadge } from './StatusBadge';
|
||||
@@ -60,6 +60,7 @@ function OverflowMenu({
|
||||
status: ScheduleStatusType;
|
||||
onAction: SchedulesTableProps['onAction'];
|
||||
}) {
|
||||
const triggerRef = useRef(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const getMenuItems = () => {
|
||||
@@ -96,6 +97,7 @@ function OverflowMenu({
|
||||
return (
|
||||
<View>
|
||||
<Button
|
||||
ref={triggerRef}
|
||||
type="bare"
|
||||
aria-label="Menu"
|
||||
onClick={e => {
|
||||
@@ -109,22 +111,20 @@ function OverflowMenu({
|
||||
style={{ transform: 'rotateZ(90deg)' }}
|
||||
/>
|
||||
</Button>
|
||||
{open && (
|
||||
<Tooltip
|
||||
position="bottom-right"
|
||||
width={150}
|
||||
style={{ padding: 0 }}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
onMenuSelect={name => {
|
||||
onAction(name, schedule.id);
|
||||
setOpen(false);
|
||||
}}
|
||||
items={getMenuItems()}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Popover
|
||||
triggerRef={triggerRef}
|
||||
isOpen={open}
|
||||
onOpenChange={() => setOpen(false)}
|
||||
>
|
||||
<Menu
|
||||
onMenuSelect={name => {
|
||||
onAction(name, schedule.id);
|
||||
setOpen(false);
|
||||
}}
|
||||
items={getMenuItems()}
|
||||
/>
|
||||
</Popover>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
6
upcoming-release-notes/2771.md
Normal file
6
upcoming-release-notes/2771.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Maintenance
|
||||
authors: [MatissJanis]
|
||||
---
|
||||
|
||||
Migrating native `Tooltip` component to react-aria Tooltip/Popover (vol.6)
|
||||
Reference in New Issue
Block a user