@chayns-components/gallery 5.0.0-beta.132 → 5.0.0-beta.1320
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -15
- package/lib/cjs/components/Gallery.js +319 -0
- package/lib/cjs/components/Gallery.js.map +1 -0
- package/lib/cjs/components/Gallery.styles.js +93 -0
- package/lib/cjs/components/Gallery.styles.js.map +1 -0
- package/lib/cjs/components/add-file/AddFile.js +32 -0
- package/lib/cjs/components/add-file/AddFile.js.map +1 -0
- package/lib/cjs/components/add-file/AddFile.styles.js +23 -0
- package/lib/cjs/components/add-file/AddFile.styles.js.map +1 -0
- package/lib/cjs/components/gallery-item/GalleryItem.js +44 -0
- package/lib/cjs/components/gallery-item/GalleryItem.js.map +1 -0
- package/lib/cjs/components/gallery-item/GalleryItem.styles.js +51 -0
- package/lib/cjs/components/gallery-item/GalleryItem.styles.js.map +1 -0
- package/lib/cjs/components/gallery-item/media-item/MediaItem.js +52 -0
- package/lib/cjs/components/gallery-item/media-item/MediaItem.js.map +1 -0
- package/lib/cjs/components/gallery-item/media-item/MediaItem.styles.js +62 -0
- package/lib/cjs/components/gallery-item/media-item/MediaItem.styles.js.map +1 -0
- package/lib/cjs/components/gallery-item/preview-item/PreviewItem.js +45 -0
- package/lib/cjs/components/gallery-item/preview-item/PreviewItem.js.map +1 -0
- package/lib/cjs/components/gallery-item/preview-item/PreviewItem.styles.js +43 -0
- package/lib/cjs/components/gallery-item/preview-item/PreviewItem.styles.js.map +1 -0
- package/lib/cjs/index.js +21 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/types/gallery.js +12 -0
- package/lib/cjs/types/gallery.js.map +1 -0
- package/lib/cjs/utils/file.js +51 -0
- package/lib/cjs/utils/file.js.map +1 -0
- package/lib/esm/components/Gallery.js +305 -0
- package/lib/esm/components/Gallery.js.map +1 -0
- package/lib/esm/components/Gallery.styles.js +86 -0
- package/lib/esm/components/Gallery.styles.js.map +1 -0
- package/lib/esm/components/add-file/AddFile.js +25 -0
- package/lib/esm/components/add-file/AddFile.js.map +1 -0
- package/lib/esm/components/add-file/AddFile.styles.js +16 -0
- package/lib/esm/components/add-file/AddFile.styles.js.map +1 -0
- package/lib/esm/components/gallery-item/GalleryItem.js +36 -0
- package/lib/esm/components/gallery-item/GalleryItem.js.map +1 -0
- package/lib/esm/components/gallery-item/GalleryItem.styles.js +44 -0
- package/lib/esm/components/gallery-item/GalleryItem.styles.js.map +1 -0
- package/lib/esm/components/gallery-item/media-item/MediaItem.js +42 -0
- package/lib/esm/components/gallery-item/media-item/MediaItem.js.map +1 -0
- package/lib/esm/components/gallery-item/media-item/MediaItem.styles.js +55 -0
- package/lib/esm/components/gallery-item/media-item/MediaItem.styles.js.map +1 -0
- package/lib/esm/components/gallery-item/preview-item/PreviewItem.js +38 -0
- package/lib/esm/components/gallery-item/preview-item/PreviewItem.js.map +1 -0
- package/lib/esm/components/gallery-item/preview-item/PreviewItem.styles.js +36 -0
- package/lib/esm/components/gallery-item/preview-item/PreviewItem.styles.js.map +1 -0
- package/lib/esm/index.js +5 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/types/gallery.js +6 -0
- package/lib/esm/types/gallery.js.map +1 -0
- package/lib/esm/utils/file.js +41 -0
- package/lib/esm/utils/file.js.map +1 -0
- package/lib/types/components/Gallery.d.ts +47 -0
- package/lib/types/components/Gallery.styles.d.ts +10 -0
- package/lib/types/components/add-file/AddFile.d.ts +9 -0
- package/lib/types/components/add-file/AddFile.styles.d.ts +4 -0
- package/lib/{components → types/components}/gallery-item/GalleryItem.d.ts +10 -6
- package/lib/types/components/gallery-item/GalleryItem.styles.d.ts +5 -0
- package/lib/types/components/gallery-item/media-item/MediaItem.d.ts +22 -0
- package/lib/types/components/gallery-item/media-item/MediaItem.styles.d.ts +16 -0
- package/lib/types/components/gallery-item/preview-item/PreviewItem.d.ts +14 -0
- package/lib/types/components/gallery-item/preview-item/PreviewItem.styles.d.ts +10 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/types/gallery.d.ts +4 -0
- package/lib/types/utils/file.d.ts +17 -0
- package/package.json +49 -29
- package/lib/api/image/post.d.ts +0 -16
- package/lib/api/image/post.js +0 -34
- package/lib/api/image/post.js.map +0 -1
- package/lib/api/video/post.d.ts +0 -16
- package/lib/api/video/post.js +0 -30
- package/lib/api/video/post.js.map +0 -1
- package/lib/components/Gallery.d.ts +0 -34
- package/lib/components/Gallery.js +0 -163
- package/lib/components/Gallery.js.map +0 -1
- package/lib/components/Gallery.styles.d.ts +0 -6
- package/lib/components/Gallery.styles.js +0 -40
- package/lib/components/Gallery.styles.js.map +0 -1
- package/lib/components/add-file/AddFile.d.ts +0 -26
- package/lib/components/add-file/AddFile.js +0 -83
- package/lib/components/add-file/AddFile.js.map +0 -1
- package/lib/components/add-file/AddFile.styles.d.ts +0 -4
- package/lib/components/add-file/AddFile.styles.js +0 -31
- package/lib/components/add-file/AddFile.styles.js.map +0 -1
- package/lib/components/gallery-item/GalleryItem.js +0 -60
- package/lib/components/gallery-item/GalleryItem.js.map +0 -1
- package/lib/components/gallery-item/GalleryItem.styles.d.ts +0 -17
- package/lib/components/gallery-item/GalleryItem.styles.js +0 -107
- package/lib/components/gallery-item/GalleryItem.styles.js.map +0 -1
- package/lib/index.d.ts +0 -4
- package/lib/index.js +0 -40
- package/lib/index.js.map +0 -1
- package/lib/types/file.d.ts +0 -20
- package/lib/types/file.js +0 -6
- package/lib/types/file.js.map +0 -1
- package/lib/utils/file.d.ts +0 -17
- package/lib/utils/file.js +0 -92
- package/lib/utils/file.js.map +0 -1
- package/lib/utils/upload.d.ts +0 -8
- package/lib/utils/upload.js +0 -56
- package/lib/utils/upload.js.map +0 -1
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { uploadFile } from '@chayns-components/core';
|
|
2
|
+
import { createDialog, DialogType, MediaType, openMedia } from 'chayns-api';
|
|
3
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import { GalleryViewMode } from '../types/gallery';
|
|
6
|
+
import { filterDuplicateFile, generatePreviewUrl, generateVideoThumbnail } from '../utils/file';
|
|
7
|
+
import AddFile from './add-file/AddFile';
|
|
8
|
+
import GalleryItem from './gallery-item/GalleryItem';
|
|
9
|
+
import { StyledGallery, StyledGalleryEditModeWrapper, StyledGalleryItemWrapper } from './Gallery.styles';
|
|
10
|
+
const Gallery = ({
|
|
11
|
+
allowDragAndDrop = false,
|
|
12
|
+
doubleFileDialogMessage = 'Diese Datei ist bereits vorhanden',
|
|
13
|
+
isEditMode = false,
|
|
14
|
+
fileMinWidth = 100,
|
|
15
|
+
files,
|
|
16
|
+
maxFiles,
|
|
17
|
+
onAdd,
|
|
18
|
+
onFileCountChange,
|
|
19
|
+
onRemove,
|
|
20
|
+
viewMode = GalleryViewMode.GRID
|
|
21
|
+
}) => {
|
|
22
|
+
const [fileItems, setFileItems] = useState([]);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This function adds a previewUrl to fileItems
|
|
26
|
+
*/
|
|
27
|
+
const handlePreviewUrlCallback = (previewUrl, file) => {
|
|
28
|
+
setFileItems(prevState => prevState.map(prevFile => {
|
|
29
|
+
if (prevFile.id === file.id) {
|
|
30
|
+
return {
|
|
31
|
+
...prevFile,
|
|
32
|
+
previewUrl
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return prevFile;
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
const callDuplicateFileDialog = useCallback(() => {
|
|
39
|
+
createDialog({
|
|
40
|
+
type: DialogType.ALERT,
|
|
41
|
+
text: doubleFileDialogMessage
|
|
42
|
+
});
|
|
43
|
+
}, [doubleFileDialogMessage]);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This function adds uploaded files to fileItems
|
|
47
|
+
*/
|
|
48
|
+
const handleUploadFileCallback = useCallback((file, uploadedFile) => {
|
|
49
|
+
setFileItems(prevState => {
|
|
50
|
+
const updatedState = prevState.map(prevFile => {
|
|
51
|
+
if (prevFile.uploadedFile?.url === uploadedFile.url) {
|
|
52
|
+
callDuplicateFileDialog();
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
if (prevFile.id === file.id) {
|
|
56
|
+
if (typeof onAdd === 'function') {
|
|
57
|
+
const prevElement = prevState.find(({
|
|
58
|
+
uploadedFile: newUploadedFile
|
|
59
|
+
}) => newUploadedFile?.url === uploadedFile?.url);
|
|
60
|
+
if (!prevElement) {
|
|
61
|
+
onAdd({
|
|
62
|
+
file: uploadedFile,
|
|
63
|
+
id: file.id
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
...prevFile,
|
|
69
|
+
uploadedFile,
|
|
70
|
+
state: 'uploaded'
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return prevFile;
|
|
74
|
+
});
|
|
75
|
+
const tmp = [];
|
|
76
|
+
updatedState.forEach(updatedFile => {
|
|
77
|
+
if (updatedFile !== undefined) {
|
|
78
|
+
tmp.push(updatedFile);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return tmp ?? [];
|
|
82
|
+
});
|
|
83
|
+
}, [callDuplicateFileDialog, onAdd]);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns the current count to check if all files are uploaded
|
|
87
|
+
*/
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (typeof onFileCountChange === 'function') {
|
|
90
|
+
onFileCountChange(fileItems.length);
|
|
91
|
+
}
|
|
92
|
+
}, [fileItems.length, onFileCountChange]);
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Prepares files for previewUrl and upload
|
|
96
|
+
*/
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
const filesToGeneratePreview = fileItems.filter(file => file.file && !file.previewUrl && (file.state === 'none' || !file.state));
|
|
99
|
+
const filesToUpload = fileItems.filter(file => !file.uploadedFile && file.state !== 'uploading');
|
|
100
|
+
filesToGeneratePreview.forEach(file => {
|
|
101
|
+
if (!file.file) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (file.file.type.includes('video/')) {
|
|
105
|
+
generateVideoThumbnail({
|
|
106
|
+
file: file.file,
|
|
107
|
+
callback: previewUrl => handlePreviewUrlCallback(previewUrl, file)
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
generatePreviewUrl({
|
|
112
|
+
file: file.file,
|
|
113
|
+
callback: previewUrl => handlePreviewUrlCallback(previewUrl, file)
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
filesToUpload.forEach(file => {
|
|
117
|
+
setFileItems(prevState => prevState.map(prevFile => {
|
|
118
|
+
if (prevFile.id === file.id) {
|
|
119
|
+
return {
|
|
120
|
+
...prevFile,
|
|
121
|
+
state: 'uploading'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return prevFile;
|
|
125
|
+
}));
|
|
126
|
+
void uploadFile({
|
|
127
|
+
fileToUpload: file,
|
|
128
|
+
callback: UploadedFile => handleUploadFileCallback(file, UploadedFile)
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}, [fileItems, handleUploadFileCallback]);
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* This function formats and adds files to fileItems
|
|
135
|
+
*/
|
|
136
|
+
const handleAddFiles = useCallback(filesToAdd => {
|
|
137
|
+
const newFileItems = [];
|
|
138
|
+
filesToAdd.forEach(file => {
|
|
139
|
+
if (file && !filterDuplicateFile({
|
|
140
|
+
files: fileItems,
|
|
141
|
+
newFile: file
|
|
142
|
+
})) {
|
|
143
|
+
newFileItems.push({
|
|
144
|
+
id: uuidv4(),
|
|
145
|
+
file,
|
|
146
|
+
state: 'none'
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
let tmp = newFileItems;
|
|
151
|
+
if (maxFiles) {
|
|
152
|
+
tmp = newFileItems.slice(0, maxFiles - (fileItems.length + filesToAdd.length - 1));
|
|
153
|
+
}
|
|
154
|
+
setFileItems(prevState => [...prevState, ...tmp]);
|
|
155
|
+
}, [fileItems, maxFiles]);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* This function adds external files to fileItems
|
|
159
|
+
*/
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (files) {
|
|
162
|
+
const newFileItems = [];
|
|
163
|
+
files.forEach(file => {
|
|
164
|
+
newFileItems.push({
|
|
165
|
+
id: file.id ?? uuidv4(),
|
|
166
|
+
uploadedFile: file.file,
|
|
167
|
+
file: undefined,
|
|
168
|
+
state: 'uploaded',
|
|
169
|
+
previewUrl: undefined
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
setFileItems(prevState => {
|
|
173
|
+
const updatedItems = prevState.map(prevItem => {
|
|
174
|
+
const newItem = newFileItems.find(item => item.uploadedFile && item.uploadedFile.url === (prevItem.uploadedFile && prevItem.uploadedFile.url));
|
|
175
|
+
return newItem || prevItem;
|
|
176
|
+
});
|
|
177
|
+
return updatedItems.concat(newFileItems.filter(newItem => !prevState.some(prevItem => prevItem.uploadedFile && newItem.uploadedFile && prevItem.uploadedFile.url === newItem.uploadedFile.url)));
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}, [files]);
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* This function deletes a selected file from the file list
|
|
184
|
+
*/
|
|
185
|
+
const handleDeleteFile = useCallback(id => {
|
|
186
|
+
let fileToDelete;
|
|
187
|
+
const filteredFiles = fileItems.filter(file => {
|
|
188
|
+
const fileId = file.id;
|
|
189
|
+
if (fileId === id && file.uploadedFile) {
|
|
190
|
+
fileToDelete = {
|
|
191
|
+
file: file.uploadedFile,
|
|
192
|
+
id
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return fileId !== id;
|
|
196
|
+
});
|
|
197
|
+
setFileItems(filteredFiles);
|
|
198
|
+
if (!fileToDelete || typeof onRemove !== 'function') {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
onRemove(fileToDelete);
|
|
202
|
+
}, [fileItems, onRemove]);
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* This function handles the drag and drop
|
|
206
|
+
*/
|
|
207
|
+
const handleDrop = useCallback(e => {
|
|
208
|
+
if (!allowDragAndDrop) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
e.preventDefault();
|
|
212
|
+
const draggedFiles = Array.from(e.dataTransfer.files);
|
|
213
|
+
handleAddFiles(draggedFiles);
|
|
214
|
+
}, [allowDragAndDrop, handleAddFiles]);
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Opens the files in a slideShow
|
|
218
|
+
*/
|
|
219
|
+
const openFiles = useCallback(file => {
|
|
220
|
+
const startIndex = fileItems.findIndex(item => item.id === file.id);
|
|
221
|
+
const items = fileItems.map(item => ({
|
|
222
|
+
url: item.uploadedFile?.url.replace('_0.mp4', '.mp4') ?? '',
|
|
223
|
+
mediaType: item.uploadedFile && 'thumbnailUrl' in item.uploadedFile ? MediaType.VIDEO : MediaType.IMAGE
|
|
224
|
+
}));
|
|
225
|
+
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
227
|
+
// @ts-ignore
|
|
228
|
+
void openMedia({
|
|
229
|
+
items,
|
|
230
|
+
startIndex
|
|
231
|
+
});
|
|
232
|
+
}, [fileItems]);
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Returns the ratio of the single file
|
|
236
|
+
*/
|
|
237
|
+
const ratio = useMemo(() => {
|
|
238
|
+
switch (fileItems.length) {
|
|
239
|
+
case 0:
|
|
240
|
+
return 0;
|
|
241
|
+
case 1:
|
|
242
|
+
return Math.max(fileItems[0]?.uploadedFile?.ratio ?? 1, 1);
|
|
243
|
+
case 2:
|
|
244
|
+
return 2;
|
|
245
|
+
case 3:
|
|
246
|
+
return 3;
|
|
247
|
+
default:
|
|
248
|
+
return 1;
|
|
249
|
+
}
|
|
250
|
+
}, [fileItems]);
|
|
251
|
+
const galleryContent = useMemo(() => {
|
|
252
|
+
const combinedFilesLength = fileItems.length;
|
|
253
|
+
if (isEditMode) {
|
|
254
|
+
const items = fileItems.map(file => /*#__PURE__*/React.createElement(GalleryItem, {
|
|
255
|
+
key: file.id,
|
|
256
|
+
fileItem: file,
|
|
257
|
+
isEditMode: true,
|
|
258
|
+
onClick: openFiles,
|
|
259
|
+
handleDeleteFile: handleDeleteFile
|
|
260
|
+
}));
|
|
261
|
+
if (maxFiles && maxFiles <= combinedFilesLength) {
|
|
262
|
+
return items;
|
|
263
|
+
}
|
|
264
|
+
items.push(/*#__PURE__*/React.createElement(AddFile, {
|
|
265
|
+
key: "add_file",
|
|
266
|
+
onAdd: handleAddFiles
|
|
267
|
+
}));
|
|
268
|
+
return items;
|
|
269
|
+
}
|
|
270
|
+
const shortedFiles = fileItems.slice(0, 4);
|
|
271
|
+
return shortedFiles.map((file, index) => {
|
|
272
|
+
let imageRatio = 1;
|
|
273
|
+
if (viewMode === GalleryViewMode.GRID) {
|
|
274
|
+
if (combinedFilesLength === 1) {
|
|
275
|
+
imageRatio = fileItems[0]?.uploadedFile?.ratio ?? 1;
|
|
276
|
+
} else if (combinedFilesLength === 2 && (index === 0 || index === 1)) {
|
|
277
|
+
imageRatio = 0.5;
|
|
278
|
+
} else if (index === 0 && combinedFilesLength > 2 || combinedFilesLength === 3 && (index === 1 || index === 2)) {
|
|
279
|
+
imageRatio = 1.5;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return /*#__PURE__*/React.createElement(GalleryItem, {
|
|
283
|
+
key: file.id,
|
|
284
|
+
fileItem: file,
|
|
285
|
+
isEditMode: false,
|
|
286
|
+
handleDeleteFile: handleDeleteFile,
|
|
287
|
+
onClick: openFiles,
|
|
288
|
+
ratio: imageRatio,
|
|
289
|
+
remainingItemsLength: combinedFilesLength > 4 && index === 3 ? combinedFilesLength : undefined
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
}, [fileItems, isEditMode, maxFiles, handleAddFiles, openFiles, handleDeleteFile, viewMode]);
|
|
293
|
+
return useMemo(() => /*#__PURE__*/React.createElement(StyledGallery, null, isEditMode ? /*#__PURE__*/React.createElement(StyledGalleryEditModeWrapper, {
|
|
294
|
+
$fileMinWidth: fileMinWidth,
|
|
295
|
+
onDragOver: e => e.preventDefault(),
|
|
296
|
+
onDrop: e => void handleDrop(e)
|
|
297
|
+
}, galleryContent) : /*#__PURE__*/React.createElement(StyledGalleryItemWrapper, {
|
|
298
|
+
$ratio: ratio,
|
|
299
|
+
$uploadedFileLength: fileItems.length,
|
|
300
|
+
$viewMode: viewMode
|
|
301
|
+
}, galleryContent)), [isEditMode, fileMinWidth, galleryContent, ratio, fileItems.length, viewMode, handleDrop]);
|
|
302
|
+
};
|
|
303
|
+
Gallery.displayName = 'Gallery';
|
|
304
|
+
export default Gallery;
|
|
305
|
+
//# sourceMappingURL=Gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gallery.js","names":["uploadFile","createDialog","DialogType","MediaType","openMedia","React","useCallback","useEffect","useMemo","useState","v4","uuidv4","GalleryViewMode","filterDuplicateFile","generatePreviewUrl","generateVideoThumbnail","AddFile","GalleryItem","StyledGallery","StyledGalleryEditModeWrapper","StyledGalleryItemWrapper","Gallery","allowDragAndDrop","doubleFileDialogMessage","isEditMode","fileMinWidth","files","maxFiles","onAdd","onFileCountChange","onRemove","viewMode","GRID","fileItems","setFileItems","handlePreviewUrlCallback","previewUrl","file","prevState","map","prevFile","id","callDuplicateFileDialog","type","ALERT","text","handleUploadFileCallback","uploadedFile","updatedState","url","undefined","prevElement","find","newUploadedFile","state","tmp","forEach","updatedFile","push","length","filesToGeneratePreview","filter","filesToUpload","includes","callback","fileToUpload","UploadedFile","handleAddFiles","filesToAdd","newFileItems","newFile","slice","updatedItems","prevItem","newItem","item","concat","some","handleDeleteFile","fileToDelete","filteredFiles","fileId","handleDrop","e","preventDefault","draggedFiles","Array","from","dataTransfer","openFiles","startIndex","findIndex","items","replace","mediaType","VIDEO","IMAGE","ratio","Math","max","galleryContent","combinedFilesLength","createElement","key","fileItem","onClick","shortedFiles","index","imageRatio","remainingItemsLength","$fileMinWidth","onDragOver","onDrop","$ratio","$uploadedFileLength","$viewMode","displayName"],"sources":["../../../src/components/Gallery.tsx"],"sourcesContent":["import {\n Image,\n uploadFile,\n Video,\n type FileItem,\n type InternalFileItem,\n} from '@chayns-components/core';\nimport { createDialog, DialogType, MediaType, openMedia, OpenMediaItem } from 'chayns-api';\nimport React, { DragEvent, FC, useCallback, useEffect, useMemo, useState } from 'react';\nimport { v4 as uuidv4 } from 'uuid';\nimport { GalleryViewMode } from '../types/gallery';\nimport { filterDuplicateFile, generatePreviewUrl, generateVideoThumbnail } from '../utils/file';\nimport AddFile from './add-file/AddFile';\nimport GalleryItem from './gallery-item/GalleryItem';\nimport {\n StyledGallery,\n StyledGalleryEditModeWrapper,\n StyledGalleryItemWrapper,\n} from './Gallery.styles';\n\nexport type GalleryProps = {\n /**\n * Whether drag and drop is allowed or not\n */\n allowDragAndDrop?: boolean;\n /**\n * The message that should be displayed if a File is already given.\n */\n doubleFileDialogMessage?: string;\n /**\n * The minimum width of a file in the edit mode\n */\n fileMinWidth?: number;\n /**\n * Images and videos which should be displayed\n */\n files?: FileItem[];\n /**\n * Whether images and videos can be edited\n */\n isEditMode?: boolean;\n /**\n * The maximum amount of images and videos that can be uploaded.\n */\n maxFiles?: number;\n /**\n * Function to be executed when files are added and uploaded\n */\n onAdd?: (file: FileItem) => void;\n /**\n * Function to be executed when the count of files are changed. Needed to check if all files are uploaded\n */\n onFileCountChange?: (fileCount: number) => void;\n /**\n * Function to be executed when a file is removed\n */\n onRemove?: (file: FileItem) => void;\n /**\n * The mode how the images should be displayed.\n */\n viewMode?: GalleryViewMode;\n};\n\nconst Gallery: FC<GalleryProps> = ({\n allowDragAndDrop = false,\n doubleFileDialogMessage = 'Diese Datei ist bereits vorhanden',\n isEditMode = false,\n fileMinWidth = 100,\n files,\n maxFiles,\n onAdd,\n onFileCountChange,\n onRemove,\n viewMode = GalleryViewMode.GRID,\n}) => {\n const [fileItems, setFileItems] = useState<InternalFileItem[]>([]);\n\n /**\n * This function adds a previewUrl to fileItems\n */\n const handlePreviewUrlCallback = (previewUrl: string, file: InternalFileItem) => {\n setFileItems((prevState) =>\n prevState.map((prevFile) => {\n if (prevFile.id === file.id) {\n return { ...prevFile, previewUrl };\n }\n return prevFile;\n }),\n );\n };\n\n const callDuplicateFileDialog = useCallback(() => {\n createDialog({ type: DialogType.ALERT, text: doubleFileDialogMessage });\n }, [doubleFileDialogMessage]);\n\n /**\n * This function adds uploaded files to fileItems\n */\n const handleUploadFileCallback = useCallback(\n (file: InternalFileItem, uploadedFile: Video | Image) => {\n setFileItems((prevState) => {\n const updatedState = prevState.map((prevFile) => {\n if (prevFile.uploadedFile?.url === uploadedFile.url) {\n callDuplicateFileDialog();\n\n return undefined;\n }\n\n if (prevFile.id === file.id) {\n if (typeof onAdd === 'function') {\n const prevElement = prevState.find(\n ({ uploadedFile: newUploadedFile }) =>\n newUploadedFile?.url === uploadedFile?.url,\n );\n\n if (!prevElement) {\n onAdd({\n file: uploadedFile,\n id: file.id,\n });\n }\n }\n\n return {\n ...prevFile,\n uploadedFile,\n state: 'uploaded',\n };\n }\n\n return prevFile;\n });\n\n const tmp: InternalFileItem[] = [];\n\n updatedState.forEach((updatedFile) => {\n if (updatedFile !== undefined) {\n tmp.push(updatedFile as InternalFileItem);\n }\n });\n\n return tmp ?? [];\n });\n },\n [callDuplicateFileDialog, onAdd],\n );\n\n /**\n * Returns the current count to check if all files are uploaded\n */\n useEffect(() => {\n if (typeof onFileCountChange === 'function') {\n onFileCountChange(fileItems.length);\n }\n }, [fileItems.length, onFileCountChange]);\n\n /**\n * Prepares files for previewUrl and upload\n */\n useEffect(() => {\n const filesToGeneratePreview = fileItems.filter(\n (file) => file.file && !file.previewUrl && (file.state === 'none' || !file.state),\n );\n\n const filesToUpload = fileItems.filter(\n (file) => !file.uploadedFile && file.state !== 'uploading',\n );\n\n filesToGeneratePreview.forEach((file) => {\n if (!file.file) {\n return;\n }\n\n if (file.file.type.includes('video/')) {\n generateVideoThumbnail({\n file: file.file,\n callback: (previewUrl) => handlePreviewUrlCallback(previewUrl, file),\n });\n\n return;\n }\n\n generatePreviewUrl({\n file: file.file,\n callback: (previewUrl) => handlePreviewUrlCallback(previewUrl, file),\n });\n });\n\n filesToUpload.forEach((file) => {\n setFileItems((prevState) =>\n prevState.map((prevFile) => {\n if (prevFile.id === file.id) {\n return { ...prevFile, state: 'uploading' };\n }\n return prevFile;\n }),\n );\n\n void uploadFile({\n fileToUpload: file,\n callback: (UploadedFile) => handleUploadFileCallback(file, UploadedFile),\n });\n });\n }, [fileItems, handleUploadFileCallback]);\n\n /**\n * This function formats and adds files to fileItems\n */\n const handleAddFiles = useCallback(\n (filesToAdd: File[]) => {\n const newFileItems: InternalFileItem[] = [];\n\n filesToAdd.forEach((file) => {\n if (file && !filterDuplicateFile({ files: fileItems, newFile: file })) {\n newFileItems.push({\n id: uuidv4(),\n file,\n state: 'none',\n });\n }\n });\n\n let tmp = newFileItems;\n\n if (maxFiles) {\n tmp = newFileItems.slice(0, maxFiles - (fileItems.length + filesToAdd.length - 1));\n }\n\n setFileItems((prevState) => [...prevState, ...tmp]);\n },\n [fileItems, maxFiles],\n );\n\n /**\n * This function adds external files to fileItems\n */\n useEffect(() => {\n if (files) {\n const newFileItems: InternalFileItem[] = [];\n\n files.forEach((file) => {\n newFileItems.push({\n id: file.id ?? uuidv4(),\n uploadedFile: file.file,\n file: undefined,\n state: 'uploaded',\n previewUrl: undefined,\n });\n });\n\n setFileItems((prevState) => {\n const updatedItems = prevState.map((prevItem) => {\n const newItem = newFileItems.find(\n (item) =>\n item.uploadedFile &&\n item.uploadedFile.url ===\n (prevItem.uploadedFile && prevItem.uploadedFile.url),\n );\n return newItem || prevItem;\n });\n\n return updatedItems.concat(\n newFileItems.filter(\n (newItem) =>\n !prevState.some(\n (prevItem) =>\n prevItem.uploadedFile &&\n newItem.uploadedFile &&\n prevItem.uploadedFile.url === newItem.uploadedFile.url,\n ),\n ),\n );\n });\n }\n }, [files]);\n\n /**\n * This function deletes a selected file from the file list\n */\n const handleDeleteFile = useCallback(\n (id?: string) => {\n let fileToDelete: FileItem | undefined;\n\n const filteredFiles = fileItems.filter((file) => {\n const fileId = file.id;\n\n if (fileId === id && file.uploadedFile) {\n fileToDelete = { file: file.uploadedFile, id };\n }\n\n return fileId !== id;\n });\n\n setFileItems(filteredFiles);\n\n if (!fileToDelete || typeof onRemove !== 'function') {\n return;\n }\n\n onRemove(fileToDelete);\n },\n [fileItems, onRemove],\n );\n\n /**\n * This function handles the drag and drop\n */\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n if (!allowDragAndDrop) {\n return;\n }\n\n e.preventDefault();\n const draggedFiles = Array.from(e.dataTransfer.files);\n\n handleAddFiles(draggedFiles);\n },\n [allowDragAndDrop, handleAddFiles],\n );\n\n /**\n * Opens the files in a slideShow\n */\n const openFiles = useCallback(\n (file: InternalFileItem) => {\n const startIndex = fileItems.findIndex((item) => item.id === file.id);\n\n const items: OpenMediaItem[] = fileItems.map((item) => ({\n url: item.uploadedFile?.url.replace('_0.mp4', '.mp4') ?? '',\n mediaType:\n item.uploadedFile && 'thumbnailUrl' in item.uploadedFile\n ? MediaType.VIDEO\n : MediaType.IMAGE,\n }));\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n void openMedia({ items, startIndex });\n },\n [fileItems],\n );\n\n /**\n * Returns the ratio of the single file\n */\n const ratio = useMemo(() => {\n switch (fileItems.length) {\n case 0:\n return 0;\n case 1:\n return Math.max(fileItems[0]?.uploadedFile?.ratio ?? 1, 1);\n case 2:\n return 2;\n case 3:\n return 3;\n default:\n return 1;\n }\n }, [fileItems]);\n\n const galleryContent = useMemo(() => {\n const combinedFilesLength = fileItems.length;\n\n if (isEditMode) {\n const items = fileItems.map((file) => (\n <GalleryItem\n key={file.id}\n fileItem={file}\n isEditMode\n onClick={openFiles}\n handleDeleteFile={handleDeleteFile}\n />\n ));\n\n if (maxFiles && maxFiles <= combinedFilesLength) {\n return items;\n }\n\n items.push(<AddFile key=\"add_file\" onAdd={handleAddFiles} />);\n\n return items;\n }\n\n const shortedFiles = fileItems.slice(0, 4);\n\n return shortedFiles.map((file, index) => {\n let imageRatio = 1;\n\n if (viewMode === GalleryViewMode.GRID) {\n if (combinedFilesLength === 1) {\n imageRatio = fileItems[0]?.uploadedFile?.ratio ?? 1;\n } else if (combinedFilesLength === 2 && (index === 0 || index === 1)) {\n imageRatio = 0.5;\n } else if (\n (index === 0 && combinedFilesLength > 2) ||\n (combinedFilesLength === 3 && (index === 1 || index === 2))\n ) {\n imageRatio = 1.5;\n }\n }\n\n return (\n <GalleryItem\n key={file.id}\n fileItem={file}\n isEditMode={false}\n handleDeleteFile={handleDeleteFile}\n onClick={openFiles}\n ratio={imageRatio}\n remainingItemsLength={\n combinedFilesLength > 4 && index === 3 ? combinedFilesLength : undefined\n }\n />\n );\n });\n }, [fileItems, isEditMode, maxFiles, handleAddFiles, openFiles, handleDeleteFile, viewMode]);\n\n return useMemo(\n () => (\n <StyledGallery>\n {isEditMode ? (\n <StyledGalleryEditModeWrapper\n $fileMinWidth={fileMinWidth}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => void handleDrop(e)}\n >\n {galleryContent}\n </StyledGalleryEditModeWrapper>\n ) : (\n <StyledGalleryItemWrapper\n $ratio={ratio}\n $uploadedFileLength={fileItems.length}\n $viewMode={viewMode}\n >\n {galleryContent}\n </StyledGalleryItemWrapper>\n )}\n </StyledGallery>\n ),\n [isEditMode, fileMinWidth, galleryContent, ratio, fileItems.length, viewMode, handleDrop],\n );\n};\n\nGallery.displayName = 'Gallery';\n\nexport default Gallery;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import { GalleryViewMode } from '../types/gallery';
|
|
3
|
+
export const StyledGallery = styled.div`
|
|
4
|
+
width: 100%;
|
|
5
|
+
`;
|
|
6
|
+
export const StyledGalleryItemWrapper = styled.div`
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: 5px;
|
|
9
|
+
|
|
10
|
+
${({
|
|
11
|
+
$viewMode,
|
|
12
|
+
$uploadedFileLength
|
|
13
|
+
}) => {
|
|
14
|
+
if ($viewMode === GalleryViewMode.GRID) {
|
|
15
|
+
return css`
|
|
16
|
+
> div:first-child {
|
|
17
|
+
grid-column: 1 / -1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
${() => {
|
|
21
|
+
switch ($uploadedFileLength) {
|
|
22
|
+
case 1:
|
|
23
|
+
return css`
|
|
24
|
+
grid-template-columns: 1fr;
|
|
25
|
+
`;
|
|
26
|
+
case 2:
|
|
27
|
+
return css`
|
|
28
|
+
grid-template-columns: repeat(2, 1fr);
|
|
29
|
+
> div:first-child {
|
|
30
|
+
grid-column: span 1;
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
case 3:
|
|
34
|
+
return css`
|
|
35
|
+
grid-template-columns: repeat(2, 1fr);
|
|
36
|
+
> div:first-child {
|
|
37
|
+
grid-column: span 2;
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
default:
|
|
41
|
+
return css`
|
|
42
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
43
|
+
> div:not(:first-child) {
|
|
44
|
+
grid-column: span 1;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
}}
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
51
|
+
switch ($uploadedFileLength) {
|
|
52
|
+
case 1:
|
|
53
|
+
return css`
|
|
54
|
+
grid-template-columns: 1fr;
|
|
55
|
+
`;
|
|
56
|
+
case 2:
|
|
57
|
+
return css`
|
|
58
|
+
grid-template-columns: repeat(2, 1fr);
|
|
59
|
+
`;
|
|
60
|
+
case 3:
|
|
61
|
+
return css`
|
|
62
|
+
grid-template-columns: repeat(3, 1fr);
|
|
63
|
+
`;
|
|
64
|
+
default:
|
|
65
|
+
return css`
|
|
66
|
+
grid-template-columns: repeat(2, 1fr);
|
|
67
|
+
> div:nth-child(-n + 2) {
|
|
68
|
+
grid-row: 1;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
}}
|
|
73
|
+
|
|
74
|
+
aspect-ratio: ${({
|
|
75
|
+
$ratio
|
|
76
|
+
}) => $ratio};
|
|
77
|
+
`;
|
|
78
|
+
export const StyledGalleryEditModeWrapper = styled.div`
|
|
79
|
+
display: grid;
|
|
80
|
+
grid-template-columns: ${({
|
|
81
|
+
$fileMinWidth
|
|
82
|
+
}) => `repeat(auto-fill, minmax(${$fileMinWidth}px, 1fr))`};
|
|
83
|
+
grid-auto-rows: 1fr;
|
|
84
|
+
gap: 6px;
|
|
85
|
+
`;
|
|
86
|
+
//# sourceMappingURL=Gallery.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gallery.styles.js","names":["styled","css","GalleryViewMode","StyledGallery","div","StyledGalleryItemWrapper","$viewMode","$uploadedFileLength","GRID","$ratio","StyledGalleryEditModeWrapper","$fileMinWidth"],"sources":["../../../src/components/Gallery.styles.ts"],"sourcesContent":["import styled, { css } from 'styled-components';\nimport { GalleryViewMode } from '../types/gallery';\n\nexport const StyledGallery = styled.div`\n width: 100%;\n`;\n\nexport const StyledGalleryItemWrapper = styled.div<{\n $uploadedFileLength: number;\n $ratio: number;\n $viewMode: GalleryViewMode;\n}>`\n display: grid;\n gap: 5px;\n\n ${({ $viewMode, $uploadedFileLength }) => {\n if ($viewMode === GalleryViewMode.GRID) {\n return css`\n > div:first-child {\n grid-column: 1 / -1;\n }\n\n ${() => {\n switch ($uploadedFileLength) {\n case 1:\n return css`\n grid-template-columns: 1fr;\n `;\n case 2:\n return css`\n grid-template-columns: repeat(2, 1fr);\n > div:first-child {\n grid-column: span 1;\n }\n `;\n case 3:\n return css`\n grid-template-columns: repeat(2, 1fr);\n > div:first-child {\n grid-column: span 2;\n }\n `;\n default:\n return css`\n grid-template-columns: repeat(3, minmax(0, 1fr));\n > div:not(:first-child) {\n grid-column: span 1;\n }\n `;\n }\n }}\n `;\n }\n\n switch ($uploadedFileLength) {\n case 1:\n return css`\n grid-template-columns: 1fr;\n `;\n case 2:\n return css`\n grid-template-columns: repeat(2, 1fr);\n `;\n case 3:\n return css`\n grid-template-columns: repeat(3, 1fr);\n `;\n default:\n return css`\n grid-template-columns: repeat(2, 1fr);\n > div:nth-child(-n + 2) {\n grid-row: 1;\n }\n `;\n }\n }}\n\n aspect-ratio: ${({ $ratio }) => $ratio};\n`;\n\nexport const StyledGalleryEditModeWrapper = styled.div<{\n $fileMinWidth: number;\n}>`\n display: grid;\n grid-template-columns: ${({ $fileMinWidth }) =>\n `repeat(auto-fill, minmax(${$fileMinWidth}px, 1fr))`};\n grid-auto-rows: 1fr;\n gap: 6px;\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,IAAIC,GAAG,QAAQ,mBAAmB;AAC/C,SAASC,eAAe,QAAQ,kBAAkB;AAElD,OAAO,MAAMC,aAAa,GAAGH,MAAM,CAACI,GAAG;AACvC;AACA,CAAC;AAED,OAAO,MAAMC,wBAAwB,GAAGL,MAAM,CAACI,GAI7C;AACF;AACA;AACA;AACA,MAAM,CAAC;EAAEE,SAAS;EAAEC;AAAoB,CAAC,KAAK;EACtC,IAAID,SAAS,KAAKJ,eAAe,CAACM,IAAI,EAAE;IACpC,OAAOP,GAAG;AACtB;AACA;AACA;AACA;AACA,kBAAkB,MAAM;MACJ,QAAQM,mBAAmB;QACvB,KAAK,CAAC;UACF,OAAON,GAAG;AACtC;AACA,6BAA6B;QACL,KAAK,CAAC;UACF,OAAOA,GAAG;AACtC;AACA;AACA;AACA;AACA,6BAA6B;QACL,KAAK,CAAC;UACF,OAAOA,GAAG;AACtC;AACA;AACA;AACA;AACA,6BAA6B;QACL;UACI,OAAOA,GAAG;AACtC;AACA;AACA;AACA;AACA,6BAA6B;MACT;IACJ,CAAC;AACjB,aAAa;EACL;EAEA,QAAQM,mBAAmB;IACvB,KAAK,CAAC;MACF,OAAON,GAAG;AAC1B;AACA,iBAAiB;IACL,KAAK,CAAC;MACF,OAAOA,GAAG;AAC1B;AACA,iBAAiB;IACL,KAAK,CAAC;MACF,OAAOA,GAAG;AAC1B;AACA,iBAAiB;IACL;MACI,OAAOA,GAAG;AAC1B;AACA;AACA;AACA;AACA,iBAAiB;EACT;AACJ,CAAC;AACL;AACA,oBAAoB,CAAC;EAAEQ;AAAO,CAAC,KAAKA,MAAM;AAC1C,CAAC;AAED,OAAO,MAAMC,4BAA4B,GAAGV,MAAM,CAACI,GAEjD;AACF;AACA,6BAA6B,CAAC;EAAEO;AAAc,CAAC,KACvC,4BAA4BA,aAAa,WAAW;AAC5D;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Icon, selectFiles } from '@chayns-components/core';
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
3
|
+
import { StyledAddFile, StyledAddFIleIconWrapper } from './AddFile.styles';
|
|
4
|
+
const AddFile = ({
|
|
5
|
+
onAdd
|
|
6
|
+
}) => {
|
|
7
|
+
const openSelectDialog = useCallback(async () => {
|
|
8
|
+
const files = await selectFiles({
|
|
9
|
+
multiple: true,
|
|
10
|
+
type: 'image/*, video/*'
|
|
11
|
+
});
|
|
12
|
+
onAdd(files);
|
|
13
|
+
}, [onAdd]);
|
|
14
|
+
return /*#__PURE__*/React.createElement(StyledAddFile, {
|
|
15
|
+
key: "addButton"
|
|
16
|
+
}, /*#__PURE__*/React.createElement(StyledAddFIleIconWrapper, {
|
|
17
|
+
onClick: () => void openSelectDialog()
|
|
18
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
19
|
+
size: 40,
|
|
20
|
+
icons: ['fa fa-plus']
|
|
21
|
+
})));
|
|
22
|
+
};
|
|
23
|
+
AddFile.displayName = 'AddFile';
|
|
24
|
+
export default AddFile;
|
|
25
|
+
//# sourceMappingURL=AddFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddFile.js","names":["Icon","selectFiles","React","useCallback","StyledAddFile","StyledAddFIleIconWrapper","AddFile","onAdd","openSelectDialog","files","multiple","type","createElement","key","onClick","size","icons","displayName"],"sources":["../../../../src/components/add-file/AddFile.tsx"],"sourcesContent":["import { Icon, selectFiles } from '@chayns-components/core';\nimport React, { FC, useCallback } from 'react';\nimport { StyledAddFile, StyledAddFIleIconWrapper } from './AddFile.styles';\n\nexport type AddFileProps = {\n /**\n * Function to be executed when files are added\n */\n onAdd: (files: File[]) => void;\n};\n\nconst AddFile: FC<AddFileProps> = ({ onAdd }) => {\n const openSelectDialog = useCallback(async () => {\n const files = await selectFiles({\n multiple: true,\n type: 'image/*, video/*',\n });\n\n onAdd(files);\n }, [onAdd]);\n\n return (\n <StyledAddFile key=\"addButton\">\n <StyledAddFIleIconWrapper onClick={() => void openSelectDialog()}>\n <Icon size={40} icons={['fa fa-plus']} />\n </StyledAddFIleIconWrapper>\n </StyledAddFile>\n );\n};\n\nAddFile.displayName = 'AddFile';\n\nexport default AddFile;\n"],"mappings":"AAAA,SAASA,IAAI,EAAEC,WAAW,QAAQ,yBAAyB;AAC3D,OAAOC,KAAK,IAAQC,WAAW,QAAQ,OAAO;AAC9C,SAASC,aAAa,EAAEC,wBAAwB,QAAQ,kBAAkB;AAS1E,MAAMC,OAAyB,GAAGA,CAAC;EAAEC;AAAM,CAAC,KAAK;EAC7C,MAAMC,gBAAgB,GAAGL,WAAW,CAAC,YAAY;IAC7C,MAAMM,KAAK,GAAG,MAAMR,WAAW,CAAC;MAC5BS,QAAQ,EAAE,IAAI;MACdC,IAAI,EAAE;IACV,CAAC,CAAC;IAEFJ,KAAK,CAACE,KAAK,CAAC;EAChB,CAAC,EAAE,CAACF,KAAK,CAAC,CAAC;EAEX,oBACIL,KAAA,CAAAU,aAAA,CAACR,aAAa;IAACS,GAAG,EAAC;EAAW,gBAC1BX,KAAA,CAAAU,aAAA,CAACP,wBAAwB;IAACS,OAAO,EAAEA,CAAA,KAAM,KAAKN,gBAAgB,CAAC;EAAE,gBAC7DN,KAAA,CAAAU,aAAA,CAACZ,IAAI;IAACe,IAAI,EAAE,EAAG;IAACC,KAAK,EAAE,CAAC,YAAY;EAAE,CAAE,CAClB,CACf,CAAC;AAExB,CAAC;AAEDV,OAAO,CAACW,WAAW,GAAG,SAAS;AAE/B,eAAeX,OAAO","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
export const StyledAddFile = styled.div`
|
|
3
|
+
position: relative;
|
|
4
|
+
`;
|
|
5
|
+
export const StyledAddFIleIconWrapper = styled.button`
|
|
6
|
+
background-color: ${({
|
|
7
|
+
theme
|
|
8
|
+
}) => theme['101']};
|
|
9
|
+
box-shadow: 0 0 0 1px
|
|
10
|
+
rgba(${({
|
|
11
|
+
theme
|
|
12
|
+
}) => theme['009-rgb']}, 0.08) inset;
|
|
13
|
+
width: 100%;
|
|
14
|
+
aspect-ratio: 1 / 1;
|
|
15
|
+
`;
|
|
16
|
+
//# sourceMappingURL=AddFile.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddFile.styles.js","names":["styled","StyledAddFile","div","StyledAddFIleIconWrapper","button","theme"],"sources":["../../../../src/components/add-file/AddFile.styles.ts"],"sourcesContent":["import type { WithTheme } from '@chayns-components/core';\nimport styled from 'styled-components';\n\nexport const StyledAddFile = styled.div`\n position: relative;\n`;\n\ntype StyledAddFIleIconWrapperProps = WithTheme<unknown>;\n\nexport const StyledAddFIleIconWrapper = styled.button<StyledAddFIleIconWrapperProps>`\n background-color: ${({ theme }: StyledAddFIleIconWrapperProps) => theme['101']};\n box-shadow: 0 0 0 1px\n rgba(${({ theme }: StyledAddFIleIconWrapperProps) => theme['009-rgb']}, 0.08) inset;\n width: 100%;\n aspect-ratio: 1 / 1;\n`;\n"],"mappings":"AACA,OAAOA,MAAM,MAAM,mBAAmB;AAEtC,OAAO,MAAMC,aAAa,GAAGD,MAAM,CAACE,GAAG;AACvC;AACA,CAAC;AAID,OAAO,MAAMC,wBAAwB,GAAGH,MAAM,CAACI,MAAqC;AACpF,wBAAwB,CAAC;EAAEC;AAAqC,CAAC,KAAKA,KAAK,CAAC,KAAK,CAAC;AAClF;AACA,eAAe,CAAC;EAAEA;AAAqC,CAAC,KAAKA,KAAK,CAAC,SAAS,CAAC;AAC7E;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Icon } from '@chayns-components/core';
|
|
2
|
+
import { AnimatePresence } from 'motion/react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
|
+
import { StyledGalleryItem, StyledGalleryItemDeleteButton, StyledGalleryItemMoreItemsIndicator } from './GalleryItem.styles';
|
|
5
|
+
import MediaItem from './media-item/MediaItem';
|
|
6
|
+
import PreviewItem from './preview-item/PreviewItem';
|
|
7
|
+
const GalleryItem = ({
|
|
8
|
+
fileItem,
|
|
9
|
+
handleDeleteFile,
|
|
10
|
+
isEditMode,
|
|
11
|
+
ratio = 1,
|
|
12
|
+
remainingItemsLength,
|
|
13
|
+
onClick
|
|
14
|
+
}) => useMemo(() => /*#__PURE__*/React.createElement(StyledGalleryItem, null, isEditMode && /*#__PURE__*/React.createElement(StyledGalleryItemDeleteButton, {
|
|
15
|
+
onClick: () => handleDeleteFile(fileItem.id)
|
|
16
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
17
|
+
size: 20,
|
|
18
|
+
icons: ['ts-wrong']
|
|
19
|
+
})), !fileItem.state || fileItem.state === 'none' || !fileItem.previewUrl && !fileItem.uploadedFile ? null : /*#__PURE__*/React.createElement(AnimatePresence, {
|
|
20
|
+
initial: false
|
|
21
|
+
}, fileItem.state === 'uploading' ? /*#__PURE__*/React.createElement(PreviewItem, {
|
|
22
|
+
ratio: ratio,
|
|
23
|
+
key: `uploading_${fileItem.id ?? ''}`,
|
|
24
|
+
fileItem: fileItem
|
|
25
|
+
}) : /*#__PURE__*/React.createElement(MediaItem, {
|
|
26
|
+
key: `uploaded_${fileItem.id ?? ''}`,
|
|
27
|
+
fileItem: fileItem,
|
|
28
|
+
isEditMode: isEditMode,
|
|
29
|
+
ratio: ratio,
|
|
30
|
+
openSelectedFile: onClick
|
|
31
|
+
})), remainingItemsLength && /*#__PURE__*/React.createElement(StyledGalleryItemMoreItemsIndicator, {
|
|
32
|
+
onClick: () => onClick(fileItem)
|
|
33
|
+
}, /*#__PURE__*/React.createElement("p", null, `+ ${remainingItemsLength - 3}`))), [fileItem, handleDeleteFile, isEditMode, onClick, ratio, remainingItemsLength]);
|
|
34
|
+
GalleryItem.displayName = 'GalleryItem';
|
|
35
|
+
export default GalleryItem;
|
|
36
|
+
//# sourceMappingURL=GalleryItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GalleryItem.js","names":["Icon","AnimatePresence","React","useMemo","StyledGalleryItem","StyledGalleryItemDeleteButton","StyledGalleryItemMoreItemsIndicator","MediaItem","PreviewItem","GalleryItem","fileItem","handleDeleteFile","isEditMode","ratio","remainingItemsLength","onClick","createElement","id","size","icons","state","previewUrl","uploadedFile","initial","key","openSelectedFile","displayName"],"sources":["../../../../src/components/gallery-item/GalleryItem.tsx"],"sourcesContent":["import { Icon, type InternalFileItem } from '@chayns-components/core';\nimport { AnimatePresence } from 'motion/react';\nimport React, { FC, useMemo } from 'react';\nimport {\n StyledGalleryItem,\n StyledGalleryItemDeleteButton,\n StyledGalleryItemMoreItemsIndicator,\n} from './GalleryItem.styles';\nimport MediaItem from './media-item/MediaItem';\nimport PreviewItem from './preview-item/PreviewItem';\n\nexport type GalleryItemProps = {\n /**\n * Images and videos which should be displayed\n */\n fileItem: InternalFileItem;\n /**\n * Whether images and videos can be edited\n */\n isEditMode: boolean;\n /**\n * Function to be executed when a file is deleted\n */\n handleDeleteFile: (id?: string) => void;\n /**\n * The ratio of the image\n */\n ratio?: number;\n /**\n * Length of the uploaded files\n */\n remainingItemsLength?: number;\n /**\n * Function to be executed if a file should be opened\n */\n onClick: (file: InternalFileItem) => void;\n};\n\nconst GalleryItem: FC<GalleryItemProps> = ({\n fileItem,\n handleDeleteFile,\n isEditMode,\n ratio = 1,\n remainingItemsLength,\n onClick,\n}) =>\n useMemo(\n () => (\n <StyledGalleryItem>\n {isEditMode && (\n <StyledGalleryItemDeleteButton onClick={() => handleDeleteFile(fileItem.id)}>\n <Icon size={20} icons={['ts-wrong']} />\n </StyledGalleryItemDeleteButton>\n )}\n {!fileItem.state ||\n fileItem.state === 'none' ||\n (!fileItem.previewUrl && !fileItem.uploadedFile) ? null : (\n <AnimatePresence initial={false}>\n {fileItem.state === 'uploading' ? (\n <PreviewItem\n ratio={ratio}\n key={`uploading_${fileItem.id ?? ''}`}\n fileItem={fileItem}\n />\n ) : (\n <MediaItem\n key={`uploaded_${fileItem.id ?? ''}`}\n fileItem={fileItem}\n isEditMode={isEditMode}\n ratio={ratio}\n openSelectedFile={onClick}\n />\n )}\n </AnimatePresence>\n )}\n {remainingItemsLength && (\n <StyledGalleryItemMoreItemsIndicator onClick={() => onClick(fileItem)}>\n <p>{`+ ${remainingItemsLength - 3}`}</p>\n </StyledGalleryItemMoreItemsIndicator>\n )}\n </StyledGalleryItem>\n ),\n [fileItem, handleDeleteFile, isEditMode, onClick, ratio, remainingItemsLength],\n );\n\nGalleryItem.displayName = 'GalleryItem';\n\nexport default GalleryItem;\n"],"mappings":"AAAA,SAASA,IAAI,QAA+B,yBAAyB;AACrE,SAASC,eAAe,QAAQ,cAAc;AAC9C,OAAOC,KAAK,IAAQC,OAAO,QAAQ,OAAO;AAC1C,SACIC,iBAAiB,EACjBC,6BAA6B,EAC7BC,mCAAmC,QAChC,sBAAsB;AAC7B,OAAOC,SAAS,MAAM,wBAAwB;AAC9C,OAAOC,WAAW,MAAM,4BAA4B;AA6BpD,MAAMC,WAAiC,GAAGA,CAAC;EACvCC,QAAQ;EACRC,gBAAgB;EAChBC,UAAU;EACVC,KAAK,GAAG,CAAC;EACTC,oBAAoB;EACpBC;AACJ,CAAC,KACGZ,OAAO,CACH,mBACID,KAAA,CAAAc,aAAA,CAACZ,iBAAiB,QACbQ,UAAU,iBACPV,KAAA,CAAAc,aAAA,CAACX,6BAA6B;EAACU,OAAO,EAAEA,CAAA,KAAMJ,gBAAgB,CAACD,QAAQ,CAACO,EAAE;AAAE,gBACxEf,KAAA,CAAAc,aAAA,CAAChB,IAAI;EAACkB,IAAI,EAAE,EAAG;EAACC,KAAK,EAAE,CAAC,UAAU;AAAE,CAAE,CACX,CAClC,EACA,CAACT,QAAQ,CAACU,KAAK,IAChBV,QAAQ,CAACU,KAAK,KAAK,MAAM,IACxB,CAACV,QAAQ,CAACW,UAAU,IAAI,CAACX,QAAQ,CAACY,YAAa,GAAG,IAAI,gBACnDpB,KAAA,CAAAc,aAAA,CAACf,eAAe;EAACsB,OAAO,EAAE;AAAM,GAC3Bb,QAAQ,CAACU,KAAK,KAAK,WAAW,gBAC3BlB,KAAA,CAAAc,aAAA,CAACR,WAAW;EACRK,KAAK,EAAEA,KAAM;EACbW,GAAG,EAAE,aAAad,QAAQ,CAACO,EAAE,IAAI,EAAE,EAAG;EACtCP,QAAQ,EAAEA;AAAS,CACtB,CAAC,gBAEFR,KAAA,CAAAc,aAAA,CAACT,SAAS;EACNiB,GAAG,EAAE,YAAYd,QAAQ,CAACO,EAAE,IAAI,EAAE,EAAG;EACrCP,QAAQ,EAAEA,QAAS;EACnBE,UAAU,EAAEA,UAAW;EACvBC,KAAK,EAAEA,KAAM;EACbY,gBAAgB,EAAEV;AAAQ,CAC7B,CAEQ,CACpB,EACAD,oBAAoB,iBACjBZ,KAAA,CAAAc,aAAA,CAACV,mCAAmC;EAACS,OAAO,EAAEA,CAAA,KAAMA,OAAO,CAACL,QAAQ;AAAE,gBAClER,KAAA,CAAAc,aAAA,YAAI,KAAKF,oBAAoB,GAAG,CAAC,EAAM,CACN,CAE1B,CACtB,EACD,CAACJ,QAAQ,EAAEC,gBAAgB,EAAEC,UAAU,EAAEG,OAAO,EAAEF,KAAK,EAAEC,oBAAoB,CACjF,CAAC;AAELL,WAAW,CAACiB,WAAW,GAAG,aAAa;AAEvC,eAAejB,WAAW","ignoreList":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
export const StyledGalleryItem = styled.div`
|
|
3
|
+
display: flex;
|
|
4
|
+
position: relative;
|
|
5
|
+
height: 100%;
|
|
6
|
+
width: 100%;
|
|
7
|
+
`;
|
|
8
|
+
export const StyledGalleryItemDeleteButton = styled.button`
|
|
9
|
+
background-color: rgba(
|
|
10
|
+
${({
|
|
11
|
+
theme
|
|
12
|
+
}) => theme['000-rgb']},
|
|
13
|
+
0.75
|
|
14
|
+
);
|
|
15
|
+
box-shadow: 0 0 0 1px
|
|
16
|
+
rgba(${({
|
|
17
|
+
theme
|
|
18
|
+
}) => theme['009-rgb']}, 0.08) inset;
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0;
|
|
21
|
+
right: 0;
|
|
22
|
+
z-index: 2;
|
|
23
|
+
height: 30px;
|
|
24
|
+
width: 30px;
|
|
25
|
+
display: flex;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
align-items: center;
|
|
28
|
+
`;
|
|
29
|
+
export const StyledGalleryItemMoreItemsIndicator = styled.div`
|
|
30
|
+
position: absolute;
|
|
31
|
+
z-index: 2;
|
|
32
|
+
height: 100%;
|
|
33
|
+
width: 100%;
|
|
34
|
+
display: flex;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
align-items: center;
|
|
37
|
+
backdrop-filter: brightness(40%);
|
|
38
|
+
|
|
39
|
+
p {
|
|
40
|
+
font-size: 40px;
|
|
41
|
+
color: white;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
//# sourceMappingURL=GalleryItem.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GalleryItem.styles.js","names":["styled","StyledGalleryItem","div","StyledGalleryItemDeleteButton","button","theme","StyledGalleryItemMoreItemsIndicator"],"sources":["../../../../src/components/gallery-item/GalleryItem.styles.ts"],"sourcesContent":["import type { WithTheme } from '@chayns-components/core';\nimport styled from 'styled-components';\n\nexport const StyledGalleryItem = styled.div`\n display: flex;\n position: relative;\n height: 100%;\n width: 100%;\n`;\n\ntype StyledGalleryItemDeleteButtonProps = WithTheme<unknown>;\n\nexport const StyledGalleryItemDeleteButton = styled.button<StyledGalleryItemDeleteButtonProps>`\n background-color: rgba(\n ${({ theme }: StyledGalleryItemDeleteButtonProps) => theme['000-rgb']},\n 0.75\n );\n box-shadow: 0 0 0 1px\n rgba(${({ theme }: StyledGalleryItemDeleteButtonProps) => theme['009-rgb']}, 0.08) inset;\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n height: 30px;\n width: 30px;\n display: flex;\n justify-content: center;\n align-items: center;\n`;\n\nexport const StyledGalleryItemMoreItemsIndicator = styled.div`\n position: absolute;\n z-index: 2;\n height: 100%;\n width: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n backdrop-filter: brightness(40%);\n\n p {\n font-size: 40px;\n color: white;\n }\n`;\n"],"mappings":"AACA,OAAOA,MAAM,MAAM,mBAAmB;AAEtC,OAAO,MAAMC,iBAAiB,GAAGD,MAAM,CAACE,GAAG;AAC3C;AACA;AACA;AACA;AACA,CAAC;AAID,OAAO,MAAMC,6BAA6B,GAAGH,MAAM,CAACI,MAA0C;AAC9F;AACA,UAAU,CAAC;EAAEC;AAA0C,CAAC,KAAKA,KAAK,CAAC,SAAS,CAAC;AAC7E;AACA;AACA;AACA,eAAe,CAAC;EAAEA;AAA0C,CAAC,KAAKA,KAAK,CAAC,SAAS,CAAC;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAMC,mCAAmC,GAAGN,MAAM,CAACE,GAAG;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Icon } from '@chayns-components/core';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { StyledMediaItemImage, StyledMediaItemImageWrapper, StyledMediaItemPlayIcon, StyledMediaItemVideo, StyledMediaItemVideoWrapper, StyledMotionMediaItem } from './MediaItem.styles';
|
|
4
|
+
const MediaItem = ({
|
|
5
|
+
fileItem,
|
|
6
|
+
isEditMode,
|
|
7
|
+
openSelectedFile,
|
|
8
|
+
ratio
|
|
9
|
+
}) => /*#__PURE__*/React.createElement(StyledMotionMediaItem, {
|
|
10
|
+
animate: {
|
|
11
|
+
opacity: 1
|
|
12
|
+
},
|
|
13
|
+
initial: {
|
|
14
|
+
opacity: 0
|
|
15
|
+
},
|
|
16
|
+
exit: {
|
|
17
|
+
opacity: 0
|
|
18
|
+
},
|
|
19
|
+
transition: {
|
|
20
|
+
duration: 3.2
|
|
21
|
+
}
|
|
22
|
+
}, fileItem.uploadedFile && 'thumbnailUrl' in fileItem.uploadedFile ? /*#__PURE__*/React.createElement(StyledMediaItemVideoWrapper, {
|
|
23
|
+
onClick: () => openSelectedFile(fileItem),
|
|
24
|
+
$ratio: ratio
|
|
25
|
+
}, /*#__PURE__*/React.createElement(StyledMediaItemPlayIcon, null, /*#__PURE__*/React.createElement(Icon, {
|
|
26
|
+
size: isEditMode ? 30 : 50,
|
|
27
|
+
icons: ['fa fa-play']
|
|
28
|
+
})), /*#__PURE__*/React.createElement(StyledMediaItemVideo, {
|
|
29
|
+
poster: fileItem.uploadedFile.thumbnailUrl
|
|
30
|
+
}, /*#__PURE__*/React.createElement("source", {
|
|
31
|
+
src: fileItem.uploadedFile.url,
|
|
32
|
+
type: "video/mp4"
|
|
33
|
+
}))) : /*#__PURE__*/React.createElement(StyledMediaItemImageWrapper, {
|
|
34
|
+
onClick: () => openSelectedFile(fileItem),
|
|
35
|
+
$ratio: ratio
|
|
36
|
+
}, /*#__PURE__*/React.createElement(StyledMediaItemImage, {
|
|
37
|
+
draggable: false,
|
|
38
|
+
src: fileItem.uploadedFile?.url
|
|
39
|
+
})));
|
|
40
|
+
MediaItem.displayName = 'MediaItem';
|
|
41
|
+
export default MediaItem;
|
|
42
|
+
//# sourceMappingURL=MediaItem.js.map
|