@fibery/ui-kit 1.38.0 → 1.38.2

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/config/jest/testFrameworkSetup.js +1 -1
  3. package/package.json +23 -22
  4. package/src/abbreviate-name.ts +42 -0
  5. package/src/actions-menu/actions-menu-item.tsx +14 -5
  6. package/src/actions-menu/actions-menu-props.tsx +1 -0
  7. package/src/actions-menu/actions-menu.tsx +4 -1
  8. package/src/actions-menu/context-actions-menu.tsx +22 -0
  9. package/src/animated-height-container.tsx +24 -5
  10. package/src/antd/ant-upload.tsx +1 -1
  11. package/src/antd/input.tsx +4 -0
  12. package/src/avatar.tsx +1 -27
  13. package/src/button/base-button.tsx +2 -0
  14. package/src/button/button.tsx +4 -4
  15. package/src/button/icon-button.tsx +3 -3
  16. package/src/card-container.tsx +3 -2
  17. package/src/checkbox.tsx +17 -0
  18. package/src/collapsible/index.tsx +4 -2
  19. package/src/collapsible-section.tsx +3 -1
  20. package/src/date-picker/autocomplete.tsx +11 -5
  21. package/src/date-picker/date-range-input.tsx +5 -1
  22. package/src/date-picker/date-range-picker-popup-content.tsx +31 -13
  23. package/src/date-picker/single-date-input.tsx +5 -1
  24. package/src/date-picker/styles.ts +20 -0
  25. package/src/design-system.ts +26 -1
  26. package/src/dropdown-menu/index.tsx +11 -1
  27. package/src/emoji-picker/emoji-picker-preview-footer.tsx +4 -0
  28. package/src/emoji-picker/emoji.tsx +4 -3
  29. package/src/emoji-picker/primitives/emoji.tsx +49 -51
  30. package/src/emoji-picker/primitives/footer.tsx +6 -0
  31. package/src/emoji-picker/primitives/search.tsx +8 -0
  32. package/src/emoji-picker/primitives/skin-tone.tsx +12 -2
  33. package/src/fibermoji-placeholder.tsx +2 -29
  34. package/src/file-item-2.tsx +566 -0
  35. package/src/file-item.tsx +196 -162
  36. package/src/header-layout.tsx +11 -0
  37. package/src/html-styles.ts +13 -4
  38. package/src/icons/ast/Back.ts +1 -1
  39. package/src/icons/ast/ExtensionFiles.ts +1 -1
  40. package/src/icons/ast/FileArchive.ts +8 -0
  41. package/src/icons/ast/FileBroken.ts +8 -0
  42. package/src/icons/ast/FileDocument.ts +8 -0
  43. package/src/icons/ast/FileImage.ts +8 -0
  44. package/src/icons/ast/FilePresentation.ts +8 -0
  45. package/src/icons/ast/FileTable.ts +8 -0
  46. package/src/icons/ast/FileUpload.ts +1 -1
  47. package/src/icons/ast/FileVideo.ts +8 -0
  48. package/src/icons/ast/SwitchToMention.ts +8 -0
  49. package/src/icons/ast/SwitchToText.ts +8 -0
  50. package/src/icons/ast/SwitchToWidget.ts +8 -0
  51. package/src/icons/ast/ViewGallery.ts +8 -0
  52. package/src/icons/ast/index.tsx +11 -0
  53. package/src/icons/react/FileArchive.tsx +13 -0
  54. package/src/icons/react/FileBroken.tsx +13 -0
  55. package/src/icons/react/FileDocument.tsx +13 -0
  56. package/src/icons/react/FileImage.tsx +13 -0
  57. package/src/icons/react/FilePresentation.tsx +13 -0
  58. package/src/icons/react/FileTable.tsx +13 -0
  59. package/src/icons/react/FileVideo.tsx +13 -0
  60. package/src/icons/react/SwitchToMention.tsx +13 -0
  61. package/src/icons/react/SwitchToText.tsx +13 -0
  62. package/src/icons/react/SwitchToWidget.tsx +13 -0
  63. package/src/icons/react/ViewGallery.tsx +13 -0
  64. package/src/icons/react/index.tsx +11 -0
  65. package/src/icons/svg/back.svg +3 -1
  66. package/src/icons/svg/extension/files.svg +3 -1
  67. package/src/icons/svg/file-archive.svg +3 -0
  68. package/src/icons/svg/file-broken.svg +3 -0
  69. package/src/icons/svg/file-document.svg +3 -0
  70. package/src/icons/svg/file-image.svg +3 -0
  71. package/src/icons/svg/file-presentation.svg +3 -0
  72. package/src/icons/svg/file-table.svg +3 -0
  73. package/src/icons/svg/file-upload.svg +3 -6
  74. package/src/icons/svg/file-video.svg +3 -0
  75. package/src/icons/svg/switch-to-mention.svg +3 -0
  76. package/src/icons/svg/switch-to-text.svg +4 -0
  77. package/src/icons/svg/switch-to-widget.svg +4 -0
  78. package/src/icons/svg/view-gallery.svg +4 -0
  79. package/src/images-gallery/images-gallery-fall-through-provider.tsx +11 -0
  80. package/src/images-gallery/images-gallery.tsx +13 -10
  81. package/src/images-gallery/zoom.tsx +13 -2
  82. package/src/images-gallery-2/images-gallery-2.tsx +522 -0
  83. package/src/images-gallery-2/slide-buttons.tsx +271 -0
  84. package/src/images-gallery-2/zoom.tsx +35 -0
  85. package/src/kbd.tsx +46 -0
  86. package/src/loading-sausage.tsx +2 -2
  87. package/src/modal-menu/modal-menu-item.tsx +10 -2
  88. package/src/modal-menu/modal-menu-trigger.tsx +19 -2
  89. package/src/notification-dot.tsx +16 -7
  90. package/src/platform-symbols.ts +9 -0
  91. package/src/platform.ts +2 -0
  92. package/src/popover/index.tsx +31 -8
  93. package/src/popover/modifiers.tsx +26 -19
  94. package/src/reactions/reaction-button.tsx +323 -101
  95. package/src/reactions/reaction-picker.tsx +14 -1
  96. package/src/reactions/reactions.tsx +11 -1
  97. package/src/reactions/tootltip.tsx +55 -0
  98. package/src/rich-text-embed-error.tsx +2 -1
  99. package/src/select/components/group-heading.tsx +8 -0
  100. package/src/select/components/menu-list-virtualized.tsx +6 -2
  101. package/src/select/components/option.tsx +4 -0
  102. package/src/select/select-control-settings-context.tsx +11 -2
  103. package/src/select/select-in-popover.tsx +10 -7
  104. package/src/select/styles.ts +21 -1
  105. package/src/tab-nav/tab-nav.tsx +1 -1
  106. package/src/toggle.tsx +8 -0
  107. package/src/tooltip.tsx +28 -19
  108. package/src/type-badge.tsx +5 -2
  109. package/src/unit/unit-with-tooltip.tsx +1 -1
  110. package/src/use-is-phone.tsx +34 -6
  111. package/src/shortcut-badge.tsx +0 -29
