@jobber/components 6.56.1 → 6.57.0

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.
@@ -1,143 +1,42 @@
1
- import React__default, { useState, useEffect } from 'react';
2
- import classnames from 'classnames';
1
+ import React__default, { useState } from 'react';
3
2
  import getHumanReadableFileSize from 'filesize';
4
- import { B as Button } from './Button-es.js';
5
- import { C as ConfirmationModal } from './ConfirmationModal-es.js';
6
- import { G as Glimmer } from './Glimmer-es.js';
7
- import { I as Icon } from './Icon-es.js';
8
- import { T as Typography } from './Typography-es.js';
3
+ import classnames from 'classnames';
4
+ import { T as Thumbnail } from './Thumbnail-es.js';
9
5
  import { T as Text } from './Text-es.js';
10
6
  import { P as ProgressBar } from './ProgressBar-es.js';
7
+ import { B as Button } from './Button-es.js';
8
+ import { C as ConfirmationModal } from './ConfirmationModal-es.js';
11
9
 
12
- var styles$2 = {"formatFile":"y9T1gWK9SHY-","expanded":"_6qcLC0nLki0-","compact":"cSm0ukEQcOU-","wrapper":"TEarBLxe1QY-","large":"rha7bX0NCtI-","base":"_7kv4ujgaxNk-","thumbnail":"Km0E9H-xb-M-","deleteButton":"d2l80-AKBiU-","clickable":"f7xR4ZcqlLo-","hoverable":"LxLX5kFFkfI-","progress":"_121nzRvOA-0-","contentBlock":"cyiC2EalTkQ-","deleteable":"qwQuqw4uODY-","spinning":"dR8gWEecWxc-"};
13
-
14
- function FormatFileDeleteButton({ size, onDelete }) {
15
- const buttonSize = size === "base" ? "small" : "base";
16
- const [deleteConfirmationOpen, setDeleteConfirmationOpen] = useState(false);
17
- return (React__default.createElement("div", { className: styles$2.deleteButton },
18
- React__default.createElement(Button, { onClick: () => setDeleteConfirmationOpen(true), variation: "destructive", type: "tertiary", icon: "trash", ariaLabel: "Delete File", size: buttonSize }),
19
- React__default.createElement(ConfirmationModal, { title: "Confirm Deletion", message: `Are you sure you want to delete this file?`, confirmLabel: "Delete", variation: "destructive", open: deleteConfirmationOpen, onConfirm: () => onDelete === null || onDelete === void 0 ? void 0 : onDelete(), onRequestClose: () => setDeleteConfirmationOpen(false) })));
20
- }
21
-
22
- var styles$1 = {"content":"GlvUe-y47J8-","hasName":"zxlhNVPlPfU-","large":"PLxm6a4dUeE-","fileName":"-HUnao9DHy4-","base":"HJGVBmS64DY-","spinning":"Svf9Lca4cus-"};
23
-
24
- var styles = {"image":"YdEHf0kMqIk-","fadeIn":"qG9O-VWpfw0-","hidden":"NoE9wiIsC-A-","spinning":"fNFmp-zaYd4-"};
25
-
26
- function InternalThumbnailImage({ file }) {
27
- const { name, src } = file;
28
- const [imageSource, setImageSource] = useState();
29
- const [imageLoaded, setImageLoaded] = useState(false);
30
- useEffect(() => {
31
- src().then(url => setImageSource(url));
32
- }, []);
33
- return (React__default.createElement(React__default.Fragment, null,
34
- !imageLoaded && React__default.createElement(Glimmer, { size: "auto" }),
35
- React__default.createElement("img", { src: imageSource, onError: file.onImageLoadError, onLoad: handleImageLoad, alt: name, "data-testid": "internalThumbnailImage", className: classnames(styles.image, { [styles.hidden]: !imageLoaded }) })));
36
- function handleImageLoad() {
37
- setImageLoaded(true);
38
- }
39
- }
40
-
41
- // This function comes from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
42
- function getClientBrowser(userAgent) {
43
- // The order matters here, and this may report false positives for unlisted browsers.
44
- if (userAgent.includes("Firefox")) {
45
- // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
46
- return "Mozilla Firefox";
47
- }
48
- else if (userAgent.includes("SamsungBrowser")) {
49
- // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
50
- return "Samsung Internet";
51
- }
52
- else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
53
- // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
54
- return "Opera";
55
- }
56
- else if (userAgent.includes("Edge")) {
57
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
58
- return "Microsoft Edge (Legacy)";
59
- }
60
- else if (userAgent.includes("Edg")) {
61
- // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
62
- return "Microsoft Edge (Chromium)";
63
- }
64
- else if (userAgent.includes("Chrome")) {
65
- // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
66
- return "Google Chrome or Chromium";
67
- }
68
- else if (userAgent.includes("Safari")) {
69
- // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
70
- return "Apple Safari";
71
- }
72
- else {
73
- return "unknown";
74
- }
75
- }
76
- function isSafari(userAgent) {
77
- return getClientBrowser(userAgent) === "Apple Safari";
78
- }
79
-
80
- function InternalThumbnail({ compact = false, size, file, }) {
81
- const { name, type } = file;
82
- const iconName = getIconNameFromType(type);
83
- const hasName = Boolean(name) && compact;
84
- if (type.startsWith("image/") && isSupportedImageType(file)) {
85
- return React__default.createElement(InternalThumbnailImage, { file: file });
86
- }
87
- return (React__default.createElement("div", { className: classnames(styles$1.content, styles$1[size], {
88
- [styles$1.hasName]: hasName,
89
- }) },
90
- React__default.createElement(Icon, { name: iconName, color: "greyBlue", size: size }),
91
- hasName && (React__default.createElement("div", { className: styles$1.fileName },
92
- React__default.createElement(Typography, { element: "span", textColor: "text", numberOfLines: 1 }, name)))));
93
- }
94
- function getIconNameFromType(mimeType) {
95
- if (mimeType.startsWith("image/"))
96
- return "image";
97
- if (mimeType.startsWith("video/"))
98
- return "video";
99
- switch (mimeType) {
100
- case "application/pdf":
101
- return "pdf";
102
- case "application/vnd.ms-excel":
103
- return "excel";
104
- default:
105
- return "file";
106
- }
107
- }
108
- function isSupportedImageType(file) {
109
- const userAgent = typeof document === "undefined" ? "" : window.navigator.userAgent;
110
- const nonHeicImage = !file.type.startsWith("image/heic");
111
- const nonSVGImage = !file.type.startsWith("image/svg");
112
- return (nonHeicImage || isSafari(userAgent)) && nonSVGImage;
113
- }
10
+ var styles = {"formatFile":"y9T1gWK9SHY-","expanded":"_6qcLC0nLki0-","compact":"cSm0ukEQcOU-","wrapper":"TEarBLxe1QY-","large":"rha7bX0NCtI-","base":"_7kv4ujgaxNk-","thumbnail":"Km0E9H-xb-M-","deleteButton":"d2l80-AKBiU-","clickable":"f7xR4ZcqlLo-","hoverable":"LxLX5kFFkfI-","progress":"_121nzRvOA-0-","contentBlock":"cyiC2EalTkQ-","deleteable":"qwQuqw4uODY-","spinning":"dR8gWEecWxc-"};
114
11
 
