Skip to content

Commit 3136570

Browse files
authored
feat(Gallery): add default gallery file actions (#327)
1 parent 1b1e6b0 commit 3136570

7 files changed

Lines changed: 133 additions & 2 deletions

File tree

src/components/Gallery/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ import {
5757
{...getGalleryItemDocument({src, name, className})}
5858
actions={renderActions()}
5959
/>
60+
61+
// you can use the pre-defined file actions (copy and download)
62+
<GalleryItem
63+
key={index}
64+
{...getGalleryItemImage({src, name, className})}
65+
actions={[
66+
getGalleryItemCopyLinkAction({
67+
copyUrl: 'https://example.jpg',
68+
onCopy: () => console.log('link copied'),
69+
}),
70+
getGalleryItemDownloadAction({
71+
downloadUrl: 'https://example.jpg',
72+
onClick: () => console.log('download action clicked'),
73+
}),
74+
]}
75+
/>
6076
```
6177

6278
### Examples

src/components/Gallery/__stories__/Gallery.stories.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ import {
1919
Gallery,
2020
GalleryItem,
2121
GalleryItemAction,
22+
getGalleryItemCopyLinkAction,
2223
getGalleryItemDocument,
24+
getGalleryItemDownloadAction,
2325
getGalleryItemImage,
2426
getGalleryItemVideo,
2527
} from '../';
@@ -190,6 +192,53 @@ const FilesGalleryTemplate: StoryFn<GalleryProps> = () => {
190192

191193
export const FilesGallery = FilesGalleryTemplate.bind({});
192194

195+
const FilesGalleryWithPreDefinedActionsTemplate: StoryFn<GalleryProps> = () => {
196+
const mobile = useMobile();
197+
198+
const [open, setOpen] = React.useState(false);
199+
200+
const handleToggle = React.useCallback(() => {
201+
setOpen(false);
202+
}, []);
203+
204+
const handleOpen = React.useCallback(() => {
205+
setOpen(true);
206+
}, []);
207+
208+
return (
209+
<React.Fragment>
210+
<Button onClick={handleOpen} view="action" size="l">
211+
Open gallery
212+
</Button>
213+
<ThemeProvider theme="dark">
214+
<Gallery open={open} onOpenChange={handleToggle}>
215+
{files.map((file, index) => (
216+
<GalleryItem
217+
key={index}
218+
{...getGalleryItemFile(file, mobile)}
219+
actions={
220+
file.type === 'text'
221+
? []
222+
: [
223+
getGalleryItemCopyLinkAction({
224+
copyUrl: file.url,
225+
}),
226+
getGalleryItemDownloadAction({
227+
downloadUrl: file.url,
228+
}),
229+
]
230+
}
231+
interactive={file.interactive}
232+
/>
233+
))}
234+
</Gallery>
235+
</ThemeProvider>
236+
</React.Fragment>
237+
);
238+
};
239+
240+
export const FilesGalleryWithPreDefinedActions = FilesGalleryWithPreDefinedActionsTemplate.bind({});
241+
193242
const EmptyGalleryTemplate: StoryFn<GalleryProps> = () => {
194243
const [open, setOpen] = React.useState(false);
195244

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"close": "Close",
33
"no-items": "No data",
4-
"back": "Back"
4+
"back": "Back",
5+
"copy-link": "Copy link",
6+
"download": "Download"
57
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"close": "Закрыть",
33
"no-items": "Нет данных",
4-
"back": "Назад"
4+
"back": "Назад",
5+
"copy-link": "Скопировать ссылку",
6+
"download": "Скачать"
57
}

src/components/Gallery/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ export * from './components/GalleryItemName';
55
export {getGalleryItemVideo} from './utils/getGalleryItemVideo';
66
export {getGalleryItemImage} from './utils/getGalleryItemImage';
77
export {getGalleryItemDocument} from './utils/getGalleryItemDocument';
8+
export {getGalleryItemDownloadAction} from './utils/getGalleryItemDownloadAction';
9+
export {getGalleryItemCopyLinkAction} from './utils/getGalleryItemCopyLinkAction';
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Link} from '@gravity-ui/icons';
2+
import {ActionTooltip, Button, CopyToClipboard, Icon} from '@gravity-ui/uikit';
3+
4+
import {GalleryItemAction} from '../GalleryItem';
5+
import {i18n} from '../i18n';
6+
7+
export type GetGalleryItemCopyLinkActionArgs = {
8+
copyUrl: string;
9+
onCopy?: () => void;
10+
};
11+
12+
export function getGalleryItemCopyLinkAction({
13+
copyUrl,
14+
onCopy,
15+
}: GetGalleryItemCopyLinkActionArgs): GalleryItemAction {
16+
return {
17+
id: 'copy-url',
18+
title: i18n('copy-link'),
19+
icon: <Icon data={Link} />,
20+
render: (props) => (
21+
<CopyToClipboard text={copyUrl} onCopy={onCopy}>
22+
{() => (
23+
<div>
24+
<ActionTooltip title={i18n('copy-link')}>
25+
<Button {...props} />
26+
</ActionTooltip>
27+
</div>
28+
)}
29+
</CopyToClipboard>
30+
),
31+
};
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {ArrowDownToLine} from '@gravity-ui/icons';
2+
import {Icon} from '@gravity-ui/uikit';
3+
4+
import {GalleryItemAction} from '../GalleryItem';
5+
import {i18n} from '../i18n';
6+
7+
export type GetGalleryItemDownloadActionArgs = {
8+
downloadUrl: string;
9+
onClick?: (event?: MouseEvent) => void;
10+
};
11+
12+
export function getGalleryItemDownloadAction({
13+
downloadUrl,
14+
onClick,
15+
}: GetGalleryItemDownloadActionArgs): GalleryItemAction {
16+
const handleClick = (event?: MouseEvent) => {
17+
event?.stopPropagation();
18+
onClick?.();
19+
};
20+
21+
return {
22+
id: 'download',
23+
title: i18n('download'),
24+
icon: <Icon data={ArrowDownToLine} />,
25+
href: downloadUrl,
26+
onClick: handleClick,
27+
};
28+
}

0 commit comments

Comments
 (0)