@zextras/carbonio-ui-preview 0.1.1 → 0.1.4
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 +5 -5
- package/lib/index.d.ts +6 -0
- package/lib/index.js +28 -0
- package/lib/index.js.map +1 -0
- package/lib/preview/ContainerWithGap.d.ts +1 -0
- package/lib/preview/ContainerWithGap.js +23 -0
- package/lib/preview/ContainerWithGap.js.map +1 -0
- package/lib/preview/FocusWithin.d.ts +7 -0
- package/lib/preview/FocusWithin.js +87 -0
- package/lib/preview/FocusWithin.js.map +1 -0
- package/lib/preview/Header.d.ts +29 -0
- package/lib/preview/Header.js +44 -0
- package/lib/preview/Header.js.map +1 -0
- package/lib/preview/ImagePreview.d.ts +37 -0
- package/lib/preview/ImagePreview.js +99 -0
- package/lib/preview/ImagePreview.js.map +1 -0
- package/lib/preview/PdfPreview.d.ts +58 -0
- package/lib/preview/PdfPreview.js +204 -0
- package/lib/preview/PdfPreview.js.map +1 -0
- package/lib/preview/PreviewCriteriaAlternativeContent.d.ts +12 -0
- package/lib/preview/PreviewCriteriaAlternativeContent.js +73 -0
- package/lib/preview/PreviewCriteriaAlternativeContent.js.map +1 -0
- package/lib/preview/PreviewManager.d.ts +12 -0
- package/lib/preview/PreviewManager.js +102 -0
- package/lib/preview/PreviewManager.js.map +1 -0
- package/lib/preview/PreviewWrapper.d.ts +9 -0
- package/lib/preview/PreviewWrapper.js +42 -0
- package/lib/preview/PreviewWrapper.js.map +1 -0
- package/lib/utils.d.ts +3 -0
- package/{src/utils.ts → lib/utils.js} +3 -2
- package/lib/utils.js.map +1 -0
- package/lib-esm/index.d.ts +6 -0
- package/{src/index.ts → lib-esm/index.js} +1 -1
- package/lib-esm/index.js.map +1 -0
- package/lib-esm/preview/ContainerWithGap.d.ts +1 -0
- package/lib-esm/preview/ContainerWithGap.js +17 -0
- package/lib-esm/preview/ContainerWithGap.js.map +1 -0
- package/lib-esm/preview/FocusWithin.d.ts +7 -0
- package/lib-esm/preview/FocusWithin.js +59 -0
- package/lib-esm/preview/FocusWithin.js.map +1 -0
- package/lib-esm/preview/Header.d.ts +29 -0
- package/lib-esm/preview/Header.js +39 -0
- package/lib-esm/preview/Header.js.map +1 -0
- package/lib-esm/preview/ImagePreview.d.ts +37 -0
- package/lib-esm/preview/ImagePreview.js +70 -0
- package/lib-esm/preview/ImagePreview.js.map +1 -0
- package/lib-esm/preview/PdfPreview.d.ts +58 -0
- package/lib-esm/preview/PdfPreview.js +175 -0
- package/lib-esm/preview/PdfPreview.js.map +1 -0
- package/lib-esm/preview/PreviewCriteriaAlternativeContent.d.ts +12 -0
- package/lib-esm/preview/PreviewCriteriaAlternativeContent.js +43 -0
- package/lib-esm/preview/PreviewCriteriaAlternativeContent.js.map +1 -0
- package/lib-esm/preview/PreviewManager.d.ts +12 -0
- package/lib-esm/preview/PreviewManager.js +75 -0
- package/lib-esm/preview/PreviewManager.js.map +1 -0
- package/lib-esm/preview/PreviewWrapper.d.ts +9 -0
- package/lib-esm/preview/PreviewWrapper.js +36 -0
- package/lib-esm/preview/PreviewWrapper.js.map +1 -0
- package/lib-esm/utils.d.ts +3 -0
- package/{src/types/carbonio-design-system.d.ts → lib-esm/utils.js} +2 -2
- package/lib-esm/utils.js.map +1 -0
- package/package.json +22 -6
- package/src/preview/ContainerWithGap.tsx +0 -11
- package/src/preview/FocusWithin.tsx +0 -76
- package/src/preview/Header.tsx +0 -122
- package/src/preview/ImagePreview.tsx +0 -194
- package/src/preview/PdfPreview.tsx +0 -398
- package/src/preview/PreviewCriteriaAlternativeContent.tsx +0 -94
- package/src/preview/PreviewManager.tsx +0 -75
- package/src/preview/PreviewWrapper.tsx +0 -20
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
|
|
3
|
-
*
|
|
4
|
-
* SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
-
*/
|
|
6
|
-
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Container,
|
|
10
|
-
IconButton,
|
|
11
|
-
Portal,
|
|
12
|
-
Tooltip,
|
|
13
|
-
useCombinedRefs
|
|
14
|
-
} from '@zextras/carbonio-design-system';
|
|
15
|
-
import findIndex from 'lodash/findIndex';
|
|
16
|
-
import findLastIndex from 'lodash/findLastIndex';
|
|
17
|
-
import map from 'lodash/map';
|
|
18
|
-
import type { DocumentProps } from 'react-pdf';
|
|
19
|
-
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack';
|
|
20
|
-
import styled, { css, SimpleInterpolation } from 'styled-components';
|
|
21
|
-
|
|
22
|
-
import FocusWithin from './FocusWithin';
|
|
23
|
-
import Header, { HeaderProps } from './Header';
|
|
24
|
-
import { PreviewCriteriaAlternativeContent } from './PreviewCriteriaAlternativeContent';
|
|
25
|
-
|
|
26
|
-
const CustomIconButton = styled(IconButton)`
|
|
27
|
-
${({ disabled }): SimpleInterpolation =>
|
|
28
|
-
disabled &&
|
|
29
|
-
css`
|
|
30
|
-
background: rgba(204, 204, 204, 0.2);
|
|
31
|
-
& > svg {
|
|
32
|
-
background: unset;
|
|
33
|
-
}
|
|
34
|
-
`};
|
|
35
|
-
& > svg {
|
|
36
|
-
width: 20px;
|
|
37
|
-
height: 20px;
|
|
38
|
-
}
|
|
39
|
-
`;
|
|
40
|
-
|
|
41
|
-
const Overlay = styled.div`
|
|
42
|
-
height: 100vh;
|
|
43
|
-
max-height: 100vh;
|
|
44
|
-
width: 100%;
|
|
45
|
-
max-width: 100%;
|
|
46
|
-
position: fixed;
|
|
47
|
-
top: 0;
|
|
48
|
-
left: 0;
|
|
49
|
-
background-color: rgba(0, 0, 0, 0.8);
|
|
50
|
-
display: flex;
|
|
51
|
-
justify-content: center;
|
|
52
|
-
align-items: center;
|
|
53
|
-
z-index: 3;
|
|
54
|
-
`;
|
|
55
|
-
|
|
56
|
-
const MiddleContainer = styled(Container)`
|
|
57
|
-
flex-grow: 1;
|
|
58
|
-
`;
|
|
59
|
-
|
|
60
|
-
const ExternalContainer = styled.div`
|
|
61
|
-
height: 100vh;
|
|
62
|
-
max-height: 100vh;
|
|
63
|
-
width: 100vw;
|
|
64
|
-
max-width: 100vw;
|
|
65
|
-
display: flex;
|
|
66
|
-
flex-direction: column;
|
|
67
|
-
position: relative;
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
const Navigator = styled.div`
|
|
71
|
-
display: flex;
|
|
72
|
-
position: absolute;
|
|
73
|
-
z-index: 1;
|
|
74
|
-
bottom: 16px;
|
|
75
|
-
background-color: ${({ theme }): string => theme.palette.gray0.regular};
|
|
76
|
-
align-self: center;
|
|
77
|
-
border-radius: 4px;
|
|
78
|
-
gap: 8px;
|
|
79
|
-
padding: 8px 16px;
|
|
80
|
-
`;
|
|
81
|
-
|
|
82
|
-
const PreviewContainer = styled.div`
|
|
83
|
-
display: flex;
|
|
84
|
-
flex-direction: column;
|
|
85
|
-
flex-grow: 1;
|
|
86
|
-
// https://bhch.github.io/posts/2021/04/centring-flex-items-and-allowing-overflow-scroll/
|
|
87
|
-
//justify-content: center;
|
|
88
|
-
//align-items: center;
|
|
89
|
-
// justify-content and align-items conflict with overflow management
|
|
90
|
-
overflow: auto;
|
|
91
|
-
outline: none;
|
|
92
|
-
|
|
93
|
-
&::-webkit-scrollbar {
|
|
94
|
-
width: 7px;
|
|
95
|
-
height: 7px;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
&::-webkit-scrollbar-track {
|
|
99
|
-
background-color: transparent;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
&::-webkit-scrollbar-thumb {
|
|
103
|
-
background-color: ${({ theme }): string => theme.palette.gray3.regular};
|
|
104
|
-
border-radius: 4px;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
& > .react-pdf__Document {
|
|
108
|
-
//padding-right: 17px;
|
|
109
|
-
padding-bottom: 16px;
|
|
110
|
-
margin: auto;
|
|
111
|
-
display: flex;
|
|
112
|
-
gap: 16px;
|
|
113
|
-
flex-direction: column;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
& .react-pdf__message {
|
|
117
|
-
color: white;
|
|
118
|
-
}
|
|
119
|
-
`;
|
|
120
|
-
|
|
121
|
-
type PdfPreviewProps = Partial<HeaderProps> & {
|
|
122
|
-
/**
|
|
123
|
-
* HTML node where to insert the Portal's children.
|
|
124
|
-
* The default value is 'window.top.document'.
|
|
125
|
-
* */
|
|
126
|
-
container?: React.RefObject<HTMLElement>;
|
|
127
|
-
/** Flag to disable the Portal implementation */
|
|
128
|
-
disablePortal?: boolean;
|
|
129
|
-
/** Flag to show or hide Portal's content */
|
|
130
|
-
show: boolean;
|
|
131
|
-
/** preview img source */
|
|
132
|
-
src: string;
|
|
133
|
-
/** Callback to hide the preview */
|
|
134
|
-
onClose: (e: React.SyntheticEvent | KeyboardEvent) => void;
|
|
135
|
-
/** use fallback content if you don't want to view the pdf for some reason; content can be customizable with customContent */
|
|
136
|
-
useFallback?: boolean;
|
|
137
|
-
/** CustomContent */
|
|
138
|
-
customContent?: React.ReactElement;
|
|
139
|
-
/** Whether a text layer should be rendered */
|
|
140
|
-
renderTextLayer?: boolean;
|
|
141
|
-
/** Src that allow open in separate tab */
|
|
142
|
-
openSrc?: string;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const zoomStep = [800, 1000, 1200, 1400, 1600, 2000, 2400, 3200];
|
|
146
|
-
|
|
147
|
-
const PdfPreview = React.forwardRef<HTMLDivElement, PdfPreviewProps>(function PreviewFn(
|
|
148
|
-
{
|
|
149
|
-
src,
|
|
150
|
-
show,
|
|
151
|
-
container,
|
|
152
|
-
disablePortal,
|
|
153
|
-
extension = '',
|
|
154
|
-
filename = '',
|
|
155
|
-
size = '',
|
|
156
|
-
actions = [],
|
|
157
|
-
closeAction,
|
|
158
|
-
onClose,
|
|
159
|
-
useFallback = false,
|
|
160
|
-
customContent,
|
|
161
|
-
renderTextLayer = false,
|
|
162
|
-
openSrc
|
|
163
|
-
},
|
|
164
|
-
ref
|
|
165
|
-
) {
|
|
166
|
-
const previewRef: React.MutableRefObject<HTMLDivElement | null> = useCombinedRefs(ref);
|
|
167
|
-
|
|
168
|
-
const [numPages, setNumPages] = useState<number | null>(null);
|
|
169
|
-
|
|
170
|
-
const $closeAction = useMemo(() => {
|
|
171
|
-
if (closeAction) {
|
|
172
|
-
return {
|
|
173
|
-
onClick: onClose,
|
|
174
|
-
...closeAction
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
return closeAction;
|
|
178
|
-
}, [closeAction, onClose]);
|
|
179
|
-
|
|
180
|
-
const onOverlayClick = useCallback<React.ReactEventHandler>(
|
|
181
|
-
(event) => {
|
|
182
|
-
// TODO: stop propagation or not?
|
|
183
|
-
event.stopPropagation();
|
|
184
|
-
(useFallback || numPages) &&
|
|
185
|
-
previewRef.current &&
|
|
186
|
-
!event.isDefaultPrevented() &&
|
|
187
|
-
(previewRef.current === event.target ||
|
|
188
|
-
!previewRef.current.contains(event.target as Node)) &&
|
|
189
|
-
onClose(event);
|
|
190
|
-
},
|
|
191
|
-
[numPages, onClose, previewRef, useFallback]
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
const [currentZoom, setCurrentZoom] = useState(zoomStep[0]);
|
|
195
|
-
const [incrementable, setIncrementable] = useState(true);
|
|
196
|
-
const [decrementable, setDecrementable] = useState(false);
|
|
197
|
-
const [fitToWidthActive, setFitToWidthActive] = useState(false);
|
|
198
|
-
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
if (!show) {
|
|
201
|
-
setCurrentZoom(zoomStep[0]);
|
|
202
|
-
setIncrementable(true);
|
|
203
|
-
setDecrementable(false);
|
|
204
|
-
setFitToWidthActive(false);
|
|
205
|
-
}
|
|
206
|
-
}, [show]);
|
|
207
|
-
|
|
208
|
-
const increaseOfOneStep = useCallback<React.ReactEventHandler>(
|
|
209
|
-
(ev) => {
|
|
210
|
-
ev.stopPropagation();
|
|
211
|
-
if (incrementable) {
|
|
212
|
-
const targetIndex = findIndex(zoomStep, (step) => step > currentZoom);
|
|
213
|
-
if (targetIndex >= 0) {
|
|
214
|
-
setCurrentZoom(zoomStep[targetIndex]);
|
|
215
|
-
if (targetIndex === zoomStep.length - 1) {
|
|
216
|
-
setIncrementable(false);
|
|
217
|
-
}
|
|
218
|
-
if (targetIndex > 0) {
|
|
219
|
-
setDecrementable(true);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
setFitToWidthActive(false);
|
|
224
|
-
},
|
|
225
|
-
[currentZoom, incrementable]
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
const decreaseOfOneStep = useCallback<React.ReactEventHandler>(
|
|
229
|
-
(ev) => {
|
|
230
|
-
ev.stopPropagation();
|
|
231
|
-
if (decrementable) {
|
|
232
|
-
const targetIndex = findLastIndex(zoomStep, (step) => step < currentZoom);
|
|
233
|
-
if (targetIndex >= 0) {
|
|
234
|
-
setCurrentZoom(zoomStep[targetIndex]);
|
|
235
|
-
if (targetIndex === 0) {
|
|
236
|
-
setDecrementable(false);
|
|
237
|
-
}
|
|
238
|
-
if (targetIndex < zoomStep.length - 1) {
|
|
239
|
-
setIncrementable(true);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
setFitToWidthActive(false);
|
|
244
|
-
},
|
|
245
|
-
[currentZoom, decrementable]
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
const fitToWidth = useCallback(
|
|
249
|
-
(ev: Event) => {
|
|
250
|
-
ev.stopPropagation();
|
|
251
|
-
if (previewRef.current) {
|
|
252
|
-
setCurrentZoom(previewRef.current?.clientWidth);
|
|
253
|
-
setIncrementable(previewRef.current?.clientWidth < zoomStep[zoomStep.length - 1]);
|
|
254
|
-
setDecrementable(previewRef.current?.clientWidth > zoomStep[0]);
|
|
255
|
-
setFitToWidthActive(true);
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
[previewRef]
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
useEffect(() => {
|
|
262
|
-
if (show && fitToWidthActive) {
|
|
263
|
-
window.addEventListener('resize', fitToWidth);
|
|
264
|
-
}
|
|
265
|
-
return (): void => {
|
|
266
|
-
window.removeEventListener('resize', fitToWidth);
|
|
267
|
-
};
|
|
268
|
-
}, [fitToWidth, previewRef, show, fitToWidthActive]);
|
|
269
|
-
|
|
270
|
-
const resetWidth = useCallback<React.ReactEventHandler>((ev) => {
|
|
271
|
-
ev.stopPropagation();
|
|
272
|
-
setCurrentZoom(zoomStep[0]);
|
|
273
|
-
setIncrementable(true);
|
|
274
|
-
setDecrementable(false);
|
|
275
|
-
setFitToWidthActive(false);
|
|
276
|
-
}, []);
|
|
277
|
-
|
|
278
|
-
// could be useful for future implementations
|
|
279
|
-
// const onPageLoadSuccess = useCallback(({ originalHeight, originalWidth, width, height }) => {
|
|
280
|
-
// console.log(originalHeight, originalWidth, width, height);
|
|
281
|
-
// }, []);
|
|
282
|
-
|
|
283
|
-
const pageElements = useMemo(() => {
|
|
284
|
-
if (numPages) {
|
|
285
|
-
return map(new Array(numPages), (el, index) => (
|
|
286
|
-
<Page
|
|
287
|
-
key={`page_${index + 1}`}
|
|
288
|
-
pageNumber={index + 1}
|
|
289
|
-
// onLoadSuccess={index === 0 ? onPageLoadSuccess : undefined}
|
|
290
|
-
width={currentZoom}
|
|
291
|
-
renderTextLayer={renderTextLayer}
|
|
292
|
-
/>
|
|
293
|
-
));
|
|
294
|
-
}
|
|
295
|
-
return [];
|
|
296
|
-
}, [currentZoom, numPages, renderTextLayer]);
|
|
297
|
-
|
|
298
|
-
const onDocumentLoadSuccess = useCallback<NonNullable<DocumentProps['onLoadSuccess']>>((args) => {
|
|
299
|
-
setNumPages(args.numPages);
|
|
300
|
-
}, []);
|
|
301
|
-
|
|
302
|
-
const file = useMemo(() => ({ url: src }), [src]);
|
|
303
|
-
|
|
304
|
-
const $customContent = useMemo(() => {
|
|
305
|
-
if (useFallback) {
|
|
306
|
-
return (
|
|
307
|
-
customContent || <PreviewCriteriaAlternativeContent downloadSrc={src} openSrc={openSrc} />
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
return undefined;
|
|
311
|
-
}, [customContent, openSrc, src, useFallback]);
|
|
312
|
-
|
|
313
|
-
return (
|
|
314
|
-
<Portal show={show} disablePortal={disablePortal} container={container}>
|
|
315
|
-
<Overlay onClick={onOverlayClick}>
|
|
316
|
-
<FocusWithin>
|
|
317
|
-
<ExternalContainer>
|
|
318
|
-
{!$customContent && (
|
|
319
|
-
<Navigator onClick={(ev): void => ev.stopPropagation()}>
|
|
320
|
-
<Tooltip label={decrementable ? 'Zoom out' : 'Minimum zoom level reached'}>
|
|
321
|
-
<CustomIconButton
|
|
322
|
-
disabled={!decrementable}
|
|
323
|
-
icon="Minus"
|
|
324
|
-
size="small"
|
|
325
|
-
backgroundColor="gray0"
|
|
326
|
-
iconColor="gray6"
|
|
327
|
-
onClick={decreaseOfOneStep}
|
|
328
|
-
/>
|
|
329
|
-
</Tooltip>
|
|
330
|
-
<Tooltip label={fitToWidthActive ? 'Reset zoom' : 'Fit to width'}>
|
|
331
|
-
<CustomIconButton
|
|
332
|
-
icon={fitToWidthActive ? 'MinimizeOutline' : 'MaximizeOutline'}
|
|
333
|
-
size="small"
|
|
334
|
-
backgroundColor="gray0"
|
|
335
|
-
iconColor="gray6"
|
|
336
|
-
onClick={fitToWidthActive ? resetWidth : fitToWidth}
|
|
337
|
-
/>
|
|
338
|
-
</Tooltip>
|
|
339
|
-
<Tooltip label={incrementable ? 'Zoom in' : 'Maximum zoom level reached'}>
|
|
340
|
-
<CustomIconButton
|
|
341
|
-
icon="Plus"
|
|
342
|
-
size="small"
|
|
343
|
-
backgroundColor="gray0"
|
|
344
|
-
iconColor="gray6"
|
|
345
|
-
onClick={increaseOfOneStep}
|
|
346
|
-
disabled={!incrementable}
|
|
347
|
-
/>
|
|
348
|
-
</Tooltip>
|
|
349
|
-
</Navigator>
|
|
350
|
-
)}
|
|
351
|
-
<Header
|
|
352
|
-
actions={actions}
|
|
353
|
-
filename={filename}
|
|
354
|
-
extension={extension}
|
|
355
|
-
size={size}
|
|
356
|
-
closeAction={$closeAction}
|
|
357
|
-
/>
|
|
358
|
-
<MiddleContainer orientation="horizontal" crossAlignment="unset" minHeight={0}>
|
|
359
|
-
{/* TODO: uncomment when navigation between items will be implemented */}
|
|
360
|
-
{/* <Container width="fit"> */}
|
|
361
|
-
{/* <Padding left="small" right="small"> */}
|
|
362
|
-
{/* <IconButton */}
|
|
363
|
-
{/* icon="ArrowBackOutline" */}
|
|
364
|
-
{/* size="medium" */}
|
|
365
|
-
{/* backgroundColor="gray0" */}
|
|
366
|
-
{/* iconColor="gray6" */}
|
|
367
|
-
{/* borderRadius="round" */}
|
|
368
|
-
{/* /> */}
|
|
369
|
-
{/* </Padding> */}
|
|
370
|
-
{/* </Container> */}
|
|
371
|
-
<PreviewContainer ref={previewRef}>
|
|
372
|
-
{$customContent || (
|
|
373
|
-
<Document file={file} onLoadSuccess={onDocumentLoadSuccess}>
|
|
374
|
-
{pageElements}
|
|
375
|
-
</Document>
|
|
376
|
-
)}
|
|
377
|
-
</PreviewContainer>
|
|
378
|
-
{/* TODO: uncomment when navigation between items will be implemented */}
|
|
379
|
-
{/* <Container width="fit"> */}
|
|
380
|
-
{/* <Padding left="small" right="small"> */}
|
|
381
|
-
{/* <IconButton */}
|
|
382
|
-
{/* icon="ArrowForwardOutline" */}
|
|
383
|
-
{/* size="medium" */}
|
|
384
|
-
{/* backgroundColor="gray0" */}
|
|
385
|
-
{/* iconColor="gray6" */}
|
|
386
|
-
{/* borderRadius="round" */}
|
|
387
|
-
{/* /> */}
|
|
388
|
-
{/* </Padding> */}
|
|
389
|
-
{/* </Container> */}
|
|
390
|
-
</MiddleContainer>
|
|
391
|
-
</ExternalContainer>
|
|
392
|
-
</FocusWithin>
|
|
393
|
-
</Overlay>
|
|
394
|
-
</Portal>
|
|
395
|
-
);
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
export { PdfPreview, PdfPreviewProps };
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
|
|
3
|
-
*
|
|
4
|
-
* SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
-
*/
|
|
6
|
-
import React, { useCallback, useRef } from 'react';
|
|
7
|
-
|
|
8
|
-
import { Button, Text } from '@zextras/carbonio-design-system';
|
|
9
|
-
import styled from 'styled-components';
|
|
10
|
-
|
|
11
|
-
import { ContainerWithGap } from './ContainerWithGap';
|
|
12
|
-
|
|
13
|
-
const FakeModalContainer = styled(ContainerWithGap)`
|
|
14
|
-
border-radius: 16px;
|
|
15
|
-
padding: 32px 64px 32px 64px;
|
|
16
|
-
margin: auto;
|
|
17
|
-
`;
|
|
18
|
-
|
|
19
|
-
const AttachmentLink = styled.a`
|
|
20
|
-
text-decoration: none;
|
|
21
|
-
//position: relative;
|
|
22
|
-
`;
|
|
23
|
-
|
|
24
|
-
interface PreviewCriteriaAlternativeContentProps {
|
|
25
|
-
downloadSrc?: string;
|
|
26
|
-
openSrc?: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const PreviewCriteriaAlternativeContent: React.VFC<
|
|
30
|
-
PreviewCriteriaAlternativeContentProps
|
|
31
|
-
> = ({ downloadSrc, openSrc }) => {
|
|
32
|
-
const ancRef = useRef<HTMLAnchorElement>(null);
|
|
33
|
-
const ancRef2 = useRef<HTMLAnchorElement>(null);
|
|
34
|
-
|
|
35
|
-
const downloadClick = useCallback<React.ReactEventHandler>(
|
|
36
|
-
(ev) => {
|
|
37
|
-
ev.preventDefault();
|
|
38
|
-
if (ancRef.current) {
|
|
39
|
-
ancRef.current.click();
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
[ancRef]
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const openClick = useCallback<React.ReactEventHandler>(
|
|
46
|
-
(ev) => {
|
|
47
|
-
ev.preventDefault();
|
|
48
|
-
if (ancRef2.current) {
|
|
49
|
-
ancRef2.current.click();
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
[ancRef2]
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<FakeModalContainer
|
|
57
|
-
background="gray0"
|
|
58
|
-
crossAlignment="center"
|
|
59
|
-
height="fit"
|
|
60
|
-
width="fit"
|
|
61
|
-
gap="16px"
|
|
62
|
-
>
|
|
63
|
-
<Text size="large" color="gray6">
|
|
64
|
-
{'This item cannot be displayed'}
|
|
65
|
-
</Text>
|
|
66
|
-
<Text size="medium" color="gray6" weight="bold">
|
|
67
|
-
{'This file exceeds the maximum weight we support and thus, it cannot be displayed'}
|
|
68
|
-
</Text>
|
|
69
|
-
<ContainerWithGap orientation="horizontal" height="fit" gap="8px">
|
|
70
|
-
{downloadSrc && (
|
|
71
|
-
<Button
|
|
72
|
-
label="DOWNLOAD FILE"
|
|
73
|
-
icon="DownloadOutline"
|
|
74
|
-
size="fill"
|
|
75
|
-
onClick={downloadClick}
|
|
76
|
-
/>
|
|
77
|
-
)}
|
|
78
|
-
{openSrc && (
|
|
79
|
-
<Button
|
|
80
|
-
label="OPEN IN A SEPARATE TAB"
|
|
81
|
-
icon="DiagonalArrowRightUp"
|
|
82
|
-
size="fill"
|
|
83
|
-
onClick={openClick}
|
|
84
|
-
/>
|
|
85
|
-
)}
|
|
86
|
-
</ContainerWithGap>
|
|
87
|
-
<Text size="small" color="gray6">
|
|
88
|
-
{'Please, download it or open it in a separate tab'}
|
|
89
|
-
</Text>
|
|
90
|
-
{downloadSrc && <AttachmentLink rel="noopener" ref={ancRef} href={downloadSrc} />}
|
|
91
|
-
{openSrc && <AttachmentLink rel="noopener" ref={ancRef2} href={openSrc} />}
|
|
92
|
-
</FakeModalContainer>
|
|
93
|
-
);
|
|
94
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
|
|
3
|
-
*
|
|
4
|
-
* SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, { useCallback, createContext, useReducer } from 'react';
|
|
8
|
-
|
|
9
|
-
import { ImagePreviewProps } from './ImagePreview';
|
|
10
|
-
import { PdfPreviewProps } from './PdfPreview';
|
|
11
|
-
import { PreviewWrapper, PreviewWrapperProps } from './PreviewWrapper';
|
|
12
|
-
import { MakeOptional } from '../utils';
|
|
13
|
-
|
|
14
|
-
type CreatePreviewArgType = (
|
|
15
|
-
| MakeOptional<Omit<ImagePreviewProps, 'show'>, 'onClose'>
|
|
16
|
-
| MakeOptional<Omit<PdfPreviewProps, 'show'>, 'onClose'>
|
|
17
|
-
) & {
|
|
18
|
-
previewType: 'pdf' | 'image';
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const PreviewsManagerContext = createContext<{
|
|
22
|
-
createPreview: (args: CreatePreviewArgType) => void;
|
|
23
|
-
}>({
|
|
24
|
-
createPreview: () => undefined
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const PreviewManager: React.FC = ({ children }) => {
|
|
28
|
-
const [previews, dispatchPreviews] = useReducer(
|
|
29
|
-
(
|
|
30
|
-
state: Array<React.ReactElement>,
|
|
31
|
-
action: { type: 'set'; value: React.ReactElement } | { type: 'empty' }
|
|
32
|
-
) => {
|
|
33
|
-
switch (action.type) {
|
|
34
|
-
case 'set': {
|
|
35
|
-
return [...state, action.value];
|
|
36
|
-
}
|
|
37
|
-
case 'empty': {
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
default: {
|
|
41
|
-
return state;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
[]
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const createPreview = useCallback<(args: CreatePreviewArgType) => void>(
|
|
49
|
-
({ onClose, ...props }) => {
|
|
50
|
-
const closePreview: PreviewWrapperProps['onClose'] = (ev) => {
|
|
51
|
-
if (onClose) onClose(ev);
|
|
52
|
-
dispatchPreviews({ type: 'empty' });
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const preview = <PreviewWrapper key={props.src} {...props} show onClose={closePreview} />;
|
|
56
|
-
|
|
57
|
-
dispatchPreviews({
|
|
58
|
-
type: 'set',
|
|
59
|
-
value: preview
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
[dispatchPreviews]
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<>
|
|
67
|
-
<PreviewsManagerContext.Provider value={{ createPreview }}>
|
|
68
|
-
{children}
|
|
69
|
-
</PreviewsManagerContext.Provider>
|
|
70
|
-
{previews}
|
|
71
|
-
</>
|
|
72
|
-
);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
export { PreviewsManagerContext, PreviewManager };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
|
|
3
|
-
*
|
|
4
|
-
* SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
-
*/
|
|
6
|
-
import React from 'react';
|
|
7
|
-
|
|
8
|
-
import { ImagePreview, ImagePreviewProps } from './ImagePreview';
|
|
9
|
-
import { PdfPreview, PdfPreviewProps } from './PdfPreview';
|
|
10
|
-
|
|
11
|
-
type PreviewsProps = ImagePreviewProps | PdfPreviewProps;
|
|
12
|
-
|
|
13
|
-
type PreviewWrapperProps = PreviewsProps & {
|
|
14
|
-
previewType: 'pdf' | 'image';
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const PreviewWrapper: React.VFC<PreviewWrapperProps> = ({ previewType, ...props }) =>
|
|
18
|
-
previewType === 'pdf' ? <PdfPreview {...props} /> : <ImagePreview {...props} />;
|
|
19
|
-
|
|
20
|
-
export { PreviewWrapper, PreviewWrapperProps };
|