115
- function FormatFile({ file, display = "expanded", displaySize = "base", onDelete, onClick, }) {
12
+ const useFormatFile = ({ file }) => {
116
13
  const isComplete = file.progress >= 1;
117
14
  const fileSize = getHumanReadableFileSize(file.size);
118
- const wrapperClassNames = classnames(styles$2[display], styles$2.formatFile, {
119
- [styles$2[displaySize]]: display === "compact",
15
+ return {
16
+ isComplete,
17
+ fileSize,
18
+ };
19
+ };
20
+
21
+ const useFormatFileStyles = ({ display = "expanded", displaySize = "base", onClick, onDelete, isComplete, }) => {
22
+ const wrapperClassNames = classnames(styles[display], styles.formatFile, {
23
+ [styles[displaySize]]: display === "compact",
120
24
  });
121
- const DetailsContainer = isComplete && onClick ? "button" : "div";
122
- const detailsClassNames = classnames(styles$2.wrapper, {
123
- [styles$2[displaySize]]: display === "compact",
124
- [styles$2.hoverable]: isHoverable({ display, isComplete, onClick, onDelete }),
125
- [styles$2.clickable]: onClick,
126
- [styles$2.deleteable]: display === "compact",
25
+ const detailsClassNames = classnames(styles.wrapper, {
26
+ [styles[displaySize]]: display === "compact",
27
+ [styles.hoverable]: isHoverable({ display, isComplete, onClick, onDelete }),
28
+ [styles.clickable]: onClick,
29
+ [styles.deleteable]: display === "compact",
127
30
  });
128
- const thumbnailContainerClassNames = classnames(styles$2.thumbnail, styles$2[displaySize]);
129
- return (React__default.createElement("div", { className: wrapperClassNames },
130
- React__default.createElement(DetailsContainer, { type: "button", className: detailsClassNames, onClick: isComplete ? onClick : undefined, tabIndex: 0, "aria-busy": !isComplete },
131
- React__default.createElement("div", { className: thumbnailContainerClassNames },
132
- React__default.createElement(InternalThumbnail, { key: file.key, compact: display === "compact", file: file, size: displaySize }),
133
- !isComplete && (React__default.createElement("div", { className: styles$2.progress },
134
- React__default.createElement(ProgressBar, { size: "small", currentStep: file.progress * 100, totalSteps: 100 })))),
135
- display === "expanded" && (React__default.createElement("div", { className: styles$2.contentBlock },
136
- React__default.createElement(Text, { size: "base" }, file.name),
137
- React__default.createElement(Text, { size: "small" }, fileSize)))),
138
- isComplete && onDelete && (React__default.createElement("div", { className: styles$2.deleteButton },
139
- React__default.createElement(FormatFileDeleteButton, { size: display === "expanded" ? "large" : displaySize, onDelete: onDelete })))));
140
- }
31
+ const thumbnailContainerClassNames = classnames(styles.thumbnail, styles[displaySize]);
32
+ return {
33
+ deleteButtonContainerClassNames: styles.deleteButton,
34
+ detailsClassNames,
35
+ progressClassNames: styles.progress,
36
+ thumbnailContainerClassNames,
37
+ wrapperClassNames,
38
+ };
39
+ };
141
40
  function isHoverable({ display, isComplete, onClick, onDelete, }) {
142
41
  if (display === "compact") {
143
42
  return Boolean(isComplete && (onClick || onDelete));
@@ -148,4 +47,67 @@ function isHoverable({ display, isComplete, onClick, onDelete, }) {
148
47
  return false;
149
48
  }
150
49
 
151
- export { FormatFile as F, isSafari as i };
50
+ function FormatFile({ file, display = "expanded", displaySize = "base", onDelete, onClick, }) {
51
+ const [deleteConfirmationOpen, setDeleteConfirmationOpen] = useState(false);
52
+ const { isComplete, fileSize } = useFormatFile({
53
+ file,
54
+ display,
55
+ displaySize,
56
+ onClick,
57
+ onDelete,
58
+ });
59
+ const { wrapperClassNames, detailsClassNames, progressClassNames, thumbnailContainerClassNames, deleteButtonContainerClassNames, } = useFormatFileStyles({
60
+ display,
61
+ displaySize,
62
+ isComplete,
63
+ onClick,
64
+ onDelete,
65
+ });
66
+ return (React__default.createElement(FormatFile.Wrapper, { className: wrapperClassNames },
67
+ React__default.createElement(FormatFile.Body, { type: "button", className: detailsClassNames, onClick: isComplete ? onClick : undefined, tabIndex: 0, ariaBusy: !isComplete, isComplete: isComplete },
68
+ React__default.createElement(FormatFile.ThumbnailContainer, { className: thumbnailContainerClassNames },
69
+ React__default.createElement(Thumbnail, { key: file.key, compact: display === "compact", file: file, size: displaySize }),
70
+ React__default.createElement(FormatFile.ProgressContainer, { isHidden: isComplete, className: progressClassNames },
71
+ React__default.createElement(ProgressBar, { size: "small", currentStep: file.progress * 100, totalSteps: 100 }))),
72
+ React__default.createElement(FormatFile.Expanded, { isVisible: display === "expanded", file: file, fileSize: fileSize })),
73
+ React__default.createElement(FormatFile.DeleteButtonContainer, { className: deleteButtonContainerClassNames, isHidden: !isComplete || onDelete === undefined },
74
+ React__default.createElement(FormatFile.DeleteButton, { onDelete: () => {
75
+ setDeleteConfirmationOpen(true);
76
+ } },
77
+ React__default.createElement(ConfirmationModal, { title: "Confirm Deletion", message: `Are you sure you want to delete this file?`, confirmLabel: "Delete", variation: "destructive", open: deleteConfirmationOpen, onConfirm: () => onDelete === null || onDelete === void 0 ? void 0 : onDelete(), onRequestClose: () => setDeleteConfirmationOpen(false) })))));
78
+ }
79
+ FormatFile.DeleteButtonContainer = function FormatFileDeleteButtonContainer({ children, className, isHidden, }) {
80
+ if (isHidden)
81
+ return null;
82
+ return React__default.createElement("div", { className: className }, children);
83
+ };
84
+ FormatFile.ProgressContainer = function FormatFileProgressContainer({ isHidden, children, className, }) {
85
+ if (isHidden)
86
+ return null;
87
+ return React__default.createElement("div", { className: className }, children);
88
+ };
89
+ FormatFile.ThumbnailContainer = function FormatFileThumbnailContainer({ children, className, }) {
90
+ return React__default.createElement("div", { className: className }, children);
91
+ };
92
+ FormatFile.Body = function FormatFileBody({ children, className, type, onClick, tabIndex, ariaBusy, isComplete, }) {
93
+ const FormatFileBodyTag = isComplete && onClick ? "button" : "div";
94
+ return (React__default.createElement(FormatFileBodyTag, { type: type, className: className, onClick: onClick, tabIndex: tabIndex, "aria-busy": ariaBusy }, children));
95
+ };
96
+ FormatFile.Expanded = function FormatFileExpanded({ file, fileSize, isVisible, }) {
97
+ if (!isVisible)
98
+ return null;
99
+ return (React__default.createElement("div", { className: styles.contentBlock },
100
+ React__default.createElement(Text, { size: "base" }, file.name),
101
+ React__default.createElement(Text, { size: "small" }, fileSize)));
102
+ };
103
+ FormatFile.Wrapper = function FormatFileWrapper({ children, className, }) {
104
+ return React__default.createElement("div", { className: className }, children);
105
+ };
106
+ FormatFile.DeleteButton = function FormatFileDeleteButton({ onDelete, size = "base", children, }) {
107
+ const buttonSize = size === "base" ? "small" : "base";
108
+ return (React__default.createElement(React__default.Fragment, null,
109
+ React__default.createElement(Button, { onClick: onDelete, variation: "destructive", type: "tertiary", icon: "trash", ariaLabel: "Delete File", size: buttonSize }),
110
+ children));
111
+ };
112
+
113
+ export { FormatFile as F, useFormatFileStyles as a, useFormatFile as u };
@@ -35,17 +35,18 @@ require('../_isIterateeCall-cjs.js');
35
35
  require('../_setToString-cjs.js');
36
36
  require('../FormatFile-cjs.js');
37
37
  require('filesize');
38
+ require('../Thumbnail-cjs.js');
39
+ require('../Glimmer-cjs.js');
40
+ require('../Content-cjs.js');
41
+ require('../ProgressBar-cjs.js');
38
42
  require('../ConfirmationModal-cjs.js');
39
43
  require('../Modal/index.cjs');
40
44
  require('../noop-cjs.js');
41
45
  require('../floating-ui.react-cjs.js');
42
46
  require('../AtlantisPortalContent-cjs.js');
43
- require('../Content-cjs.js');
44
47
  require('../Markdown-cjs.js');
45
48
  require('../Emphasis-cjs.js');
46
49
  require('../index-cjs.js');
47
- require('../Glimmer-cjs.js');
48
- require('../ProgressBar-cjs.js');
49
50
 
50
51
 
51
52
 
@@ -33,14 +33,15 @@ import '../_isIterateeCall-es.js';
33
33
  import '../_setToString-es.js';
34
34
  import '../FormatFile-es.js';
35
35
  import 'filesize';
36
+ import '../Thumbnail-es.js';
37
+ import '../Glimmer-es.js';
38
+ import '../Content-es.js';
39
+ import '../ProgressBar-es.js';
36
40
  import '../ConfirmationModal-es.js';
37
41
  import '../Modal/index.mjs';
38
42
  import '../noop-es.js';
39
43
  import '../floating-ui.react-es.js';
40
44
  import '../AtlantisPortalContent-es.js';
41
- import '../Content-es.js';
42
45
  import '../Markdown-es.js';
43
46
  import '../Emphasis-es.js';
44
47
  import '../index-es.js';
45
- import '../Glimmer-es.js';
46
- import '../ProgressBar-es.js';
@@ -5,7 +5,9 @@ var React = require('react');
5
5
  var classnames = require('classnames');
6
6
  var LightBox = require('./LightBox-cjs.js');
7
7
  var FormatFile = require('./FormatFile-cjs.js');
8
+ require('filesize');
8
9
  var Button = require('./Button-cjs.js');
10
+ var Thumbnail = require('./Thumbnail-cjs.js');
9
11
 
10
12
  var styles = {"gallery":"_6UhvrmKZdns-","galleryLarge":"f0hnJ8v-iHE-","showMoreButton":"EvHA4-Q7O9g-","baseShowMoreButton":"VWW-3mSlumg-","largeShowMoreButton":"DNhegGxB75M-","spinning":"aqCoXiyvGKw-"};
11
13
 
@@ -65,7 +67,7 @@ function isSupportedImageType(file) {
65
67
  const userAgent = typeof document === "undefined" ? "" : window.navigator.userAgent;
66
68
  const nonHeicImage = !file.type.startsWith("image/heic");
67
69
  const nonSVGImage = !file.type.startsWith("image/svg");
68
- return (nonHeicImage || FormatFile.isSafari(userAgent)) && nonSVGImage;
70
+ return (nonHeicImage || Thumbnail.isSafari(userAgent)) && nonSVGImage;
69
71
  }
70
72
  function generateImagesArray(files) {
71
73
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
@@ -2,8 +2,10 @@ import { a as __awaiter } from './tslib.es6-es.js';
2
2
  import React__default, { useState } from 'react';
3
3
  import classnames from 'classnames';
4
4
  import { L as LightBox } from './LightBox-es.js';
5
- import { F as FormatFile, i as isSafari } from './FormatFile-es.js';
5
+ import { F as FormatFile } from './FormatFile-es.js';
6
+ import 'filesize';
6
7
  import { B as Button } from './Button-es.js';
8
+ import { i as isSafari } from './Thumbnail-es.js';
7
9
 
8
10
  var styles = {"gallery":"_6UhvrmKZdns-","galleryLarge":"f0hnJ8v-iHE-","showMoreButton":"EvHA4-Q7O9g-","baseShowMoreButton":"VWW-3mSlumg-","largeShowMoreButton":"DNhegGxB75M-","spinning":"aqCoXiyvGKw-"};
9
11
 
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { FileUpload } from "../InputFile";
3
+ interface ThumbnailProps {
4
+ readonly compact?: boolean;
5
+ readonly size: "base" | "large";
6
+ readonly file: FileUpload;
7
+ /**
8
+ * **Use at your own risk:** Custom classNames for specific elements. This should only be used as a
9
+ * **last resort**. Using this may result in unexpected side effects.
10
+ * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
11
+ */
12
+ readonly UNSAFE_className?: {
13
+ container?: string;
14
+ };
15
+ /**
16
+ * **Use at your own risk:** Custom classNames for specific elements. This should only be used as a
17
+ * **last resort**. Using this may result in unexpected side effects.
18
+ * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
19
+ */
20
+ readonly UNSAFE_style?: {
21
+ container?: React.CSSProperties;
22
+ };
23
+ }
24
+ export declare function Thumbnail({ compact, size, file, UNSAFE_className, UNSAFE_style, }: ThumbnailProps): JSX.Element;
25
+ export {};
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { FileUpload } from "../InputFile";
3
+ interface InternalThumbnailImageProps {
4
+ readonly file: FileUpload;
5
+ /**
6
+ * **Use at your own risk:** Custom classNames for specific elements. This should only be used as a
7
+ * **last resort**. Using this may result in unexpected side effects.
8
+ * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
9
+ */
10
+ readonly UNSAFE_className?: {
11
+ container?: string;
12
+ };
13
+ /**
14
+ * **Use at your own risk:** Custom classNames for specific elements. This should only be used as a
15
+ * **last resort**. Using this may result in unexpected side effects.
16
+ * More information in the [Customizing components Guide](https://atlantis.getjobber.com/guides/customizing-components).
17
+ */
18
+ readonly UNSAFE_style?: {
19
+ container?: React.CSSProperties;
20
+ };
21
+ }
22
+ export declare function InternalThumbnailImage({ file, UNSAFE_className, UNSAFE_style, }: InternalThumbnailImageProps): JSX.Element;
23
+ export {};
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ var Thumbnail = require('../Thumbnail-cjs.js');
4
+ require('react');
5
+ require('classnames');
6
+ require('../Glimmer-cjs.js');
7
+ require('../tslib.es6-cjs.js');
8
+ require('../Content-cjs.js');
9
+ require('../Icon-cjs.js');
10
+ require('@jobber/design');
11
+ require('../Typography-cjs.js');
12
+
13
+
14
+
15
+ exports.Thumbnail = Thumbnail.Thumbnail;
@@ -0,0 +1 @@
1
+ export * from "./Thumbnail";
@@ -0,0 +1,9 @@
1
+ export { T as Thumbnail } from '../Thumbnail-es.js';
2
+ import 'react';
3
+ import 'classnames';
4
+ import '../Glimmer-es.js';
5
+ import '../tslib.es6-es.js';
6
+ import '../Content-es.js';
7
+ import '../Icon-es.js';
8
+ import '@jobber/design';
9
+ import '../Typography-es.js';
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var classnames = require('classnames');
5
+ var Glimmer = require('./Glimmer-cjs.js');
6
+ var Icon = require('./Icon-cjs.js');
7
+ var Typography = require('./Typography-cjs.js');
8
+
9
+ var styles$1 = {"content":"b9lhF-BkUnI-","hasName":"BJLJeUxloeQ-","large":"t5IzWH6-Sy0-","fileName":"tj--cPRjQfI-","base":"l2Vxo1qaR8U-","spinning":"LDAOyzklETo-"};
10
+
11
+ var styles = {"image":"qOmZU-rbNf4-","fadeIn":"zB1aNhsmmqY-","hidden":"_2bihNsPs7w4-","spinning":"ZLMkLuZeH-o-"};
12
+
13
+ function InternalThumbnailImage({ file, UNSAFE_className, UNSAFE_style, }) {
14
+ const { name, src } = file;
15
+ const [imageSource, setImageSource] = React.useState();
16
+ const [imageLoaded, setImageLoaded] = React.useState(false);
17
+ React.useEffect(() => {
18
+ src().then(url => setImageSource(url));
19
+ }, []);
20
+ return (React.createElement(React.Fragment, null,
21
+ !imageLoaded && React.createElement(Glimmer.Glimmer, { size: "auto" }),
22
+ React.createElement("img", { src: imageSource, onError: file.onImageLoadError, onLoad: handleImageLoad, alt: name, "data-testid": "internalThumbnailImage", className: classnames(styles.image, { [styles.hidden]: !imageLoaded }, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container), style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container })));
23
+ function handleImageLoad() {
24
+ setImageLoaded(true);
25
+ }
26
+ }
27
+
28
+ // This function comes from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
29
+ function getClientBrowser(userAgent) {
30
+ // The order matters here, and this may report false positives for unlisted browsers.
31
+ if (userAgent.includes("Firefox")) {
32
+ // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
33
+ return "Mozilla Firefox";
34
+ }
35
+ else if (userAgent.includes("SamsungBrowser")) {
36
+ // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
37
+ return "Samsung Internet";
38
+ }
39
+ else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
40
+ // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
41
+ return "Opera";
42
+ }
43
+ else if (userAgent.includes("Edge")) {
44
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
45
+ return "Microsoft Edge (Legacy)";
46
+ }
47
+ else if (userAgent.includes("Edg")) {
48
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
49
+ return "Microsoft Edge (Chromium)";
50
+ }
51
+ else if (userAgent.includes("Chrome")) {
52
+ // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
53
+ return "Google Chrome or Chromium";
54
+ }
55
+ else if (userAgent.includes("Safari")) {
56
+ // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
57
+ return "Apple Safari";
58
+ }
59
+ else {
60
+ return "unknown";
61
+ }
62
+ }
63
+ function isSafari(userAgent) {
64
+ return getClientBrowser(userAgent) === "Apple Safari";
65
+ }
66
+
67
+ function Thumbnail({ compact = false, size, file, UNSAFE_className, UNSAFE_style, }) {
68
+ const { name, type } = file;
69
+ const iconName = getIconNameFromType(type);
70
+ const hasName = Boolean(name) && compact;
71
+ if (type.startsWith("image/") && isSupportedImageType(file)) {
72
+ return (React.createElement(InternalThumbnailImage, { file: file, UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }));
73
+ }
74
+ return (React.createElement("div", { className: classnames(styles$1.content, styles$1[size], {
75
+ [styles$1.hasName]: hasName,
76
+ }, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container), style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container },
77
+ React.createElement(Icon.Icon, { name: iconName, color: "greyBlue", size: size }),
78
+ hasName && (React.createElement("div", { className: styles$1.fileName },
79
+ React.createElement(Typography.Typography, { element: "span", textColor: "text", numberOfLines: 1 }, name)))));
80
+ }
81
+ function getIconNameFromType(mimeType) {
82
+ if (mimeType.startsWith("image/"))
83
+ return "image";
84
+ if (mimeType.startsWith("video/"))
85
+ return "video";
86
+ switch (mimeType) {
87
+ case "application/pdf":
88
+ return "pdf";
89
+ case "application/vnd.ms-excel":
90
+ return "excel";
91
+ default:
92
+ return "file";
93
+ }
94
+ }
95
+ function isSupportedImageType(file) {
96
+ const userAgent = typeof document === "undefined" ? "" : window.navigator.userAgent;
97
+ const nonHeicImage = !file.type.startsWith("image/heic");
98
+ const nonSVGImage = !file.type.startsWith("image/svg");
99
+ return (nonHeicImage || isSafari(userAgent)) && nonSVGImage;
100
+ }
101
+
102
+ exports.Thumbnail = Thumbnail;
103
+ exports.isSafari = isSafari;
@@ -0,0 +1,100 @@
1
+ import React__default, { useState, useEffect } from 'react';
2
+ import classnames from 'classnames';
3
+ import { G as Glimmer } from './Glimmer-es.js';
4
+ import { I as Icon } from './Icon-es.js';
5
+ import { T as Typography } from './Typography-es.js';
6
+
7
+ var styles$1 = {"content":"b9lhF-BkUnI-","hasName":"BJLJeUxloeQ-","large":"t5IzWH6-Sy0-","fileName":"tj--cPRjQfI-","base":"l2Vxo1qaR8U-","spinning":"LDAOyzklETo-"};
8
+
9
+ var styles = {"image":"qOmZU-rbNf4-","fadeIn":"zB1aNhsmmqY-","hidden":"_2bihNsPs7w4-","spinning":"ZLMkLuZeH-o-"};
10
+
11
+ function InternalThumbnailImage({ file, UNSAFE_className, UNSAFE_style, }) {
12
+ const { name, src } = file;
13
+ const [imageSource, setImageSource] = useState();
14
+ const [imageLoaded, setImageLoaded] = useState(false);
15
+ useEffect(() => {
16
+ src().then(url => setImageSource(url));
17
+ }, []);
18
+ return (React__default.createElement(React__default.Fragment, null,
19
+ !imageLoaded && React__default.createElement(Glimmer, { size: "auto" }),
20
+ React__default.createElement("img", { src: imageSource, onError: file.onImageLoadError, onLoad: handleImageLoad, alt: name, "data-testid": "internalThumbnailImage", className: classnames(styles.image, { [styles.hidden]: !imageLoaded }, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container), style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container })));
21
+ function handleImageLoad() {
22
+ setImageLoaded(true);
23
+ }
24
+ }
25
+
26
+ // This function comes from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
27
+ function getClientBrowser(userAgent) {
28
+ // The order matters here, and this may report false positives for unlisted browsers.
29
+ if (userAgent.includes("Firefox")) {
30
+ // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
31
+ return "Mozilla Firefox";
32
+ }
33
+ else if (userAgent.includes("SamsungBrowser")) {
34
+ // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
35
+ return "Samsung Internet";
36
+ }
37
+ else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
38
+ // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
39
+ return "Opera";
40
+ }
41
+ else if (userAgent.includes("Edge")) {
42
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
43
+ return "Microsoft Edge (Legacy)";
44
+ }
45
+ else if (userAgent.includes("Edg")) {
46
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
47
+ return "Microsoft Edge (Chromium)";
48
+ }
49
+ else if (userAgent.includes("Chrome")) {
50
+ // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
51
+ return "Google Chrome or Chromium";
52
+ }
53
+ else if (userAgent.includes("Safari")) {
54
+ // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
55
+ return "Apple Safari";
56
+ }
57
+ else {
58
+ return "unknown";
59
+ }
60
+ }
61
+ function isSafari(userAgent) {
62
+ return getClientBrowser(userAgent) === "Apple Safari";
63
+ }
64
+
65
+ function Thumbnail({ compact = false, size, file, UNSAFE_className, UNSAFE_style, }) {
66
+ const { name, type } = file;
67
+ const iconName = getIconNameFromType(type);
68
+ const hasName = Boolean(name) && compact;
69
+ if (type.startsWith("image/") && isSupportedImageType(file)) {
70
+ return (React__default.createElement(InternalThumbnailImage, { file: file, UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }));
71
+ }
72
+ return (React__default.createElement("div", { className: classnames(styles$1.content, styles$1[size], {
73
+ [styles$1.hasName]: hasName,
74
+ }, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container), style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container },
75
+ React__default.createElement(Icon, { name: iconName, color: "greyBlue", size: size }),
76
+ hasName && (React__default.createElement("div", { className: styles$1.fileName },
77
+ React__default.createElement(Typography, { element: "span", textColor: "text", numberOfLines: 1 }, name)))));
78
+ }
79
+ function getIconNameFromType(mimeType) {
80
+ if (mimeType.startsWith("image/"))
81
+ return "image";
82
+ if (mimeType.startsWith("video/"))
83
+ return "video";
84
+ switch (mimeType) {
85
+ case "application/pdf":
86
+ return "pdf";
87
+ case "application/vnd.ms-excel":
88
+ return "excel";
89
+ default:
90
+ return "file";
91
+ }
92
+ }
93
+ function isSupportedImageType(file) {
94
+ const userAgent = typeof document === "undefined" ? "" : window.navigator.userAgent;
95
+ const nonHeicImage = !file.type.startsWith("image/heic");
96
+ const nonSVGImage = !file.type.startsWith("image/svg");
97
+ return (nonHeicImage || isSafari(userAgent)) && nonSVGImage;
98
+ }
99
+
100
+ export { Thumbnail as T, isSafari as i };
package/dist/index.cjs CHANGED
@@ -95,6 +95,7 @@ var Stack = require('./Stack-cjs.js');
95
95
  var Switch = require('./Switch-cjs.js');
96
96
  var Body = require('./Body-cjs.js');
97
97
  var Tabs = require('./Tabs-cjs.js');
98
+ var Thumbnail = require('./Thumbnail-cjs.js');
98
99
  var Tiles = require('./Tiles-cjs.js');
99
100
  var showToast = require('./showToast-cjs.js');
100
101
  var Tooltip = require('./Tooltip-cjs.js');
@@ -271,6 +272,8 @@ exports.FormatDate = FormatDate.FormatDate;
271
272
  exports.strFormatDate = FormatDate.strFormatDate;
272
273
  exports.FormatEmail = FormatEmail.FormatEmail;
273
274
  exports.FormatFile = FormatFile.FormatFile;
275
+ exports.useFormatFile = FormatFile.useFormatFile;
276
+ exports.useFormatFileStyles = FormatFile.useFormatFileStyles;
274
277
  exports.FormatRelativeDateTime = FormatRelativeDateTime.FormatRelativeDateTime;
275
278
  exports.FormatTime = FormatTime.FormatTime;
276
279
  exports.Frame = Frame.Frame;
@@ -344,6 +347,7 @@ exports.Row = Body.Row;
344
347
  exports.Table = Body.Table;
345
348
  exports.Tab = Tabs.Tab;
346
349
  exports.Tabs = Tabs.Tabs;
350
+ exports.Thumbnail = Thumbnail.Thumbnail;
347
351
  exports.Tiles = Tiles.Tiles;
348
352
  exports.Toast = showToast.Toast;
349
353
  exports.showToast = showToast.showToast;
package/dist/index.d.mts CHANGED
@@ -81,6 +81,7 @@ export * from "./Switch";
81
81
  export * from "./Table";
82
82
  export * from "./Tabs";
83
83
  export * from "./Text";
84
+ export * from "./Thumbnail";
84
85
  export * from "./Tiles";
85
86
  export * from "./Toast";
86
87
  export * from "./Tooltip";
package/dist/index.d.ts CHANGED
@@ -81,6 +81,7 @@ export * from "./Switch";
81
81
  export * from "./Table";
82
82
  export * from "./Tabs";
83
83
  export * from "./Text";
84
+ export * from "./Thumbnail";
84
85
  export * from "./Tiles";
85
86
  export * from "./Toast";
86
87
  export * from "./Tooltip";