Skip to content

Commit 5d6269f

Browse files
authored
feat(view/useFilesGallery): add possibility to override gallery item props (#824)
1 parent 2bbc465 commit 5d6269f

File tree

9 files changed

+178
-17
lines changed

9 files changed

+178
-17
lines changed

demo/stories/view/gallery/ViewWithGallery.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ import './ViewWithGallery.scss';
88

99
export type ViewWithGalleryProps = YfmStaticViewProps;
1010

11+
const getCopyUrl = (url: string) => url;
12+
const getDownloadUrl = (url: string) => url;
13+
1114
const ViewWithGalleryContent: FC<ViewWithGalleryProps> = (props) => {
12-
const {openFilesGallery} = useFilesGallery();
15+
const {openFilesGallery} = useFilesGallery(undefined, {
16+
copyUrl: getCopyUrl,
17+
download: getDownloadUrl,
18+
});
1319

1420
return (
1521
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
"@diplodoc/quote-link-extension": "0.1.3",
230230
"@diplodoc/tabs-extension": "^3.5.1",
231231
"@diplodoc/transform": "^4.58.0",
232-
"@gravity-ui/components": "4.2.2",
232+
"@gravity-ui/components": "4.10.0",
233233
"@gravity-ui/eslint-config": "3.3.0",
234234
"@gravity-ui/gulp-utils": "1.0.3",
235235
"@gravity-ui/prettier-config": "1.1.0",
@@ -327,7 +327,7 @@
327327
"@diplodoc/quote-link-extension": "^0.1.3",
328328
"@diplodoc/tabs-extension": "^3.5.1",
329329
"@diplodoc/transform": "^4.43.0",
330-
"@gravity-ui/components": "^4.2.2",
330+
"@gravity-ui/components": "^4.10.0",
331331
"@gravity-ui/uikit": "^7.1.0",
332332
"highlight.js": "^11.8.0",
333333
"katex": "^0.16.9",

src/i18n/gallery/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"link_copied": "The link copied",
3+
"link_copy": "Copy link",
4+
"file_download": "Download"
5+
}

src/i18n/gallery/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {registerKeyset} from '../i18n';
2+
3+
import en from './en.json';
4+
import ru from './ru.json';
5+
6+
const KEYSET = 'gallery';
7+
8+
export const i18n = registerKeyset(KEYSET, {en, ru});

src/i18n/gallery/ru.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"link_copied": "Ссылка скопирована",
3+
"link_copy": "Скопировать ссылку",
4+
"file_download": "Скачать"
5+
}

src/view/hooks/useFilesGallery/README.md

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@ _GalleryProvider_:
1515

1616
_useFilesGallery_
1717

18-
| Property | Type | Required | Values | Default | Description |
19-
| :---------- | :----------------------------------- | :------- | :----- | :------ | :-------------------------------------------------------------------------------------------------------------------------- |
20-
| customFiles | `(GalleryItem & { url?: string })[]` | | | | The additional files list (pass the url to be able to exclude the items from content if they are found in the custom files) |
18+
| Property | Type | Required | Values | Default | Description |
19+
|:------------|:---------------------------------------------| :------- | :----- | :------ |:----------------------------------------------------------------------------------------------------------------------------|
20+
| customFiles | `(GalleryItem & { url?: string })[]` | | | | The additional files list (pass the url to be able to exclude the items from content if they are found in the custom files) |
21+
| options | `UseFilesGalleryOptions` | | | | The files gallery options |
22+
23+
_UseFilesGalleryOptions_
24+
25+
| Property | Type | Required | Values | Default | Description |
26+
|:------------------|:---------------------------------------------------------------------------------------------------------------|:---------|:-------|:--------|:----------------------------------------------------------------------------------------------|
27+
| download | `(url: string, type: FilesGalleryItemType, element: Element) => string or undefined` | | | | The file download link getter (if you want to show the download action) |
28+
| copyUrl | `(url: string, type: FilesGalleryItemType, element: Element) => string or undefined` | | | | The file copy link getter (if you want to show the copy link action) |
29+
| overrideItemProps | `(url: string, type: FilesGalleryItemType, element: Element, currentProps: GalleryItemProps) => GalleryItemProps` | | | | The custom gallery item props getter (if you want to override the default gallery item props) |
30+
2131

2232
_useFilesGallery returns function `openFilesGallery` with the following args_:
2333

@@ -74,3 +84,41 @@ const {openFilesGallery} = useFilesGallery(customFiles);
7484
<YfmStaticView {...props} />
7585
</div>;
7686
```
87+
88+
If you want to add download and copy link action, provide download and copyUrl options
89+
90+
```tsx
91+
import {YfmStaticView, useFilesGallery} from '@gravity-ui/markdown-editor/view';
92+
93+
const {openFilesGallery} = useFilesGallery(undefined, {download: urlFromContent => getDownloadUrl(urlFromContent), copyUrl: urlFromContent => getUrlForCopy(urlFromContent)});
94+
95+
<div onClick={openFilesGallery}>
96+
<YfmStaticView {...props} />
97+
</div>;
98+
```
99+
100+
If you want to override some gallery item props, provide overrideItemProps option
101+
102+
```tsx
103+
import {YfmStaticView, useFilesGallery} from '@gravity-ui/markdown-editor/view';
104+
105+
function getGalleryItemProps(url: string, type: 'image' | 'video', element: Element, currentProps: GalleryItemProps) {
106+
return {
107+
actions: [
108+
{
109+
id: 'download',
110+
title: 'Download',
111+
icon: <Icon data={ArrowDownToLineIcon} />,
112+
href: url,
113+
onClick: handleDownload,
114+
}
115+
]
116+
}
117+
}
118+
119+
const {openFilesGallery} = useFilesGallery(undefined, {overrideItemProps:getGalleryItemProps});
120+
121+
<div onClick={openFilesGallery}>
122+
<YfmStaticView {...props} />
123+
</div>;
124+
```

src/view/hooks/useFilesGallery/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,16 @@ export type GalleryItemPropsWithUrl = GalleryItemProps & {
44
// pass the url to be able to exclude the items from content if they are found in the custom files
55
url?: string;
66
};
7+
8+
export type FilesGalleryItemType = 'image' | 'video';
9+
10+
export type UseFilesGalleryOptions = {
11+
download?: (url: string, type: FilesGalleryItemType, element: Element) => string | undefined;
12+
copyUrl?: (url: string, type: FilesGalleryItemType, element: Element) => string | undefined;
13+
overrideItemProps?: (
14+
url: string,
15+
type: FilesGalleryItemType,
16+
element: Element,
17+
currentProps: GalleryItemProps,
18+
) => GalleryItemProps;
19+
};

src/view/hooks/useFilesGallery/useFilesGallery.tsx

Lines changed: 83 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
import * as React from 'react';
22

3-
import {getGalleryItemImage, getGalleryItemVideo, useGallery} from '@gravity-ui/components';
3+
import {
4+
type GalleryItemAction,
5+
getGalleryItemCopyLinkAction,
6+
getGalleryItemDownloadAction,
7+
getGalleryItemImage,
8+
getGalleryItemVideo,
9+
useGallery,
10+
} from '@gravity-ui/components';
11+
import {useToaster} from '@gravity-ui/uikit';
12+
13+
import {i18n} from 'src/i18n/gallery';
414

515
import {extensionRegex, supportedExtensions, supportedVideoExtensions} from './constants';
6-
import type {GalleryItemPropsWithUrl} from './types';
7-
8-
export function useFilesGallery(customFiles?: GalleryItemPropsWithUrl[]) {
16+
import type {FilesGalleryItemType, GalleryItemPropsWithUrl, UseFilesGalleryOptions} from './types';
17+
18+
export function useFilesGallery(
19+
customFiles?: GalleryItemPropsWithUrl[],
20+
{
21+
download: getItemDownloladUrl,
22+
overrideItemProps,
23+
copyUrl: getItemCopyUrl,
24+
}: UseFilesGalleryOptions = {},
25+
) {
926
const {openGallery} = useGallery();
1027

28+
const toaster = useToaster();
29+
1130
return {
1231
openFilesGallery: React.useCallback(
1332
(event: React.MouseEvent<HTMLDivElement>) => {
@@ -44,11 +63,61 @@ export function useFilesGallery(customFiles?: GalleryItemPropsWithUrl[]) {
4463
? element.getAttribute('alt')
4564
: element.getAttribute('title')) || '';
4665

47-
result.push({
48-
...(supportedVideoExtensions.includes(extension)
66+
const filesGalleryItemType: FilesGalleryItemType =
67+
supportedVideoExtensions.includes(extension) ? 'video' : 'image';
68+
const galleryItemActions: GalleryItemAction[] = [];
69+
70+
const itemCopyUrl = getItemCopyUrl?.(
71+
link,
72+
filesGalleryItemType,
73+
element,
74+
);
75+
76+
if (itemCopyUrl) {
77+
const handleLinkCopied = () => {
78+
toaster.add({
79+
theme: 'success',
80+
name: 'g-md-editor-gallery-copy-link',
81+
title: i18n('link_copied'),
82+
});
83+
};
84+
85+
galleryItemActions.push(
86+
getGalleryItemCopyLinkAction({
87+
copyUrl: itemCopyUrl,
88+
onCopy: handleLinkCopied,
89+
}),
90+
);
91+
}
92+
93+
const downloadUrl = getItemDownloladUrl?.(
94+
link,
95+
filesGalleryItemType,
96+
element,
97+
);
98+
99+
if (downloadUrl) {
100+
galleryItemActions.push(
101+
getGalleryItemDownloadAction({downloadUrl}),
102+
);
103+
}
104+
105+
const galleryItemProps = {
106+
...(filesGalleryItemType === 'video'
49107
? getGalleryItemVideo({src: link, name: name})
50108
: getGalleryItemImage({src: link, name: name})),
51109
url: link,
110+
actions: galleryItemActions,
111+
};
112+
113+
result.push({
114+
...galleryItemProps,
115+
...overrideItemProps?.(
116+
link,
117+
filesGalleryItemType,
118+
element,
119+
galleryItemProps,
120+
),
52121
});
53122
}
54123
}
@@ -68,7 +137,14 @@ export function useFilesGallery(customFiles?: GalleryItemPropsWithUrl[]) {
68137

69138
return false;
70139
},
71-
[customFiles, openGallery],
140+
[
141+
customFiles,
142+
getItemCopyUrl,
143+
getItemDownloladUrl,
144+
overrideItemProps,
145+
toaster,
146+
openGallery,
147+
],
72148
),
73149
};
74150
}

0 commit comments

Comments
 (0)