Skip to content

Commit fef5ed8

Browse files
committed
fix(Gallery): do not call useTranslation() hook in gallery action builders
1 parent 469c624 commit fef5ed8

File tree

6 files changed

+59
-43
lines changed

6 files changed

+59
-43
lines changed

src/components/Gallery/GalleryItem.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import * as React from 'react';
22

33
import {ButtonProps} from '@gravity-ui/uikit';
44

5+
import type {TProps, WithTFn} from './i18n';
6+
57
export type GalleryItemAction = {
68
id: string;
7-
title: string;
9+
title: string | WithTFn;
810
hotkey?: string;
911
onClick?: () => void;
1012
href?: string;
1113
icon: React.ReactNode;
12-
render?: (props: ButtonProps) => React.ReactNode;
14+
render?: (props: ButtonProps, tProps: TProps) => React.ReactNode;
1315
};
1416

1517
export type GalleryItemProps = {

src/components/Gallery/components/DesktopGalleryHeader/DesktopGalleryHeader.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33
import {ArrowLeft, ArrowRight, Xmark} from '@gravity-ui/icons';
44
import type {ButtonProps} from '@gravity-ui/uikit';
55
import {ActionTooltip, Button, Flex, Icon, Text, useDirection} from '@gravity-ui/uikit';
6+
import isFunction from 'lodash/isFunction';
67

78
import {block} from '../../../utils/cn';
89
import type {GalleryItemAction} from '../../GalleryItem';
@@ -63,23 +64,24 @@ export const DesktopGalleryHeader = ({
6364
)}
6465
<div className={cnDesktopGalleryHeader('actions')}>
6566
{actions?.map((action) => {
67+
const title = isFunction(action.title) ? action.title({t}) : action.title;
6668
const buttonProps: ButtonProps = {
6769
type: 'button',
6870
size: 'l',
6971
view: 'flat',
7072
onClick: action.onClick,
7173
href: action.href,
7274
target: '__blank',
73-
'aria-label': action.title,
75+
'aria-label': title,
7476
children: action.icon,
7577
};
7678

7779
return action.render ? (
7880
<React.Fragment key={action.id}>
79-
{action.render(buttonProps)}
81+
{action.render(buttonProps, {t})}
8082
</React.Fragment>
8183
) : (
82-
<ActionTooltip key={action.id} title={action.title} hotkey={action.hotkey}>
84+
<ActionTooltip key={action.id} title={title} hotkey={action.hotkey}>
8385
<Button {...buttonProps} />
8486
</ActionTooltip>
8587
);

src/components/Gallery/components/MobileGalleryActions/MobileGalleryActions.tsx

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import * as React from 'react';
22

33
import {Button, ButtonProps, Flex, List, Sheet} from '@gravity-ui/uikit';
4+
import isFunction from 'lodash/isFunction';
45

56
import {block} from '../../../utils/cn';
67
import type {GalleryItemAction, GalleryItemProps} from '../../GalleryItem';
8+
import {i18n} from '../../i18n';
79

810
import './MobileGalleryActions.scss';
911

@@ -16,35 +18,47 @@ export type MobileGalleryActionsProps = {
1618
};
1719

1820
export const MobileGalleryActions = ({open, actions = [], onClose}: MobileGalleryActionsProps) => {
19-
const renderListItem = React.useCallback((item: GalleryItemAction) => {
20-
const buttonProps: ButtonProps = {
21-
type: 'button',
22-
size: 'xl',
23-
view: 'flat',
24-
onClick: item.onClick,
25-
href: item.href,
26-
target: '__blank',
27-
'aria-label': item.title,
28-
className: cnMobileGalleryActions('list-item'),
29-
width: 'max',
30-
children: (
31-
<Flex alignItems="center" gap={3} className={cnMobileGalleryActions('custom-item')}>
32-
{item.icon}
33-
{item.title}
34-
</Flex>
35-
),
36-
};
37-
38-
return (
39-
<React.Fragment>
40-
{item.render ? (
41-
<React.Fragment key={item.id}>{item.render(buttonProps)}</React.Fragment>
42-
) : (
43-
<Button {...buttonProps} />
44-
)}
45-
</React.Fragment>
46-
);
47-
}, []);
21+
const {t} = i18n.useTranslation();
22+
23+
const renderListItem = React.useCallback(
24+
(item: GalleryItemAction) => {
25+
const title = isFunction(item.title) ? item.title({t}) : item.title;
26+
const buttonProps: ButtonProps = {
27+
type: 'button',
28+
size: 'xl',
29+
view: 'flat',
30+
onClick: item.onClick,
31+
href: item.href,
32+
target: '__blank',
33+
'aria-label': title,
34+
className: cnMobileGalleryActions('list-item'),
35+
width: 'max',
36+
children: (
37+
<Flex
38+
alignItems="center"
39+
gap={3}
40+
className={cnMobileGalleryActions('custom-item')}
41+
>
42+
{item.icon}
43+
{title}
44+
</Flex>
45+
),
46+
};
47+
48+
return (
49+
<React.Fragment>
50+
{item.render ? (
51+
<React.Fragment key={item.id}>
52+
{item.render(buttonProps, {t})}
53+
</React.Fragment>
54+
) : (
55+
<Button {...buttonProps} />
56+
)}
57+
</React.Fragment>
58+
);
59+
},
60+
[t],
61+
);
4862

4963
return (
5064
<Sheet className={cnMobileGalleryActions()} visible={open} onClose={onClose}>

src/components/Gallery/i18n/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ import en from './en.json';
66
import ru from './ru.json';
77

88
export const i18n = addComponentKeysets({en, ru}, `${NAMESPACE}gallery`);
9+
10+
export type TFn = ReturnType<(typeof i18n)['useTranslation']>['t'];
11+
export type TProps = {t: TFn};
12+
export type WithTFn = (props: TProps) => string;

src/components/Gallery/utils/getGalleryItemCopyLinkAction.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {Link} from '@gravity-ui/icons';
22
import {ActionTooltip, Button, CopyToClipboard, Icon} from '@gravity-ui/uikit';
33

44
import {GalleryItemAction} from '../GalleryItem';
5-
import {i18n} from '../i18n';
65

76
export type GetGalleryItemCopyLinkActionArgs = {
87
copyUrl: string;
@@ -13,13 +12,11 @@ export function getGalleryItemCopyLinkAction({
1312
copyUrl,
1413
onCopy,
1514
}: GetGalleryItemCopyLinkActionArgs): GalleryItemAction {
16-
const {t} = i18n.useTranslation();
17-
1815
return {
1916
id: 'copy-url',
20-
title: t('copy-link'),
17+
title: ({t}) => t('copy-link'),
2118
icon: <Icon data={Link} />,
22-
render: (props) => (
19+
render: (props, {t}) => (
2320
<CopyToClipboard text={copyUrl} onCopy={onCopy}>
2421
{() => (
2522
<div>

src/components/Gallery/utils/getGalleryItemDownloadAction.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {ArrowDownToLine} from '@gravity-ui/icons';
22
import {Icon} from '@gravity-ui/uikit';
33

44
import {GalleryItemAction} from '../GalleryItem';
5-
import {i18n} from '../i18n';
65

76
export type GetGalleryItemDownloadActionArgs = {
87
downloadUrl: string;
@@ -13,16 +12,14 @@ export function getGalleryItemDownloadAction({
1312
downloadUrl,
1413
onClick,
1514
}: GetGalleryItemDownloadActionArgs): GalleryItemAction {
16-
const {t} = i18n.useTranslation();
17-
1815
const handleClick = (event?: MouseEvent) => {
1916
event?.stopPropagation();
2017
onClick?.();
2118
};
2219

2320
return {
2421
id: 'download',
25-
title: t('download'),
22+
title: ({t}) => t('download'),
2623
icon: <Icon data={ArrowDownToLine} />,
2724
href: downloadUrl,
2825
onClick: handleClick,

0 commit comments

Comments
 (0)