@@ -0,0 +1,566 @@
1
+ /* eslint-disable max-lines */
2
+ import {css, cx} from "@linaria/core";
3
+ import {useCallback, useEffect, useState} from "react";
4
+ import {ActionsMenu, ActionsMenuItem, ActionsMenuSeparator} from "./actions-menu";
5
+ import {ActionsButtonCompact} from "./button/actions-button-compact";
6
+ import {border, colors, space, themeVars, fontSize, fontWeight, lineHeight} from "./design-system";
7
+ import {makeButtonColors} from "./button/make-button-colors";
8
+ import Delete from "./icons/react/Delete";
9
+ import FileDownload from "./icons/react/FileDownload";
10
+ import FileImage from "./icons/react/FileImage";
11
+ import FileVideo from "./icons/react/FileVideo";
12
+ import FileTable from "./icons/react/FileTable";
13
+ import FileDocument from "./icons/react/FileDocument";
14
+ import FileArchive from "./icons/react/FileArchive";
15
+ import FilePresentation from "./icons/react/FilePresentation";
16
+ import Link from "./icons/react/Link";
17
+ import RicheditorOpenLink from "./icons/react/RicheditorOpenLink";
18
+ import Spinner from "./icons/react/Spinner";
19
+ import AppWiki from "./icons/react/AppWiki";
20
+ import {copyToClipboard} from "./copy-to-clipboard";
21
+ import {useToast} from "./toast/toast-provider";
22
+ import {Icon} from "./icons/Icon";
23
+ import {useImagesGalleryMethods, useImagesGalleryRegistry} from "./images-gallery/images-gallery";
24
+
25
+ const fileItemStyle = css`
26
+ display: block;
27
+ height: 100%;
28
+ background-color: ${themeVars.transparent};
29
+ background-size: cover;
30
+ text-decoration: none;
31
+ border-radius: ${space.s8}px;
32
+ border: 1px solid ${themeVars.separatorColor};
33
+ background-clip: padding-box;
34
+ &:focus {
35
+ text-decoration: none;
36
+ }
37
+ `;
38
+
39
+ const overlayStyle = css`
40
+ width: 100%;
41
+ height: 100%;
42
+ padding: ${space.s8}px;
43
+ overflow: hidden;
44
+ color: ${themeVars.textColor};
45
+ border-radius: ${border.radius8}px;
46
+ cursor: pointer;
47
+ opacity: 0;
48
+ `;
49
+
50
+ const imageOverlayStyle = css`
51
+ background-size: 100% 200%;
52
+ background-position: 0 100%;
53
+ color: ${themeVars.transparent};
54
+ border-radius: ${border.radius6}px;
55
+ &:hover {
56
+ background-position: 0 0;
57
+ color: ${themeVars.inversedTextColor};
58
+ }
59
+ `;
60
+
61
+ const fileOverlayStyle = css`
62
+ opacity: 1;
63
+ background: transparent;
64
+ `;
65
+
66
+ export type FileItemType = {
67
+ name: string;
68
+ url: string;
69
+ downloadUrl?: string | null;
70
+ thumbnailUrl: string | null;
71
+ contentType: string;
72
+ previewData: null | {
73
+ type: "image" | "video" | "iframe";
74
+ previewSrc: string | null;
75
+ originalSrc: string;
76
+ };
77
+ status?: string;
78
+ };
79
+
80
+ export type FileItemProps = {
81
+ data: FileItemType;
82
+ onRemoveClick?: (x: FileItemType) => void;
83
+ disabled?: boolean;
84
+ };
85
+
86
+ export function FileItem(props: FileItemProps) {
87
+ const {name, url, thumbnailUrl, status, previewData: preview, contentType} = props.data;
88
+ const isPending = status === "uploading" || status === "deleting";
89
+ const isBackgroundReady = Boolean(thumbnailUrl && !isPending);
90
+ const [isActionsOpened, setIsActionsOpened] = useState(false);
91
+
92
+ const showFileIcon = !isPending && !isBackgroundReady;
93
+
94
+ const [zoomed, setZoomed] = useState(false);
95
+ const imagesRegistry = useImagesGalleryRegistry();
96
+ const galleryMethods = useImagesGalleryMethods();
97
+
98
+ useEffect(() => {
99
+ if (!preview) {
100
+ return;
101
+ }
102
+
103
+ imagesRegistry.set(preview.originalSrc, {
104
+ type: preview.type,
105
+ src: preview.originalSrc,
106
+ zoomed: false,
107
+ setZoomed,
108
+ actions: <FilePreviewActions url={preview.originalSrc} name={name} />,
109
+ });
110
+ }, [imagesRegistry, name, preview]);
111
+
112
+ useEffect(() => {
113
+ if (!preview) {
114
+ return;
115
+ }
116
+
117
+ if (zoomed) {
118
+ galleryMethods.setActivated(true);
119
+ }
120
+ const imageData = imagesRegistry.get(preview.originalSrc);
121
+ if (imageData) {
122
+ imageData.zoomed = zoomed;
123
+ } else {
124
+ imagesRegistry.set(preview.originalSrc, {
125
+ type: preview.type,
126
+ src: preview.originalSrc,
127
+ zoomed,
128
+ setZoomed,
129
+ actions: <FilePreviewActions url={preview.originalSrc} name={name} />,
130
+ });
131
+ }
132
+ }, [galleryMethods, zoomed, preview, imagesRegistry, name]);
133
+
134
+ const onContainerClick = useCallback(() => {
135
+ if (preview) {
136
+ setZoomed(true);
137
+ } else {
138
+ stratFileDownload(url, name);
139
+ }
140
+ }, [name, preview, url]);
141
+
142
+ return (
143
+ <div
144
+ className={cx(
145
+ css`
146
+ flex: 1 0 0;
147
+ height: 100%;
148
+ `,
149
+ isBackgroundReady &&
150
+ css`
151
+ &:hover .${overlayStyle} {
152
+ opacity: 1;
153
+ background-position: 0 0;
154
+ color: ${themeVars.whiteColor};
155
+ background-color: rgba(0, 0, 0, 0.6);
156
+ }
157
+ `,
158
+ isBackgroundReady &&
159
+ isActionsOpened &&
160
+ css`
161
+ .${overlayStyle} {
162
+ opacity: 1;
163
+ background-position: 0 0;
164
+ color: ${themeVars.whiteColor};
165
+ background-color: rgba(0, 0, 0, 0.6);
166
+ }
167
+ `
168
+ )}
169
+ >
170
+ <div
171
+ style={isBackgroundReady ? {backgroundImage: `url(${thumbnailUrl})`} : {}}
172
+ onClick={onContainerClick}
173
+ className={cx(
174
+ css`
175
+ flex-shrink: 0;
176
+ `,
177
+ fileItemStyle,
178
+ isPending &&
179
+ css`
180
+ ${{backgroundColor: themeVars.entityCardSelectedColor}}
181
+ `
182
+ )}
183
+ >
184
+ {isPending && (
185
+ <div
186
+ className={css`
187
+ display: flex;
188
+ flex-direction: column;
189
+ justify-content: center; /* centers vertically */
190
+ align-items: center; /* centers horizontally */
191
+ height: 100%;
192
+ width: 100%;
193
+ `}
194
+ >
195
+ <Spinner />
196
+ </div>
197
+ )}
198
+ {showFileIcon && (
199
+ <div className={cx(overlayStyle, fileOverlayStyle)}>
200
+ <div
201
+ className={css`
202
+ display: flex;
203
+ flex-direction: column;
204
+ justify-content: center; /* centers vertically */
205
+ align-items: center; /* centers horizontally */
206
+ height: 100%;
207
+ width: 100%;
208
+ padding-top: ${space.s1}px;
209
+ gap: ${space.s2}px;
210
+ `}
211
+ >
212
+ <Icon containerSize={40} iconSize={40}>
213
+ <FileIcon contentType={contentType} />
214
+ </Icon>
215
+ <div
216
+ className={css`
217
+ align-content: center;
218
+
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 10px;
222
+ flex-shrink: 0;
223
+ color: ${themeVars.colorTextMenuItem};
224
+ text-overflow: ellipsis;
225
+ overflow: hidden;
226
+ `}
227
+ >
228
+ <FileTitle
229
+ title={name}
230
+ className={css`
231
+ -webkit-line-clamp: 1;
232
+ -webkit-box-orient: vertical;
233
+ overflow: hidden;
234
+ text-overflow: ellipsis;
235
+ `}
236
+ />
237
+ </div>
238
+ </div>
239
+ <div
240
+ className={css`
241
+ position: absolute;
242
+ top: ${space.s8}px;
243
+ right: ${space.s8}px;
244
+ `}
245
+ >
246
+ <FileActionsMenu
247
+ setIsActionsOpened={setIsActionsOpened}
248
+ data={props.data}
249
+ disabled={props.disabled}
250
+ isBackgroundReady={isBackgroundReady}
251
+ onRemoveClick={props.onRemoveClick}
252
+ />
253
+ </div>
254
+ </div>
255
+ )}
256
+ {!isPending && !showFileIcon && (
257
+ <div className={cx(overlayStyle, isBackgroundReady ? imageOverlayStyle : fileOverlayStyle)}>
258
+ <div
259
+ className={css`
260
+ position: relative;
261
+ display: flex;
262
+ flex-direction: column;
263
+ justify-content: space-between; /* Top + bottom placement */
264
+ width: 100%;
265
+ height: 100%;
266
+ overflow: hidden;
267
+ box-sizing: border-box;
268
+ gap: ${space.s8}px;
269
+ `}
270
+ >
271
+ <div
272
+ className={css`
273
+ align-self: flex-end;
274
+ `}
275
+ >
276
+ <FileActionsMenu
277
+ setIsActionsOpened={setIsActionsOpened}
278
+ data={props.data}
279
+ disabled={props.disabled}
280
+ isBackgroundReady={isBackgroundReady}
281
+ onRemoveClick={props.onRemoveClick}
282
+ />
283
+ </div>
284
+ <div
285
+ className={css`
286
+ display: flex;
287
+ align-self: flex-start;
288
+ align-items: flex-end;
289
+ text-overflow: ellipsis;
290
+ //overflow: hidden;
291
+ box-sizing: border-box;
292
+ `}
293
+ >
294
+ <FileTitle title={name} />
295
+ </div>
296
+ </div>
297
+ </div>
298
+ )}
299
+ </div>
300
+ </div>
301
+ );
302
+ }
303
+
304
+ function FileActionsMenu({
305
+ data,
306
+ disabled,
307
+ setIsActionsOpened,
308
+ onRemoveClick,
309
+ isBackgroundReady,
310
+ }: {
311
+ data: FileItemType;
312
+ onRemoveClick?: (data: FileItemType) => void;
313
+ disabled?: boolean;
314
+ setIsActionsOpened: (val: boolean) => void;
315
+ isBackgroundReady: boolean;
316
+ }) {
317
+ const toast = useToast();
318
+
319
+ return (
320
+ <ActionsMenu
321
+ onOpenChange={setIsActionsOpened}
322
+ trigger={
323
+ <ActionsButtonCompact
324
+ className={css`
325
+ z-index: 1;
326
+ `}
327
+ style={isBackgroundReady ? makeButtonColors(colors.inversedTextColor, "ghost") : undefined}
328
+ />
329
+ }
330
+ >
331
+ <ActionsMenuItem
332
+ Icon={Link}
333
+ onSelect={() => {
334
+ copyToClipboard(`${window.origin}${data.url}`)
335
+ .then(() => toast.success({title: "Link copied to clipboard"}))
336
+ .catch((error) => toast.error({title: "Unable to copy link to clipboard", subTitle: error.message}));
337
+ }}
338
+ >
339
+ Copy file URL
340
+ </ActionsMenuItem>
341
+ <a href={data.url} target="_blank" rel="noopener noreferrer">
342
+ <ActionsMenuItem Icon={RicheditorOpenLink}>Open in new tab</ActionsMenuItem>
343
+ </a>
344
+ <a download={data.name} href={`${data.url}?attachment`}>
345
+ <ActionsMenuItem Icon={FileDownload}>Download</ActionsMenuItem>
346
+ </a>
347
+ <ActionsMenuSeparator />
348
+ <ActionsMenuItem Icon={Delete} onSelect={() => onRemoveClick?.(data)} dangerous disabled={disabled}>
349
+ Delete
350
+ </ActionsMenuItem>
351
+ </ActionsMenu>
352
+ );
353
+ }
354
+
355
+ function FileTitle({title, className}: {title: string; className?: string}) {
356
+ return (
357
+ <div
358
+ className={cx(
359
+ css`
360
+ border-radius: ${border.radius4}px;
361
+ background: ${themeVars.badgeBgColor};
362
+ padding: ${space.s2}px ${space.s5}px;
363
+ height: 100%;
364
+ vertical-align: top;
365
+ text-align: center;
366
+ justify-content: center;
367
+ word-break: break-word;
368
+ overflow: hidden;
369
+ font-size: ${fontSize.mini}px;
370
+ font-weight: ${fontWeight.medium};
371
+ line-height: ${lineHeight.narrow};
372
+ text-transform: none;
373
+ text-overflow: ellipsis;
374
+ -webkit-line-clamp: 1;
375
+ -webkit-box-orient: vertical;
376
+
377
+ &:hover {
378
+ text-decoration: none;
379
+ color: inherit;
380
+ }
381
+ `,
382
+ className
383
+ )}
384
+ >
385
+ {title}
386
+ </div>
387
+ );
388
+ }
389
+
390
+ function FilePreviewActions({url, name}: {url: string; name: string}) {
391
+ return (
392
+ <>
393
+ <a href={url} target="_blank" rel="noopener noreferrer">
394
+ <ActionsMenuItem Icon={RicheditorOpenLink}>Open in new tab</ActionsMenuItem>
395
+ </a>
396
+ <a download={name} href={`${url}?attachment`}>
397
+ <ActionsMenuItem Icon={FileDownload}>Download</ActionsMenuItem>
398
+ </a>
399
+ </>
400
+ );
401
+ }
402
+
403
+ function stratFileDownload(url: string, filename: string) {
404
+ const a = document.createElement("a");
405
+ a.href = `${url}?attachment`;
406
+ a.download = filename;
407
+ a.style.display = "none";
408
+
409
+ document.body.appendChild(a);
410
+ a.click();
411
+ document.body.removeChild(a);
412
+ }
413
+
414
+ function FileIcon({contentType}: {contentType: string}) {
415
+ if (contentType.startsWith("image/")) {
416
+ return <FileImage />;
417
+ }
418
+ if (contentType.startsWith("video/")) {
419
+ return <FileVideo />;
420
+ }
421
+ if (SheetsContentTypes.includes(contentType)) {
422
+ return <FileTable />;
423
+ }
424
+ if (ArchiveContentTypes.includes(contentType)) {
425
+ return <FileArchive />;
426
+ }
427
+ if (PresentationContentTypes.includes(contentType)) {
428
+ return <FilePresentation />;
429
+ }
430
+ if (DocumentContentTypes.includes(contentType) || contentType.startsWith("text/")) {
431
+ return <FileDocument />;
432
+ }
433
+
434
+ return <AppWiki />;
435
+ }
436
+
437
+ const ArchiveContentTypes = [
438
+ "application/zip",
439
+ "application/zip-compressed",
440
+ "application/x-zip",
441
+ "application/x-zip-compressed",
442
+ "multipart/x-zip",
443
+
444
+ "application/x-rar-compressed",
445
+ "application/vnd.rar",
446
+
447
+ "application/x-7z-compressed",
448
+
449
+ "application/gzip",
450
+ "application/x-gzip",
451
+
452
+ "application/x-tar",
453
+
454
+ "application/x-bzip",
455
+ "application/x-bzip2",
456
+ "application/x-bzip3",
457
+ "application/x-bzip4",
458
+
459
+ "application/x-xz",
460
+
461
+ "application/zstd",
462
+ "application/x-zstd",
463
+
464
+ "application/x-lzma",
465
+ "application/x-lzip",
466
+
467
+ "application/x-lzh",
468
+ "application/x-lha",
469
+
470
+ "application/x-iso9660-image",
471
+ "application/x-cd-image",
472
+
473
+ "application/x-apple-diskimage",
474
+
475
+ "application/x-arj",
476
+
477
+ "application/x-cpio",
478
+
479
+ "application/x-rpm",
480
+
481
+ "application/x-deb",
482
+ "application/vnd.debian.binary-package",
483
+
484
+ "application/x-compress",
485
+ "application/x-archive",
486
+ "application/vnd.android.package-archive",
487
+ ];
488
+
489
+ const PresentationContentTypes = [
490
+ "application/x-iwork-keynote-sffkey",
491
+ "application/vnd.ms-powerpoint",
492
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
493
+ "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
494
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
495
+ "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
496
+ "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
497
+ "application/vnd.ms-powerpoint.template.macroEnabled.12",
498
+ "application/vnd.oasis.opendocument.presentation",
499
+ "application/vnd.oasis.opendocument.presentation-template",
500
+ "application/vnd.apple.keynote",
501
+ "application/vnd.google-apps.presentation",
502
+ "application/pdf",
503
+ "application/vnd.sun.xml.impress",
504
+ "application/vnd.stardivision.impress",
505
+ ];
506
+
507
+ const SheetsContentTypes = [
508
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
509
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
510
+ "application/vnd.ms-excel",
511
+ "application/vnd.ms-excel.sheet.macroEnabled.12",
512
+ "application/vnd.ms-excel.template.macroEnabled.12",
513
+ "application/vnd.ms-excel.addin.macroEnabled.12",
514
+ "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
515
+ "application/vnd.oasis.opendocument.spreadsheet",
516
+ "application/vnd.oasis.opendocument.spreadsheet-template",
517
+ "application/vnd.apple.numbers",
518
+ "application/vnd.google-apps.spreadsheet",
519
+ "text/csv",
520
+ "text/x-comma-separated-values",
521
+ "application/csv",
522
+ "text/tab-separated-values",
523
+ "application/vnd.lotus-1-2-3",
524
+ "application/x-123",
525
+ "application/vnd.stardivision.calc",
526
+ "application/vnd.sun.xml.calc",
527
+ "application/x-dbase",
528
+ "application/x-iwork-numbers-sffnumbers",
529
+ ];
530
+
531
+ const DocumentContentTypes = [
532
+ "application/msword",
533
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
534
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
535
+ "application/vnd.ms-word.document.macroEnabled.12",
536
+ "application/vnd.ms-word.template.macroEnabled.12",
537
+
538
+ "application/vnd.oasis.opendocument.text",
539
+ "application/vnd.oasis.opendocument.text-template",
540
+ "application/vnd.oasis.opendocument.text-master",
541
+ "application/vnd.oasis.opendocument.text-web",
542
+
543
+ "application/vnd.apple.pages",
544
+ "application/x-iwork-pages-sffpages",
545
+
546
+ "application/rtf",
547
+ "text/rtf",
548
+
549
+ "text/plain",
550
+ "text/markdown",
551
+ "text/html",
552
+
553
+ "application/vnd.google-apps.document",
554
+
555
+ "application/vnd.sun.xml.writer",
556
+ "application/vnd.sun.xml.writer.template",
557
+ "application/vnd.sun.xml.writer.global",
558
+
559
+ "application/vnd.stardivision.writer",
560
+ "application/vnd.stardivision.writer-global",
561
+
562
+ "application/x-mswrite",
563
+ "application/x-abiword",
564
+
565
+ "application/pdf",
566
+ ];