@zextras/carbonio-ui-preview 0.0.1

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.
@@ -0,0 +1,627 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+ import React, { useRef, useCallback, useEffect, useState, useMemo, createContext, useReducer } from "react";
33
+ import { Text, Tooltip, IconButton, Container, useCombinedRefs, Portal, Button } from "@zextras/carbonio-design-system";
34
+ import styled, { css } from "styled-components";
35
+ import last from "lodash/last";
36
+ import map from "lodash/map";
37
+ import findIndex from "lodash/findIndex";
38
+ import findLastIndex from "lodash/findLastIndex";
39
+ import { Page, Document } from "react-pdf/dist/esm/entry.webpack";
40
+ const FocusContainer = styled.span`
41
+ outline: none;
42
+ & > * {
43
+ outline: none;
44
+ }
45
+ `;
46
+ const FocusWithin = ({ children, returnFocus = true }) => {
47
+ const contentRef = useRef(null);
48
+ const startSentinelRef = useRef(null);
49
+ const endSentinelRef = useRef(null);
50
+ const onStartSentinelFocus = useCallback(() => {
51
+ if (contentRef.current) {
52
+ const node = last(contentRef.current.querySelectorAll("[tabindex]"));
53
+ node && node.focus();
54
+ }
55
+ }, []);
56
+ const onEndSentinelFocus = useCallback(() => {
57
+ if (contentRef.current) {
58
+ const node = contentRef.current.querySelector("[tabindex]");
59
+ node && node.focus();
60
+ }
61
+ }, []);
62
+ useEffect(() => {
63
+ var _a;
64
+ const documentElement = ((_a = window.top) == null ? void 0 : _a.document) || document;
65
+ const focusedElement = documentElement.activeElement;
66
+ contentRef.current && contentRef.current.focus();
67
+ startSentinelRef.current && startSentinelRef.current.addEventListener("focus", onStartSentinelFocus);
68
+ endSentinelRef.current && endSentinelRef.current.addEventListener("focus", onEndSentinelFocus);
69
+ const startSentinelRefSave = startSentinelRef.current;
70
+ const endSentinelRefSave = endSentinelRef.current;
71
+ return () => {
72
+ startSentinelRefSave && startSentinelRefSave.removeEventListener("focus", onStartSentinelFocus);
73
+ endSentinelRefSave && endSentinelRefSave.removeEventListener("focus", onEndSentinelFocus);
74
+ if (focusedElement && returnFocus) {
75
+ focusedElement.focus();
76
+ }
77
+ };
78
+ }, [onStartSentinelFocus, onEndSentinelFocus, returnFocus]);
79
+ return /* @__PURE__ */ React.createElement(FocusContainer, null, /* @__PURE__ */ React.createElement("span", {
80
+ tabIndex: 0,
81
+ ref: startSentinelRef
82
+ }), /* @__PURE__ */ React.createElement("div", {
83
+ tabIndex: -1,
84
+ ref: contentRef
85
+ }, children), /* @__PURE__ */ React.createElement("span", {
86
+ tabIndex: 0,
87
+ ref: endSentinelRef
88
+ }));
89
+ };
90
+ const HeaderContainer = styled.div`
91
+ display: flex;
92
+ justify-content: space-between;
93
+ padding: 16px;
94
+ `;
95
+ const LeftContainer = styled.div`
96
+ display: flex;
97
+ justify-content: flex-start;
98
+ align-items: center;
99
+ gap: 8px;
100
+ `;
101
+ const RightContainer = styled.div`
102
+ display: flex;
103
+ justify-content: flex-end;
104
+ align-items: center;
105
+ gap: 8px;
106
+ `;
107
+ const InfoContainer = styled.div`
108
+ width: fit-content;
109
+ & div {
110
+ line-height: 1.5;
111
+ }
112
+ `;
113
+ const UpperCaseText = styled(Text)`
114
+ text-transform: uppercase;
115
+ `;
116
+ const Header = ({ closeAction, actions, filename, extension, size }) => /* @__PURE__ */ React.createElement(HeaderContainer, null, /* @__PURE__ */ React.createElement(LeftContainer, null, closeAction && /* @__PURE__ */ React.createElement(Tooltip, {
117
+ label: closeAction.tooltipLabel,
118
+ disabled: !closeAction.tooltipLabel,
119
+ key: closeAction.id,
120
+ placement: closeAction.tooltipPlacement
121
+ }, /* @__PURE__ */ React.createElement(IconButton, {
122
+ onClick: closeAction.onClick,
123
+ icon: closeAction.icon,
124
+ size: "medium",
125
+ backgroundColor: "transparent",
126
+ iconColor: "gray6"
127
+ })), /* @__PURE__ */ React.createElement(InfoContainer, null, /* @__PURE__ */ React.createElement(Text, {
128
+ size: "small",
129
+ color: "gray6"
130
+ }, filename), /* @__PURE__ */ React.createElement(UpperCaseText, {
131
+ size: "small",
132
+ color: "gray6"
133
+ }, extension, extension && size && /* @__PURE__ */ React.createElement(React.Fragment, null, " \xB7 "), size))), /* @__PURE__ */ React.createElement(RightContainer, null, map(actions, ({ id, onClick, disabled, icon, tooltipLabel, tooltipPlacement }) => /* @__PURE__ */ React.createElement(Tooltip, {
134
+ label: tooltipLabel,
135
+ disabled: !tooltipLabel,
136
+ key: id,
137
+ placement: tooltipPlacement
138
+ }, /* @__PURE__ */ React.createElement(IconButton, {
139
+ onClick,
140
+ disabled,
141
+ icon,
142
+ size: "medium",
143
+ backgroundColor: "transparent",
144
+ iconColor: "gray6"
145
+ })))));
146
+ const Overlay$1 = styled.div`
147
+ height: 100vh;
148
+ max-height: 100vh;
149
+ width: 100%;
150
+ max-width: 100%;
151
+ position: fixed;
152
+ top: 0;
153
+ left: 0;
154
+ background-color: rgba(0, 0, 0, 0.8);
155
+ display: flex;
156
+ justify-content: center;
157
+ align-items: center;
158
+ z-index: 1003;
159
+ `;
160
+ const ExternalContainer$1 = styled.div`
161
+ height: 100vh;
162
+ max-height: 100vh;
163
+ width: 100vw;
164
+ max-width: 100vw;
165
+ display: flex;
166
+ flex-direction: column;
167
+ position: relative;
168
+ `;
169
+ const MiddleContainer$1 = styled(Container)`
170
+ flex-grow: 1;
171
+ `;
172
+ const Image = styled.img`
173
+ max-height: 100%;
174
+ max-width: 100%;
175
+ min-height: 0;
176
+ min-width: 0;
177
+ align-self: center;
178
+ filter: drop-shadow(0px 5px 14px rgba(0, 0, 0, 0.35));
179
+ border-radius: 4px;
180
+ `;
181
+ const PreviewContainer$1 = styled.div.attrs({
182
+ $paddingVertical: "32px",
183
+ $paddingHorizontal: "16px",
184
+ $gap: "8px"
185
+ })`
186
+ display: flex;
187
+ max-width: 100%;
188
+ max-height: calc(100vh - ${({ $paddingVertical }) => $paddingVertical} * 2);
189
+ flex-direction: column;
190
+ gap: ${({ $gap }) => $gap};
191
+ justify-content: center;
192
+ align-items: center;
193
+ overflow: hidden;
194
+ padding: ${({ $paddingVertical, $paddingHorizontal }) => `${$paddingVertical} ${$paddingHorizontal}`};
195
+ outline: none;
196
+ flex-grow: 1;
197
+ `;
198
+ const ImagePreview = React.forwardRef(function PreviewFn({
199
+ src,
200
+ show,
201
+ container,
202
+ disablePortal,
203
+ extension = "",
204
+ filename = "",
205
+ size = "",
206
+ actions = [],
207
+ closeAction,
208
+ onClose,
209
+ alt
210
+ }, ref) {
211
+ const previewRef = useCombinedRefs(ref);
212
+ const imageRef = useRef(null);
213
+ const escapeEvent = useCallback((event) => {
214
+ if (event.key === "Escape") {
215
+ onClose(event);
216
+ }
217
+ }, [onClose]);
218
+ useEffect(() => {
219
+ if (show) {
220
+ document.addEventListener("keyup", escapeEvent);
221
+ }
222
+ return () => {
223
+ document.removeEventListener("keyup", escapeEvent);
224
+ };
225
+ }, [escapeEvent, show]);
226
+ const onOverlayClick = useCallback((event) => {
227
+ event.stopPropagation();
228
+ previewRef.current && !event.isDefaultPrevented() && (previewRef.current === event.target || !previewRef.current.contains(event.target)) && onClose(event);
229
+ }, [onClose, previewRef]);
230
+ return /* @__PURE__ */ React.createElement(Portal, {
231
+ show,
232
+ disablePortal,
233
+ container
234
+ }, /* @__PURE__ */ React.createElement(Overlay$1, {
235
+ onClick: onOverlayClick
236
+ }, /* @__PURE__ */ React.createElement(FocusWithin, null, /* @__PURE__ */ React.createElement(ExternalContainer$1, null, /* @__PURE__ */ React.createElement(Header, {
237
+ actions,
238
+ filename,
239
+ extension,
240
+ size,
241
+ closeAction
242
+ }), /* @__PURE__ */ React.createElement(MiddleContainer$1, {
243
+ orientation: "horizontal",
244
+ crossAlignment: "unset",
245
+ minHeight: 0
246
+ }, /* @__PURE__ */ React.createElement(PreviewContainer$1, {
247
+ ref: previewRef
248
+ }, /* @__PURE__ */ React.createElement(Image, {
249
+ alt: alt != null ? alt : filename,
250
+ src,
251
+ onError: () => console.log("TODO handle error"),
252
+ ref: imageRef
253
+ })))))));
254
+ });
255
+ const ContainerWithGap = styled(Container)`
256
+ gap: ${({ gap }) => gap};
257
+ `;
258
+ const FakeModalContainer = styled(ContainerWithGap)`
259
+ border-radius: 16px;
260
+ padding: 32px 64px 32px 64px;
261
+ margin: auto;
262
+ `;
263
+ const AttachmentLink = styled.a`
264
+ text-decoration: none;
265
+ //position: relative;
266
+ `;
267
+ const PreviewCriteriaAlternativeContent = ({ downloadSrc, openSrc }) => {
268
+ const ancRef = useRef(null);
269
+ const ancRef2 = useRef(null);
270
+ const downloadClick = useCallback((ev) => {
271
+ ev.preventDefault();
272
+ if (ancRef.current) {
273
+ ancRef.current.click();
274
+ }
275
+ }, [ancRef]);
276
+ const openClick = useCallback((ev) => {
277
+ ev.preventDefault();
278
+ if (ancRef2.current) {
279
+ ancRef2.current.click();
280
+ }
281
+ }, [ancRef2]);
282
+ return /* @__PURE__ */ React.createElement(FakeModalContainer, {
283
+ background: "gray0",
284
+ crossAlignment: "center",
285
+ height: "fit",
286
+ width: "fit",
287
+ gap: "16px"
288
+ }, /* @__PURE__ */ React.createElement(Text, {
289
+ size: "large",
290
+ color: "gray6"
291
+ }, "This item cannot be displayed"), /* @__PURE__ */ React.createElement(Text, {
292
+ size: "medium",
293
+ color: "gray6",
294
+ weight: "bold"
295
+ }, "This file exceeds the maximum weight we support and thus, it cannot be displayed"), /* @__PURE__ */ React.createElement(ContainerWithGap, {
296
+ orientation: "horizontal",
297
+ height: "fit",
298
+ gap: "8px"
299
+ }, downloadSrc && /* @__PURE__ */ React.createElement(Button, {
300
+ label: "DOWNLOAD FILE",
301
+ icon: "DownloadOutline",
302
+ size: "fill",
303
+ onClick: downloadClick
304
+ }), openSrc && /* @__PURE__ */ React.createElement(Button, {
305
+ label: "OPEN IN A SEPARATE TAB",
306
+ icon: "DiagonalArrowRightUp",
307
+ size: "fill",
308
+ onClick: openClick
309
+ })), /* @__PURE__ */ React.createElement(Text, {
310
+ size: "small",
311
+ color: "gray6"
312
+ }, "Please, download it or open it in a separate tab"), downloadSrc && /* @__PURE__ */ React.createElement(AttachmentLink, {
313
+ rel: "noopener",
314
+ ref: ancRef,
315
+ href: downloadSrc
316
+ }), openSrc && /* @__PURE__ */ React.createElement(AttachmentLink, {
317
+ rel: "noopener",
318
+ ref: ancRef2,
319
+ href: openSrc
320
+ }));
321
+ };
322
+ const CustomIconButton = styled(IconButton)`
323
+ ${({ disabled }) => disabled && css`
324
+ background: rgba(204, 204, 204, 0.2);
325
+ & > svg {
326
+ background: unset;
327
+ }
328
+ `};
329
+ & > svg {
330
+ width: 20px;
331
+ height: 20px;
332
+ }
333
+ `;
334
+ const Overlay = styled.div`
335
+ height: 100vh;
336
+ max-height: 100vh;
337
+ width: 100%;
338
+ max-width: 100%;
339
+ position: fixed;
340
+ top: 0;
341
+ left: 0;
342
+ background-color: rgba(0, 0, 0, 0.8);
343
+ display: flex;
344
+ justify-content: center;
345
+ align-items: center;
346
+ z-index: 3;
347
+ `;
348
+ const MiddleContainer = styled(Container)`
349
+ flex-grow: 1;
350
+ `;
351
+ const ExternalContainer = styled.div`
352
+ height: 100vh;
353
+ max-height: 100vh;
354
+ width: 100vw;
355
+ max-width: 100vw;
356
+ display: flex;
357
+ flex-direction: column;
358
+ position: relative;
359
+ `;
360
+ const Navigator = styled.div`
361
+ display: flex;
362
+ position: absolute;
363
+ z-index: 1;
364
+ bottom: 16px;
365
+ background-color: ${({ theme }) => theme.palette.gray0.regular};
366
+ align-self: center;
367
+ border-radius: 4px;
368
+ gap: 8px;
369
+ padding: 8px 16px;
370
+ `;
371
+ const PreviewContainer = styled.div`
372
+ display: flex;
373
+ flex-direction: column;
374
+ flex-grow: 1;
375
+ // https://bhch.github.io/posts/2021/04/centring-flex-items-and-allowing-overflow-scroll/
376
+ //justify-content: center;
377
+ //align-items: center;
378
+ // justify-content and align-items conflict with overflow management
379
+ overflow: auto;
380
+ outline: none;
381
+
382
+ &::-webkit-scrollbar {
383
+ width: 7px;
384
+ height: 7px;
385
+ }
386
+
387
+ &::-webkit-scrollbar-track {
388
+ background-color: transparent;
389
+ }
390
+
391
+ &::-webkit-scrollbar-thumb {
392
+ background-color: ${({ theme }) => theme.palette.gray3.regular};
393
+ border-radius: 4px;
394
+ }
395
+
396
+ & > .react-pdf__Document {
397
+ //padding-right: 17px;
398
+ padding-bottom: 16px;
399
+ margin: auto;
400
+ display: flex;
401
+ gap: 16px;
402
+ flex-direction: column;
403
+ }
404
+
405
+ & .react-pdf__message {
406
+ color: white;
407
+ }
408
+ `;
409
+ const zoomStep = [800, 1e3, 1200, 1400, 1600, 2e3, 2400, 3200];
410
+ const PdfPreview = React.forwardRef(function PreviewFn2({
411
+ src,
412
+ show,
413
+ container,
414
+ disablePortal,
415
+ extension = "",
416
+ filename = "",
417
+ size = "",
418
+ actions = [],
419
+ closeAction,
420
+ onClose,
421
+ useFallback = false,
422
+ customContent,
423
+ renderTextLayer = false,
424
+ openSrc
425
+ }, ref) {
426
+ const previewRef = useCombinedRefs(ref);
427
+ const [numPages, setNumPages] = useState(null);
428
+ const $closeAction = useMemo(() => {
429
+ if (closeAction) {
430
+ return __spreadValues({
431
+ onClick: onClose
432
+ }, closeAction);
433
+ }
434
+ return closeAction;
435
+ }, [closeAction, onClose]);
436
+ const onOverlayClick = useCallback((event) => {
437
+ event.stopPropagation();
438
+ (useFallback || numPages) && previewRef.current && !event.isDefaultPrevented() && (previewRef.current === event.target || !previewRef.current.contains(event.target)) && onClose(event);
439
+ }, [numPages, onClose, previewRef, useFallback]);
440
+ const [currentZoom, setCurrentZoom] = useState(zoomStep[0]);
441
+ const [incrementable, setIncrementable] = useState(true);
442
+ const [decrementable, setDecrementable] = useState(false);
443
+ const [fitToWidthActive, setFitToWidthActive] = useState(false);
444
+ useEffect(() => {
445
+ if (!show) {
446
+ setCurrentZoom(zoomStep[0]);
447
+ setIncrementable(true);
448
+ setDecrementable(false);
449
+ setFitToWidthActive(false);
450
+ }
451
+ }, [show]);
452
+ const increaseOfOneStep = useCallback((ev) => {
453
+ ev.stopPropagation();
454
+ if (incrementable) {
455
+ const targetIndex = findIndex(zoomStep, (step) => step > currentZoom);
456
+ if (targetIndex >= 0) {
457
+ setCurrentZoom(zoomStep[targetIndex]);
458
+ if (targetIndex === zoomStep.length - 1) {
459
+ setIncrementable(false);
460
+ }
461
+ if (targetIndex > 0) {
462
+ setDecrementable(true);
463
+ }
464
+ }
465
+ }
466
+ setFitToWidthActive(false);
467
+ }, [currentZoom, incrementable]);
468
+ const decreaseOfOneStep = useCallback((ev) => {
469
+ ev.stopPropagation();
470
+ if (decrementable) {
471
+ const targetIndex = findLastIndex(zoomStep, (step) => step < currentZoom);
472
+ if (targetIndex >= 0) {
473
+ setCurrentZoom(zoomStep[targetIndex]);
474
+ if (targetIndex === 0) {
475
+ setDecrementable(false);
476
+ }
477
+ if (targetIndex < zoomStep.length - 1) {
478
+ setIncrementable(true);
479
+ }
480
+ }
481
+ }
482
+ setFitToWidthActive(false);
483
+ }, [currentZoom, decrementable]);
484
+ const fitToWidth = useCallback((ev) => {
485
+ var _a, _b, _c;
486
+ ev.stopPropagation();
487
+ if (previewRef.current) {
488
+ setCurrentZoom((_a = previewRef.current) == null ? void 0 : _a.clientWidth);
489
+ setIncrementable(((_b = previewRef.current) == null ? void 0 : _b.clientWidth) < zoomStep[zoomStep.length - 1]);
490
+ setDecrementable(((_c = previewRef.current) == null ? void 0 : _c.clientWidth) > zoomStep[0]);
491
+ setFitToWidthActive(true);
492
+ }
493
+ }, [previewRef]);
494
+ useEffect(() => {
495
+ if (show && fitToWidthActive) {
496
+ window.addEventListener("resize", fitToWidth);
497
+ }
498
+ return () => {
499
+ window.removeEventListener("resize", fitToWidth);
500
+ };
501
+ }, [fitToWidth, previewRef, show, fitToWidthActive]);
502
+ const resetWidth = useCallback((ev) => {
503
+ ev.stopPropagation();
504
+ setCurrentZoom(zoomStep[0]);
505
+ setIncrementable(true);
506
+ setDecrementable(false);
507
+ setFitToWidthActive(false);
508
+ }, []);
509
+ const pageElements = useMemo(() => {
510
+ if (numPages) {
511
+ return map(new Array(numPages), (el, index) => /* @__PURE__ */ React.createElement(Page, {
512
+ key: `page_${index + 1}`,
513
+ pageNumber: index + 1,
514
+ width: currentZoom,
515
+ renderTextLayer
516
+ }));
517
+ }
518
+ return [];
519
+ }, [currentZoom, numPages, renderTextLayer]);
520
+ const onDocumentLoadSuccess = useCallback((args) => {
521
+ setNumPages(args.numPages);
522
+ }, []);
523
+ const file = useMemo(() => ({ url: src }), [src]);
524
+ const $customContent = useMemo(() => {
525
+ if (useFallback) {
526
+ return customContent || /* @__PURE__ */ React.createElement(PreviewCriteriaAlternativeContent, {
527
+ downloadSrc: src,
528
+ openSrc
529
+ });
530
+ }
531
+ return void 0;
532
+ }, [customContent, openSrc, src, useFallback]);
533
+ return /* @__PURE__ */ React.createElement(Portal, {
534
+ show,
535
+ disablePortal,
536
+ container
537
+ }, /* @__PURE__ */ React.createElement(Overlay, {
538
+ onClick: onOverlayClick
539
+ }, /* @__PURE__ */ React.createElement(FocusWithin, null, /* @__PURE__ */ React.createElement(ExternalContainer, null, !$customContent && /* @__PURE__ */ React.createElement(Navigator, {
540
+ onClick: (ev) => ev.stopPropagation()
541
+ }, /* @__PURE__ */ React.createElement(Tooltip, {
542
+ label: decrementable ? "Zoom out" : "Minimum zoom level reached"
543
+ }, /* @__PURE__ */ React.createElement(CustomIconButton, {
544
+ disabled: !decrementable,
545
+ icon: "Minus",
546
+ size: "small",
547
+ backgroundColor: "gray0",
548
+ iconColor: "gray6",
549
+ onClick: decreaseOfOneStep
550
+ })), /* @__PURE__ */ React.createElement(Tooltip, {
551
+ label: fitToWidthActive ? "Reset zoom" : "Fit to width"
552
+ }, /* @__PURE__ */ React.createElement(CustomIconButton, {
553
+ icon: fitToWidthActive ? "MinimizeOutline" : "MaximizeOutline",
554
+ size: "small",
555
+ backgroundColor: "gray0",
556
+ iconColor: "gray6",
557
+ onClick: fitToWidthActive ? resetWidth : fitToWidth
558
+ })), /* @__PURE__ */ React.createElement(Tooltip, {
559
+ label: incrementable ? "Zoom in" : "Maximum zoom level reached"
560
+ }, /* @__PURE__ */ React.createElement(CustomIconButton, {
561
+ icon: "Plus",
562
+ size: "small",
563
+ backgroundColor: "gray0",
564
+ iconColor: "gray6",
565
+ onClick: increaseOfOneStep,
566
+ disabled: !incrementable
567
+ }))), /* @__PURE__ */ React.createElement(Header, {
568
+ actions,
569
+ filename,
570
+ extension,
571
+ size,
572
+ closeAction: $closeAction
573
+ }), /* @__PURE__ */ React.createElement(MiddleContainer, {
574
+ orientation: "horizontal",
575
+ crossAlignment: "unset",
576
+ minHeight: 0
577
+ }, /* @__PURE__ */ React.createElement(PreviewContainer, {
578
+ ref: previewRef
579
+ }, $customContent || /* @__PURE__ */ React.createElement(Document, {
580
+ file,
581
+ onLoadSuccess: onDocumentLoadSuccess
582
+ }, pageElements)))))));
583
+ });
584
+ const PreviewWrapper = (_a) => {
585
+ var _b = _a, { previewType } = _b, props = __objRest(_b, ["previewType"]);
586
+ return previewType === "pdf" ? /* @__PURE__ */ React.createElement(PdfPreview, __spreadValues({}, props)) : /* @__PURE__ */ React.createElement(ImagePreview, __spreadValues({}, props));
587
+ };
588
+ const PreviewsManagerContext = createContext({
589
+ createPreview: () => void 0
590
+ });
591
+ const PreviewManager = ({ children }) => {
592
+ const [previews, dispatchPreviews] = useReducer((state, action) => {
593
+ switch (action.type) {
594
+ case "set": {
595
+ return [...state, action.value];
596
+ }
597
+ case "empty": {
598
+ return [];
599
+ }
600
+ default: {
601
+ return state;
602
+ }
603
+ }
604
+ }, []);
605
+ const createPreview = useCallback((_a) => {
606
+ var _b = _a, { onClose } = _b, props = __objRest(_b, ["onClose"]);
607
+ const closePreview = (ev) => {
608
+ if (onClose)
609
+ onClose(ev);
610
+ dispatchPreviews({ type: "empty" });
611
+ };
612
+ const preview = /* @__PURE__ */ React.createElement(PreviewWrapper, __spreadProps(__spreadValues({
613
+ key: props.src
614
+ }, props), {
615
+ show: true,
616
+ onClose: closePreview
617
+ }));
618
+ dispatchPreviews({
619
+ type: "set",
620
+ value: preview
621
+ });
622
+ }, [dispatchPreviews]);
623
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(PreviewsManagerContext.Provider, {
624
+ value: { createPreview }
625
+ }, children), previews);
626
+ };
627
+ export { ImagePreview, PdfPreview, PreviewManager, PreviewWrapper, PreviewsManagerContext };
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@zextras/carbonio-ui-preview",
3
+ "version": "0.0.1",
4
+ "description": "Preview ui utility for Zextras Carbonio",
5
+ "main": "dist/carbonio-ui-preview.es.js",
6
+ "module": "dist/carbonio-ui-preview.es.js",
7
+ "types": "dist/carbonio-ui-preview.es.d.ts",
8
+ "scripts": {
9
+ "build": "vite build",
10
+ "build:watch": "vite build --watch",
11
+ "_postinstall": "is-ci || husky install",
12
+ "prepublishOnly": "pinst --disable",
13
+ "postpublish": "pinst --enable",
14
+ "type-check": "tsc --noEmit",
15
+ "type-check:watch": "npm run type-check -- --watch",
16
+ "lint": "eslint --ext .js,.jsx,.ts,.tsx --resolve-plugins-relative-to node_modules/@zextras/carbonio-ui-configs src",
17
+ "test": "jest"
18
+ },
19
+ "keywords": [],
20
+ "author": "Zextras SF Team <https://www.zextras.com/carbonio/>",
21
+ "license": "AGPL-3.0-only",
22
+ "devDependencies": {
23
+ "@commitlint/cli": "14.1.0",
24
+ "@commitlint/config-conventional": "14.1.0",
25
+ "@types/lodash": "^4.14.181",
26
+ "@types/react": "17.0.36",
27
+ "@types/react-dom": "17.0.11",
28
+ "@types/react-pdf": "^5.0.9",
29
+ "@types/styled-components": "^5.1.15",
30
+ "@zextras/carbonio-ui-configs": "^0.1.11",
31
+ "eslint-plugin-notice": "^0.9.10",
32
+ "husky": "^5.2.0",
33
+ "is-ci": "3.0.1",
34
+ "pinst": "2.1.6",
35
+ "vite": "^2.9.1",
36
+ "vite-dts": "^1.0.4"
37
+ },
38
+ "dependencies": {
39
+ "core-js": "3.19.1",
40
+ "react-pdf": "^5.7.1"
41
+ },
42
+ "peerDependencies": {
43
+ "@zextras/carbonio-design-system": "^0.1.4",
44
+ "lodash": "^4.17.21",
45
+ "react": "^17.0.2",
46
+ "react-dom": "^17.0.2",
47
+ "styled-components": "^5.3.3"
48
+ },
49
+ "browserslist": [
50
+ ">1%",
51
+ "last 1 version",
52
+ "Firefox ESR",
53
+ "not dead"
54
+ ]
55
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
3
+ *
4
+ * SPDX-License-Identifier: AGPL-3.0-only
5
+ */
6
+
7
+ /** Base components */
8
+ export * from './preview/ImagePreview';
9
+ export * from './preview/PdfPreview';
10
+ /** Utils */
11
+ export * from './preview/PreviewManager';
12
+ export * from './preview/PreviewWrapper';
@@ -0,0 +1,11 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
3
+ *
4
+ * SPDX-License-Identifier: AGPL-3.0-only
5
+ */
6
+ import { Container } from '@zextras/carbonio-design-system';
7
+ import styled from 'styled-components';
8
+
9
+ export const ContainerWithGap = styled(Container)`
10
+ gap: ${({ gap }): string => gap};
11
+ `;