@useupup/svelte 3.3.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.
Files changed (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/UpupUploader.svelte +96 -0
  4. package/dist/UpupUploader.svelte.d.ts +5 -0
  5. package/dist/UpupUploader.svelte.d.ts.map +1 -0
  6. package/dist/assets/logos.d.ts +5 -0
  7. package/dist/assets/logos.d.ts.map +1 -0
  8. package/dist/assets/logos.js +4 -0
  9. package/dist/components/AudioUploader.svelte +220 -0
  10. package/dist/components/AudioUploader.svelte.d.ts +4 -0
  11. package/dist/components/AudioUploader.svelte.d.ts.map +1 -0
  12. package/dist/components/AudioWaveform.svelte +72 -0
  13. package/dist/components/AudioWaveform.svelte.d.ts +7 -0
  14. package/dist/components/AudioWaveform.svelte.d.ts.map +1 -0
  15. package/dist/components/BoxUploader.svelte +17 -0
  16. package/dist/components/BoxUploader.svelte.d.ts +19 -0
  17. package/dist/components/BoxUploader.svelte.d.ts.map +1 -0
  18. package/dist/components/CameraUploader.svelte +140 -0
  19. package/dist/components/CameraUploader.svelte.d.ts +4 -0
  20. package/dist/components/CameraUploader.svelte.d.ts.map +1 -0
  21. package/dist/components/ClientBoxUploader.svelte +60 -0
  22. package/dist/components/ClientBoxUploader.svelte.d.ts +19 -0
  23. package/dist/components/ClientBoxUploader.svelte.d.ts.map +1 -0
  24. package/dist/components/ClientDropboxUploader.svelte +60 -0
  25. package/dist/components/ClientDropboxUploader.svelte.d.ts +19 -0
  26. package/dist/components/ClientDropboxUploader.svelte.d.ts.map +1 -0
  27. package/dist/components/ClientGoogleDriveUploader.svelte +57 -0
  28. package/dist/components/ClientGoogleDriveUploader.svelte.d.ts +19 -0
  29. package/dist/components/ClientGoogleDriveUploader.svelte.d.ts.map +1 -0
  30. package/dist/components/ClientOneDriveUploader.svelte +60 -0
  31. package/dist/components/ClientOneDriveUploader.svelte.d.ts +19 -0
  32. package/dist/components/ClientOneDriveUploader.svelte.d.ts.map +1 -0
  33. package/dist/components/DefaultAddMoreIcon.svelte +11 -0
  34. package/dist/components/DefaultAddMoreIcon.svelte.d.ts +8 -0
  35. package/dist/components/DefaultAddMoreIcon.svelte.d.ts.map +1 -0
  36. package/dist/components/DefaultLoaderIcon.svelte +5 -0
  37. package/dist/components/DefaultLoaderIcon.svelte.d.ts +19 -0
  38. package/dist/components/DefaultLoaderIcon.svelte.d.ts.map +1 -0
  39. package/dist/components/DropboxUploader.svelte +17 -0
  40. package/dist/components/DropboxUploader.svelte.d.ts +19 -0
  41. package/dist/components/DropboxUploader.svelte.d.ts.map +1 -0
  42. package/dist/components/EmptyIcon.svelte +3 -0
  43. package/dist/components/EmptyIcon.svelte.d.ts +19 -0
  44. package/dist/components/EmptyIcon.svelte.d.ts.map +1 -0
  45. package/dist/components/FileHero.svelte +152 -0
  46. package/dist/components/FileHero.svelte.d.ts +8 -0
  47. package/dist/components/FileHero.svelte.d.ts.map +1 -0
  48. package/dist/components/FileIcon.svelte +23 -0
  49. package/dist/components/FileIcon.svelte.d.ts +8 -0
  50. package/dist/components/FileIcon.svelte.d.ts.map +1 -0
  51. package/dist/components/FileItem.svelte +95 -0
  52. package/dist/components/FileItem.svelte.d.ts +12 -0
  53. package/dist/components/FileItem.svelte.d.ts.map +1 -0
  54. package/dist/components/FileList.svelte +442 -0
  55. package/dist/components/FileList.svelte.d.ts +4 -0
  56. package/dist/components/FileList.svelte.d.ts.map +1 -0
  57. package/dist/components/FilePreview.svelte +218 -0
  58. package/dist/components/FilePreview.svelte.d.ts +17 -0
  59. package/dist/components/FilePreview.svelte.d.ts.map +1 -0
  60. package/dist/components/FilePreviewPortal.svelte +189 -0
  61. package/dist/components/FilePreviewPortal.svelte.d.ts +12 -0
  62. package/dist/components/FilePreviewPortal.svelte.d.ts.map +1 -0
  63. package/dist/components/FilePreviewThumbnail.svelte +87 -0
  64. package/dist/components/FilePreviewThumbnail.svelte.d.ts +17 -0
  65. package/dist/components/FilePreviewThumbnail.svelte.d.ts.map +1 -0
  66. package/dist/components/FileRow.svelte +192 -0
  67. package/dist/components/FileRow.svelte.d.ts +10 -0
  68. package/dist/components/FileRow.svelte.d.ts.map +1 -0
  69. package/dist/components/GoogleDriveUploader.svelte +17 -0
  70. package/dist/components/GoogleDriveUploader.svelte.d.ts +19 -0
  71. package/dist/components/GoogleDriveUploader.svelte.d.ts.map +1 -0
  72. package/dist/components/Icon.svelte +24 -0
  73. package/dist/components/Icon.svelte.d.ts +10 -0
  74. package/dist/components/Icon.svelte.d.ts.map +1 -0
  75. package/dist/components/Icons.d.ts +10 -0
  76. package/dist/components/Icons.d.ts.map +1 -0
  77. package/dist/components/Icons.js +9 -0
  78. package/dist/components/ImageEditorStub.svelte +3 -0
  79. package/dist/components/ImageEditorStub.svelte.d.ts +19 -0
  80. package/dist/components/ImageEditorStub.svelte.d.ts.map +1 -0
  81. package/dist/components/OneDriveUploader.svelte +17 -0
  82. package/dist/components/OneDriveUploader.svelte.d.ts +19 -0
  83. package/dist/components/OneDriveUploader.svelte.d.ts.map +1 -0
  84. package/dist/components/ScreenCaptureUploader.svelte +254 -0
  85. package/dist/components/ScreenCaptureUploader.svelte.d.ts +4 -0
  86. package/dist/components/ScreenCaptureUploader.svelte.d.ts.map +1 -0
  87. package/dist/components/ServerModeDriveUploader.svelte +250 -0
  88. package/dist/components/ServerModeDriveUploader.svelte.d.ts +10 -0
  89. package/dist/components/ServerModeDriveUploader.svelte.d.ts.map +1 -0
  90. package/dist/components/SourceSelector.svelte +292 -0
  91. package/dist/components/SourceSelector.svelte.d.ts +19 -0
  92. package/dist/components/SourceSelector.svelte.d.ts.map +1 -0
  93. package/dist/components/SourceView.svelte +100 -0
  94. package/dist/components/SourceView.svelte.d.ts +4 -0
  95. package/dist/components/SourceView.svelte.d.ts.map +1 -0
  96. package/dist/components/TrashIcon.svelte +11 -0
  97. package/dist/components/TrashIcon.svelte.d.ts +8 -0
  98. package/dist/components/TrashIcon.svelte.d.ts.map +1 -0
  99. package/dist/components/UploaderPanel.svelte +363 -0
  100. package/dist/components/UploaderPanel.svelte.d.ts +4 -0
  101. package/dist/components/UploaderPanel.svelte.d.ts.map +1 -0
  102. package/dist/components/UrlUploader.svelte +71 -0
  103. package/dist/components/UrlUploader.svelte.d.ts +4 -0
  104. package/dist/components/UrlUploader.svelte.d.ts.map +1 -0
  105. package/dist/components/icons/AudioIcon.svelte +5 -0
  106. package/dist/components/icons/AudioIcon.svelte.d.ts +7 -0
  107. package/dist/components/icons/AudioIcon.svelte.d.ts.map +1 -0
  108. package/dist/components/icons/BoxIcon.svelte +5 -0
  109. package/dist/components/icons/BoxIcon.svelte.d.ts +7 -0
  110. package/dist/components/icons/BoxIcon.svelte.d.ts.map +1 -0
  111. package/dist/components/icons/CameraIcon.svelte +5 -0
  112. package/dist/components/icons/CameraIcon.svelte.d.ts +7 -0
  113. package/dist/components/icons/CameraIcon.svelte.d.ts.map +1 -0
  114. package/dist/components/icons/DropboxIcon.svelte +5 -0
  115. package/dist/components/icons/DropboxIcon.svelte.d.ts +7 -0
  116. package/dist/components/icons/DropboxIcon.svelte.d.ts.map +1 -0
  117. package/dist/components/icons/GoogleDriveIcon.svelte +5 -0
  118. package/dist/components/icons/GoogleDriveIcon.svelte.d.ts +7 -0
  119. package/dist/components/icons/GoogleDriveIcon.svelte.d.ts.map +1 -0
  120. package/dist/components/icons/LinkIcon.svelte +5 -0
  121. package/dist/components/icons/LinkIcon.svelte.d.ts +7 -0
  122. package/dist/components/icons/LinkIcon.svelte.d.ts.map +1 -0
  123. package/dist/components/icons/MyDeviceIcon.svelte +5 -0
  124. package/dist/components/icons/MyDeviceIcon.svelte.d.ts +7 -0
  125. package/dist/components/icons/MyDeviceIcon.svelte.d.ts.map +1 -0
  126. package/dist/components/icons/OneDriveIcon.svelte +5 -0
  127. package/dist/components/icons/OneDriveIcon.svelte.d.ts +7 -0
  128. package/dist/components/icons/OneDriveIcon.svelte.d.ts.map +1 -0
  129. package/dist/components/icons/ScreenCaptureIcon.svelte +5 -0
  130. package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts +7 -0
  131. package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts.map +1 -0
  132. package/dist/components/shared/DriveAuthFallback.svelte +60 -0
  133. package/dist/components/shared/DriveAuthFallback.svelte.d.ts +12 -0
  134. package/dist/components/shared/DriveAuthFallback.svelte.d.ts.map +1 -0
  135. package/dist/components/shared/DriveBrowser.svelte +209 -0
  136. package/dist/components/shared/DriveBrowser.svelte.d.ts +25 -0
  137. package/dist/components/shared/DriveBrowser.svelte.d.ts.map +1 -0
  138. package/dist/components/shared/DriveBrowserHeader.svelte +191 -0
  139. package/dist/components/shared/DriveBrowserHeader.svelte.d.ts +14 -0
  140. package/dist/components/shared/DriveBrowserHeader.svelte.d.ts.map +1 -0
  141. package/dist/components/shared/DriveBrowserIcon.svelte +39 -0
  142. package/dist/components/shared/DriveBrowserIcon.svelte.d.ts +8 -0
  143. package/dist/components/shared/DriveBrowserIcon.svelte.d.ts.map +1 -0
  144. package/dist/components/shared/DriveBrowserItem.svelte +63 -0
  145. package/dist/components/shared/DriveBrowserItem.svelte.d.ts +10 -0
  146. package/dist/components/shared/DriveBrowserItem.svelte.d.ts.map +1 -0
  147. package/dist/components/shared/FileSuccessCheck.svelte +47 -0
  148. package/dist/components/shared/FileSuccessCheck.svelte.d.ts +10 -0
  149. package/dist/components/shared/FileSuccessCheck.svelte.d.ts.map +1 -0
  150. package/dist/components/shared/ProgressBar.svelte +81 -0
  151. package/dist/components/shared/ProgressBar.svelte.d.ts +10 -0
  152. package/dist/components/shared/ProgressBar.svelte.d.ts.map +1 -0
  153. package/dist/components/shared/SourceViewContainer.svelte +27 -0
  154. package/dist/components/shared/SourceViewContainer.svelte.d.ts +10 -0
  155. package/dist/components/shared/SourceViewContainer.svelte.d.ts.map +1 -0
  156. package/dist/components/shared/UploaderHeader.svelte +156 -0
  157. package/dist/components/shared/UploaderHeader.svelte.d.ts +13 -0
  158. package/dist/components/shared/UploaderHeader.svelte.d.ts.map +1 -0
  159. package/dist/composables/use-tiles-per-row.d.ts +19 -0
  160. package/dist/composables/use-tiles-per-row.d.ts.map +1 -0
  161. package/dist/composables/use-tiles-per-row.js +30 -0
  162. package/dist/composables/useBox.d.ts +28 -0
  163. package/dist/composables/useBox.d.ts.map +1 -0
  164. package/dist/composables/useBox.js +61 -0
  165. package/dist/composables/useCameraUploader.d.ts +23 -0
  166. package/dist/composables/useCameraUploader.d.ts.map +1 -0
  167. package/dist/composables/useCameraUploader.js +114 -0
  168. package/dist/composables/useDropbox.d.ts +28 -0
  169. package/dist/composables/useDropbox.d.ts.map +1 -0
  170. package/dist/composables/useDropbox.js +61 -0
  171. package/dist/composables/useFetchFileByUrl.d.ts +9 -0
  172. package/dist/composables/useFetchFileByUrl.d.ts.map +1 -0
  173. package/dist/composables/useFetchFileByUrl.js +33 -0
  174. package/dist/composables/useGoogleDrive.d.ts +28 -0
  175. package/dist/composables/useGoogleDrive.d.ts.map +1 -0
  176. package/dist/composables/useGoogleDrive.js +65 -0
  177. package/dist/composables/useOneDrive.d.ts +29 -0
  178. package/dist/composables/useOneDrive.d.ts.map +1 -0
  179. package/dist/composables/useOneDrive.js +64 -0
  180. package/dist/composables/useSSEProcessing.d.ts +20 -0
  181. package/dist/composables/useSSEProcessing.d.ts.map +1 -0
  182. package/dist/composables/useSSEProcessing.js +17 -0
  183. package/dist/composables/useServerModeDrive.d.ts +17 -0
  184. package/dist/composables/useServerModeDrive.d.ts.map +1 -0
  185. package/dist/composables/useServerModeDrive.js +33 -0
  186. package/dist/composables/useSourceSelector.d.ts +13 -0
  187. package/dist/composables/useSourceSelector.d.ts.map +1 -0
  188. package/dist/composables/useSourceSelector.js +36 -0
  189. package/dist/composables/useUploaderPanel.d.ts +12 -0
  190. package/dist/composables/useUploaderPanel.d.ts.map +1 -0
  191. package/dist/composables/useUploaderPanel.js +43 -0
  192. package/dist/context/create-uploader-context.d.ts +4 -0
  193. package/dist/context/create-uploader-context.d.ts.map +1 -0
  194. package/dist/context/create-uploader-context.js +324 -0
  195. package/dist/context/source-view-header-extra.d.ts +14 -0
  196. package/dist/context/source-view-header-extra.d.ts.map +1 -0
  197. package/dist/context/source-view-header-extra.js +41 -0
  198. package/dist/context/uploader-context.d.ts +109 -0
  199. package/dist/context/uploader-context.d.ts.map +1 -0
  200. package/dist/context/uploader-context.js +96 -0
  201. package/dist/index.d.ts +10 -0
  202. package/dist/index.d.ts.map +1 -0
  203. package/dist/index.js +5 -0
  204. package/dist/lib/constants.d.ts +13 -0
  205. package/dist/lib/constants.d.ts.map +1 -0
  206. package/dist/lib/constants.js +67 -0
  207. package/dist/lib/to-readable.d.ts +14 -0
  208. package/dist/lib/to-readable.d.ts.map +1 -0
  209. package/dist/lib/to-readable.js +15 -0
  210. package/dist/lib/view-mode.d.ts +24 -0
  211. package/dist/lib/view-mode.d.ts.map +1 -0
  212. package/dist/lib/view-mode.js +31 -0
  213. package/dist/shared/types.d.ts +15 -0
  214. package/dist/shared/types.d.ts.map +1 -0
  215. package/dist/shared/types.js +1 -0
  216. package/dist/styles.d.ts +4 -0
  217. package/dist/tailwind-prefixed.css +2479 -0
  218. package/dist/tailwind.css +74 -0
  219. package/dist/use-upup-upload.d.ts +38 -0
  220. package/dist/use-upup-upload.d.ts.map +1 -0
  221. package/dist/use-upup-upload.js +81 -0
  222. package/package.json +101 -0
@@ -0,0 +1,43 @@
1
+ import { onMount, onDestroy } from 'svelte';
2
+ import { derived } from 'svelte/store';
3
+ import { DragDropController } from '@useupup/core/internal';
4
+ import { useUploaderFiles, useUploaderOptions, useUploaderRuntime, useUploaderView, } from '../context/uploader-context';
5
+ import { toReadable } from '../lib/to-readable';
6
+ export default function useUploaderPanel() {
7
+ const { core, orchestrator } = useUploaderRuntime();
8
+ const { setFiles } = useUploaderFiles();
9
+ const { flagDriveDropRejected } = useUploaderView();
10
+ const options = useUploaderOptions();
11
+ const { disableDragDrop, isProcessing, folderUploadAllowDrop } = options;
12
+ if (!core || !orchestrator)
13
+ throw new Error('useUploaderPanel must be used inside an initialized <UpupUploader />');
14
+ const controller = new DragDropController({
15
+ core,
16
+ orchestrator,
17
+ setFiles,
18
+ // The file list derives from the orchestrator snapshot — derive the
19
+ // border's file count from the same source so it stays in lockstep.
20
+ filesSize: () => orchestrator.getSnapshot().files.size,
21
+ options: () => options,
22
+ props: () => ({ disableDragDrop, isProcessing, folderUploadAllowDrop }),
23
+ onReadonlyDropRejected: source => {
24
+ flagDriveDropRejected(source);
25
+ },
26
+ });
27
+ const state = toReadable(controller);
28
+ onMount(() => {
29
+ controller.init();
30
+ });
31
+ onDestroy(() => {
32
+ controller.destroy();
33
+ });
34
+ return {
35
+ isDragging: derived(state, $s => $s.isDragging),
36
+ absoluteIsDragging: derived(state, $s => $s.absoluteIsDragging),
37
+ absoluteHasBorder: derived(state, $s => $s.absoluteHasBorder),
38
+ handleDragOver: controller.handleDragOver.bind(controller),
39
+ handleDragLeave: controller.handleDragLeave.bind(controller),
40
+ handleDrop: controller.handleDrop.bind(controller),
41
+ handlePaste: controller.handlePaste.bind(controller),
42
+ };
43
+ }
@@ -0,0 +1,4 @@
1
+ import type { UploaderProps } from '../shared/types';
2
+ import type { IUploaderContext } from './uploader-context';
3
+ export declare function createUploaderContext(props: UploaderProps): IUploaderContext;
4
+ //# sourceMappingURL=create-uploader-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-uploader-context.d.ts","sourceRoot":"","sources":["../../src/context/create-uploader-context.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAqB1D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,gBAAgB,CA6Y5E"}
@@ -0,0 +1,324 @@
1
+ import { onMount, onDestroy } from 'svelte';
2
+ import { derived } from 'svelte/store';
3
+ import { normalizeUploaderOptions, createUploaderController, } from '@useupup/core/internal';
4
+ import { useUpupUpload } from '../use-upup-upload';
5
+ import { useSSEProcessing } from '../composables/useSSEProcessing';
6
+ import { toReadable } from '../lib/to-readable';
7
+ import EmptyIcon from '../components/EmptyIcon.svelte';
8
+ import TrashIcon from '../components/TrashIcon.svelte';
9
+ import DefaultAddMoreIcon from '../components/DefaultAddMoreIcon.svelte';
10
+ const EMPTY_STYLE = {};
11
+ /** Read-only drive provider → flattened i18n label key (the human provider name
12
+ * for the drop-rejection toast). Typed `Record<CloudProvider, keyof
13
+ * UiTranslations>` so the compiler enforces exhaustiveness against the same
14
+ * drive-source union core's DragDropController gates on. */
15
+ const DRIVE_SOURCE_LABEL_KEY = {
16
+ googleDrive: 'googleDrive',
17
+ oneDrive: 'oneDrive',
18
+ dropbox: 'dropbox',
19
+ box: 'box',
20
+ };
21
+ export function createUploaderContext(props) {
22
+ // ── Destructure props with defaults ──────────────────────────
23
+ const { allowedFileTypes: acceptProp = '*', mini = false, animations = true, isProcessing = false, allowPreview = true, folderUpload, showBranding = true, quietCompletion = false, disableDragDrop = false, className, style, maxFileSize: maxFileSizeProp, maxFiles, imageCompression = false, thumbnailGenerator = false, checksumVerification = false, webWorker, heicConversion = false, stripExifData = false, contentDeduplication = false, crashRecovery = false,
24
+ // No destructure default: `undefined` must reach core so its default-on
25
+ // network awareness applies; only an explicit `false` opts out.
26
+ networkAware, sources, onError: errorHandler, onWarn: warningHandler, icons = {}, i18n, onIntegrationClick = () => { }, onFileClick = () => { }, onFileRemoved: onFileRemovedProp, onStatusChange, onFilesDragOver = () => { }, onFilesDragLeave = () => { }, onFilesDrop = () => { }, onFileTypeMismatch = () => { }, onBeforeFileAdded, onRestrictionFailed, enablePaste = false, autoUpload = false, maxConcurrentUploads, imageEditor: imageEditorProp, onUploadStart = () => { }, onFileUploadStart = () => { }, onFileUploadProgress = () => { }, onFilesUploadProgress = () => { }, onFileUploadComplete = () => { }, onFilesUploadComplete = () => { }, onUploadComplete = () => { }, onFilesSelected = () => { }, onDoneClicked = () => { }, onPrepareFiles, provider, mode: modeProp, uploadEndpoint, serverUrl, cloudDrives, metadata, cors, maxRetries, resumable, processingEndpoint, onFileProcessed, processingTimeout, } = props;
27
+ function onError(message) {
28
+ errorHandler?.(message);
29
+ }
30
+ function onWarn(message) {
31
+ warningHandler?.(message);
32
+ }
33
+ // ── Build factory-compatible options object ──────────────────
34
+ // UploaderProps.allowedFileTypes is string | string[] | undefined;
35
+ // UploaderControllerOptions.allowedFileTypes is string | undefined.
36
+ // normalizeUploaderOptions handles both via join cast.
37
+ const factoryOptions = {
38
+ provider,
39
+ mode: modeProp,
40
+ sources: sources,
41
+ uploadEndpoint,
42
+ serverUrl,
43
+ maxFiles,
44
+ theme: props.theme,
45
+ folderUpload,
46
+ cors,
47
+ cloudDrives,
48
+ imageCompression,
49
+ thumbnailGenerator,
50
+ checksumVerification,
51
+ webWorker,
52
+ heicConversion,
53
+ stripExifData,
54
+ contentDeduplication,
55
+ autoUpload,
56
+ maxConcurrentUploads,
57
+ crashRecovery,
58
+ networkAware,
59
+ allowedFileTypes: typeof acceptProp === 'string' ? acceptProp : acceptProp.join(','),
60
+ mini,
61
+ animations,
62
+ isProcessing,
63
+ allowPreview,
64
+ showBranding,
65
+ quietCompletion,
66
+ disableDragDrop,
67
+ className,
68
+ maxFileSize: maxFileSizeProp,
69
+ minFileSize: props.minFileSize,
70
+ maxTotalFileSize: props.maxTotalFileSize,
71
+ imageEditor: imageEditorProp,
72
+ metadata,
73
+ maxRetries,
74
+ resumable,
75
+ i18n,
76
+ onBeforeFileAdded,
77
+ onError: errorHandler,
78
+ onWarn: warningHandler,
79
+ onUploadStart,
80
+ onFileUploadStart,
81
+ onFileUploadProgress,
82
+ onFilesUploadProgress,
83
+ onFileUploadComplete,
84
+ onFilesUploadComplete,
85
+ onUploadComplete,
86
+ onFilesSelected,
87
+ onDoneClicked,
88
+ onPrepareFiles,
89
+ onFileRemoved: onFileRemovedProp,
90
+ onStatusChange,
91
+ onFileTypeMismatch,
92
+ onRestrictionFailed,
93
+ };
94
+ // ── Normalize options (pure) ─────────────────────────────────
95
+ const normalized = normalizeUploaderOptions(factoryOptions);
96
+ const { resolved } = normalized;
97
+ // ── Core (via useUpupUpload; owns core lifecycle) ────────────
98
+ const upload = useUpupUpload(normalized.coreOptions);
99
+ // ── SSE processing ──────────────────────────────────────────
100
+ const { connectSSE } = useSSEProcessing({
101
+ processingEndpoint,
102
+ onFileProcessed,
103
+ onError: err => {
104
+ onError(err.message);
105
+ },
106
+ processingTimeout,
107
+ });
108
+ // ── Uploader controller (created once, owns orchestrator/theme/plugins/commands) ──
109
+ const controller = createUploaderController({ core: upload.core, options: factoryOptions, normalized }, {
110
+ connectSSE: file => {
111
+ connectSSE(file);
112
+ },
113
+ });
114
+ controller.updateCallbacks({
115
+ onError,
116
+ onWarn,
117
+ onUploadStart,
118
+ onFileUploadStart,
119
+ onFileUploadProgress,
120
+ onFilesUploadProgress,
121
+ onFileUploadComplete,
122
+ onFilesUploadComplete,
123
+ onUploadComplete,
124
+ onFilesSelected,
125
+ onDoneClicked,
126
+ onPrepareFiles,
127
+ onFileRemoved: onFileRemovedProp,
128
+ onStatusChange,
129
+ onFileTypeMismatch,
130
+ onRestrictionFailed,
131
+ autoUpload,
132
+ });
133
+ // ── Subscribe to orchestrator state (toReadable handles sub/unsub) ──
134
+ const orchState = toReadable(controller.orchestrator);
135
+ // ── Subscribe to theme state (toReadable handles sub/unsub) ──
136
+ const themeState = toReadable(controller.theme);
137
+ // ── Subscribe to the transient-UI store (deferred removal / overlay / toast) ─
138
+ const transientState = toReadable(controller.transientUi);
139
+ // ── Subscribe to the motion gate (data-motion resolution) ────
140
+ const motionState = toReadable(controller.motionGate);
141
+ // Drop-rejection: core's DragDropController fires onReadonlyDropRejected with
142
+ // the drive FileSource; resolve its human provider label, then raise the
143
+ // toast (core store owns the 3s auto-clear).
144
+ function flagDriveDropRejected(source) {
145
+ const key = DRIVE_SOURCE_LABEL_KEY[source];
146
+ const label = key ? resolved.translations[key] : source;
147
+ controller.transientUi.flagDropRejected(label);
148
+ }
149
+ // ── Lifecycle via factory (idempotent init/destroy) ──────────
150
+ // controller.init() owns: orchestrator.init, theme.init, plugin registration,
151
+ // status-change dedup, crash recovery.
152
+ // controller.destroy() owns: orchestrator.destroy, theme.destroy, plugin cleanup.
153
+ // core lifecycle remains owned by useUpupUpload's onDestroy.
154
+ onMount(() => {
155
+ controller.init();
156
+ });
157
+ onDestroy(() => {
158
+ controller.destroy();
159
+ });
160
+ // ── Input ref: delegate to factory (Svelte bind:this registration) ──────
161
+ // UpupUploader.svelte: $effect(() => ctx.registerFileInput(inputEl))
162
+ // must keep these field names; bodies delegate to controller.*.
163
+ const registerFileInput = (el) => {
164
+ controller.registerFileInput(el);
165
+ };
166
+ const getFileInput = () => controller.getFileInput();
167
+ const openFilePicker = () => {
168
+ controller.openFilePicker();
169
+ };
170
+ // ── Icons resolution (framework-specific) ───────────────────
171
+ const resolvedIcons = {
172
+ ContainerAddMoreIcon: icons.ContainerAddMoreIcon ?? DefaultAddMoreIcon,
173
+ FileDeleteIcon: icons.FileDeleteIcon ?? TrashIcon,
174
+ CameraCaptureIcon: icons.CameraCaptureIcon ?? EmptyIcon,
175
+ CameraRotateIcon: icons.CameraRotateIcon ?? EmptyIcon,
176
+ CameraDeleteIcon: icons.CameraDeleteIcon ?? EmptyIcon,
177
+ LoaderIcon: icons.LoaderIcon ?? EmptyIcon,
178
+ };
179
+ const resolvedStyle = style ?? EMPTY_STYLE;
180
+ // ── Assemble IUploaderContext ────────────────────────────────────
181
+ return {
182
+ core: upload.core,
183
+ orchestrator: controller.orchestrator,
184
+ mode: resolved.mode,
185
+ serverUrl: resolved.serverUrl,
186
+ registerFileInput,
187
+ getFileInput,
188
+ openFilePicker,
189
+ // Reactive so consumers (SourceView/UploaderPanel/FileList) re-render when the
190
+ // active source changes.
191
+ activeSource: derived(orchState, $s => $s.activeSource),
192
+ setActiveSource: (source) => {
193
+ controller.commands.setActiveSource(source);
194
+ },
195
+ isAddingMore: derived(orchState, $s => $s.isAddingMore),
196
+ setIsAddingMore: (v) => {
197
+ controller.commands.setIsAddingMore(v);
198
+ },
199
+ viewMode: derived(orchState, $s => $s.viewMode),
200
+ setViewMode: (m) => {
201
+ controller.commands.setViewMode(m);
202
+ },
203
+ isOnline: derived(orchState, $s => $s.isOnline),
204
+ motionMode: motionState,
205
+ sourceOverlayOpen: derived(transientState, $s => $s.sourceOverlayOpen),
206
+ sourceOverlayClosing: derived(transientState, $s => $s.sourceOverlayClosing),
207
+ openSourceOverlay: () => {
208
+ controller.transientUi.openSourceOverlay();
209
+ },
210
+ closeSourceOverlay: () => {
211
+ controller.transientUi.closeSourceOverlay();
212
+ },
213
+ dropRejected: derived(transientState, $s => $s.dropRejected),
214
+ flagDriveDropRejected,
215
+ translations: resolved.translations,
216
+ translator: resolved.translator,
217
+ lang: resolved.lang,
218
+ dir: resolved.dir,
219
+ theme: {
220
+ // All theme fields stay reactive (mirroring React): ThemeStore
221
+ // recomputes tokens/resolved/slotOverrides/slots at init() and on OS
222
+ // dark/light change, so `themeMode:'system'` resolves live instead of
223
+ // freezing the construction-time (light) values.
224
+ themeMode: derived(themeState, $s => $s.themeMode),
225
+ isDark: derived(themeState, $s => $s.isDark),
226
+ tokens: derived(themeState, $s => $s.tokens),
227
+ resolved: derived(themeState, $s => $s.resolved),
228
+ slotOverrides: derived(themeState, $s => $s.slotOverrides),
229
+ slots: derived(themeState, $s => $s.slots),
230
+ },
231
+ setThemeConfig: config => {
232
+ controller.theme.setThemeConfig(config);
233
+ },
234
+ files: derived(orchState, $s => $s.files),
235
+ leavingFileIds: derived(transientState, $s => $s.leavingFileIds),
236
+ // ContextFiles.setFiles is fire-and-forget (`=> void`); route the async
237
+ // command's rejection to onError rather than floating the promise.
238
+ setFiles: (newFiles) => {
239
+ controller.commands
240
+ .handleSetSelectedFiles(newFiles)
241
+ .catch((error) => {
242
+ onError(error instanceof Error ? error.message : String(error));
243
+ });
244
+ },
245
+ uploadFiles: (newFiles) => controller.commands.uploadFiles(newFiles),
246
+ resetState: () => {
247
+ controller.commands.resetState();
248
+ },
249
+ replaceFiles: (newFiles) => {
250
+ controller.commands.replaceFiles(newFiles);
251
+ },
252
+ handleDone: () => {
253
+ controller.commands.handleDone();
254
+ },
255
+ handleCancel: () => {
256
+ controller.commands.handleCancel();
257
+ },
258
+ handlePause: () => {
259
+ controller.commands.handlePause();
260
+ },
261
+ handleResume: () => {
262
+ controller.commands.handleResume();
263
+ },
264
+ handleFileRemove: (fileId) => {
265
+ controller.commands.handleFileRemove(fileId);
266
+ },
267
+ editingFile: derived(orchState, $s => $s.editingFile),
268
+ openImageEditor: (file) => {
269
+ controller.commands.openImageEditor(file);
270
+ },
271
+ closeImageEditor: () => {
272
+ controller.commands.closeImageEditor();
273
+ },
274
+ saveImageEdit: (editedImageData, mimeType) => {
275
+ controller.commands.saveImageEdit(editedImageData, mimeType);
276
+ },
277
+ replaceFile: (fileId, newFile) => {
278
+ controller.commands.replaceFile(fileId, newFile);
279
+ },
280
+ cloudDrives: resolved.cloudDrives,
281
+ upload: {
282
+ totalProgress: derived(orchState, $s => $s.totalProgress),
283
+ filesProgressMap: derived(orchState, $s => $s.filesProgressMap),
284
+ startUpload: () => controller.commands.startUpload(),
285
+ retryUpload: (fileId) => controller.commands.retryUpload(fileId),
286
+ uploadStatus: derived(orchState, $s => $s.uploadStatus),
287
+ uploadError: derived(orchState, $s => $s.uploadError),
288
+ uploadErrorCode: derived(orchState, $s => $s.uploadErrorCode),
289
+ uploadSpeed: derived(orchState, $s => $s.uploadSpeed),
290
+ uploadEta: derived(orchState, $s => $s.uploadEta),
291
+ uploadedBytes: derived(orchState, $s => $s.uploadedBytes),
292
+ totalBytes: derived(orchState, $s => $s.totalBytes),
293
+ },
294
+ props: {
295
+ mini,
296
+ maxRetries,
297
+ resumable,
298
+ onError,
299
+ onIntegrationClick,
300
+ onFileClick,
301
+ onFilesDragOver,
302
+ onFilesDragLeave,
303
+ onFilesDrop,
304
+ onWarn,
305
+ enablePaste,
306
+ sources: resolved.sources,
307
+ allowedFileTypes: resolved.allowedFileTypes,
308
+ maxFileSize: resolved.maxFileSize,
309
+ limit: resolved.limit,
310
+ isProcessing,
311
+ allowPreview,
312
+ folderUploadAllowDrop: resolved.folderUploadAllowDrop,
313
+ folderPickerButtonVisible: resolved.folderPickerButtonVisible,
314
+ showBranding,
315
+ quietCompletion,
316
+ disableDragDrop,
317
+ className: className ?? '',
318
+ style: resolvedStyle,
319
+ multiple: resolved.multiple,
320
+ icons: resolvedIcons,
321
+ imageEditor: resolved.imageEditor,
322
+ },
323
+ };
324
+ }
@@ -0,0 +1,14 @@
1
+ import { type Writable } from 'svelte/store';
2
+ export declare function provideSourceViewHeaderExtra(): Writable<HTMLElement | null>;
3
+ export declare function useSourceViewHeaderExtra(): Writable<HTMLElement | null> | null;
4
+ /**
5
+ * Svelte action: relocate `node` into `target` (the portal). `node` is a
6
+ * `display:contents` wrapper so its children render as if they were direct
7
+ * children of the host — matching React's createPortal / Vue's <Teleport>,
8
+ * which insert the extras as direct siblings of the Back button.
9
+ */
10
+ export declare function portal(node: HTMLElement, target: HTMLElement | null): {
11
+ update(t: HTMLElement | null): void;
12
+ destroy(): void;
13
+ };
14
+ //# sourceMappingURL=source-view-header-extra.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-view-header-extra.d.ts","sourceRoot":"","sources":["../../src/context/source-view-header-extra.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAatD,wBAAgB,4BAA4B,IAAI,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,CAI3E;AAED,wBAAgB,wBAAwB,IAAI,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CAM9E;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAClB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,WAAW,GAAG,IAAI,GAC3B;IACC,MAAM,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAAA;IACnC,OAAO,IAAI,IAAI,CAAA;CAClB,CAaA"}
@@ -0,0 +1,41 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ import { writable } from 'svelte/store';
3
+ /**
4
+ * DOM host inside the SourceView header row, just before the Back button.
5
+ * A source view portals its right-side header extras into it (e.g. the drive
6
+ * browser's avatar + log out + separator) so account controls share the top
7
+ * row instead of occupying their own strip. The store holds null until the host
8
+ * span mounts; consumers guard their portal on it. Svelte has no <Teleport>, so
9
+ * the DOM-host + `portal` action below is the framework idiom mirroring React's
10
+ * SourceViewHeaderExtraContext / Vue's <Teleport>.
11
+ */
12
+ const SourceViewHeaderExtraKey = Symbol('upup-source-view-header-extra');
13
+ export function provideSourceViewHeaderExtra() {
14
+ const store = writable(null);
15
+ setContext(SourceViewHeaderExtraKey, store);
16
+ return store;
17
+ }
18
+ export function useSourceViewHeaderExtra() {
19
+ return (getContext(SourceViewHeaderExtraKey) ?? null);
20
+ }
21
+ /**
22
+ * Svelte action: relocate `node` into `target` (the portal). `node` is a
23
+ * `display:contents` wrapper so its children render as if they were direct
24
+ * children of the host — matching React's createPortal / Vue's <Teleport>,
25
+ * which insert the extras as direct siblings of the Back button.
26
+ */
27
+ export function portal(node, target) {
28
+ function mount(t) {
29
+ if (t)
30
+ t.appendChild(node);
31
+ }
32
+ mount(target);
33
+ return {
34
+ update(t) {
35
+ mount(t);
36
+ },
37
+ destroy() {
38
+ node.remove();
39
+ },
40
+ };
41
+ }
@@ -0,0 +1,109 @@
1
+ import type { Readable } from 'svelte/store';
2
+ import type { FileSource, UploadFile, UpupThemeMode, ResolvedImageEditorOptions, FilesProgressMap } from '@useupup/core';
3
+ import type { BaseContextUpload, BaseContextRuntime, BaseContextSource, BaseContextI18n, BaseContextFiles, BaseContextUploadControls, BaseContextView, BaseContextEditor, BaseContextTheme, MotionMode } from '@useupup/core/internal';
4
+ import { UploadStatus } from '@useupup/core';
5
+ import type { UploaderProps, UploaderIcons } from '../shared/types';
6
+ export { UploadStatus };
7
+ export type ContextUpload = Omit<BaseContextUpload, 'uploadStatus' | 'uploadError' | 'uploadErrorCode' | 'totalProgress' | 'filesProgressMap' | 'uploadSpeed' | 'uploadEta' | 'uploadedBytes' | 'totalBytes'> & {
8
+ uploadStatus: Readable<UploadStatus>;
9
+ uploadError: Readable<string | undefined>;
10
+ uploadErrorCode: Readable<string | undefined>;
11
+ totalProgress: Readable<number>;
12
+ filesProgressMap: Readable<FilesProgressMap>;
13
+ uploadSpeed: Readable<number>;
14
+ uploadEta: Readable<number>;
15
+ uploadedBytes: Readable<number>;
16
+ totalBytes: Readable<number>;
17
+ };
18
+ export type ContextRuntime = Omit<BaseContextRuntime, 'isOnline'> & {
19
+ /** Register the hidden file <input> (Svelte `bind:this`) so openFilePicker can click it. */
20
+ registerFileInput: (el: HTMLInputElement | null) => void;
21
+ /** Read the registered hidden file <input> (to toggle webkitdirectory/directory or reset value). */
22
+ getFileInput: () => HTMLInputElement | null;
23
+ isOnline: Readable<boolean>;
24
+ /** Resolved `data-motion` value ('on' | 'off') from the core motion gate. */
25
+ motionMode: Readable<MotionMode>;
26
+ };
27
+ export type ContextSource = Omit<BaseContextSource, 'activeSource'> & {
28
+ activeSource: Readable<FileSource | undefined>;
29
+ };
30
+ export type ContextI18n = BaseContextI18n;
31
+ export type ContextFiles = Omit<BaseContextFiles, 'files'> & {
32
+ files: Readable<Map<string, UploadFile>>;
33
+ /** Transient: file ids currently playing their exit animation. Read by
34
+ * FileList (hero) and FileItem (cards) to render `upup-fx-exit`. Sourced
35
+ * from the core transient-UI store (deferred removal). */
36
+ leavingFileIds: Readable<ReadonlySet<string>>;
37
+ };
38
+ export type ContextUploadControls = Omit<BaseContextUploadControls, 'upload'> & {
39
+ upload: ContextUpload;
40
+ };
41
+ export type ContextView = Omit<BaseContextView, 'isAddingMore' | 'viewMode'> & {
42
+ isAddingMore: Readable<boolean>;
43
+ viewMode: Readable<'grid' | 'list'>;
44
+ /** Add-more source overlay: source surface mounted above the dimmed,
45
+ * still-mounted file list. Sourced from the core transient-UI store. */
46
+ sourceOverlayOpen: Readable<boolean>;
47
+ /** Overlay is playing its reverse close-slide before it unmounts. */
48
+ sourceOverlayClosing: Readable<boolean>;
49
+ openSourceOverlay: () => void;
50
+ closeSourceOverlay: () => void;
51
+ /** Human provider label whose read-only picker just rejected an OS drop —
52
+ * drives the drop-rejection toast. Null when no rejection is showing.
53
+ * Auto-clears via the core transient-UI store's 3s window. */
54
+ dropRejected: Readable<string | null>;
55
+ /** Raise the drop-rejection toast for a read-only drive source (resolves the
56
+ * provider label, then flags the core store). Wired to core's
57
+ * DragDropController.onReadonlyDropRejected. */
58
+ flagDriveDropRejected: (source: FileSource) => void;
59
+ };
60
+ export type ContextEditor = Omit<BaseContextEditor, 'editingFile'> & {
61
+ editingFile: Readable<UploadFile | null>;
62
+ };
63
+ export type ContextTheme = Omit<BaseContextTheme, 'themeMode' | 'isDark' | 'tokens' | 'resolved' | 'slotOverrides' | 'slots'> & {
64
+ themeMode: Readable<Exclude<UpupThemeMode, 'system'>>;
65
+ isDark: Readable<boolean>;
66
+ tokens: Readable<BaseContextTheme['tokens']>;
67
+ resolved: Readable<BaseContextTheme['resolved']>;
68
+ slotOverrides: Readable<BaseContextTheme['slotOverrides']>;
69
+ slots: Readable<BaseContextTheme['slots']>;
70
+ };
71
+ type RequiredDefined<T, K extends keyof T> = {
72
+ [P in K]-?: NonNullable<T[P]>;
73
+ };
74
+ export type ContextProps = RequiredDefined<UploaderProps, 'sources' | 'isProcessing' | 'allowPreview' | 'mini' | 'onFileClick' | 'onIntegrationClick' | 'onFilesDragOver' | 'onFilesDragLeave' | 'onFilesDrop' | 'onWarn' | 'enablePaste' | 'onError' | 'showBranding' | 'quietCompletion' | 'className' | 'style' | 'disableDragDrop'> & {
75
+ maxFileSize?: UploaderProps['maxFileSize'];
76
+ maxRetries?: UploaderProps['maxRetries'];
77
+ resumable?: UploaderProps['resumable'];
78
+ } & {
79
+ allowedFileTypes: string;
80
+ limit: number;
81
+ folderUploadAllowDrop: boolean;
82
+ folderPickerButtonVisible: boolean;
83
+ multiple: boolean;
84
+ icons: Required<UploaderIcons>;
85
+ imageEditor: ResolvedImageEditorOptions;
86
+ };
87
+ export interface IUploaderContext extends ContextRuntime, ContextSource, ContextI18n, ContextFiles, ContextUploadControls, ContextView, ContextEditor {
88
+ props: ContextProps;
89
+ theme: ContextTheme;
90
+ /**
91
+ * Re-resolve the live ThemeStore when the `theme` prop changes after mount
92
+ * (mirrors React's `controller.theme.setThemeConfig(theme)` effect). The
93
+ * store short-circuits on a structurally-equal config, so an inlined object
94
+ * literal per render does not loop.
95
+ */
96
+ setThemeConfig: (config: UploaderProps['theme']) => void;
97
+ }
98
+ export declare function provideUploaderContext(value: IUploaderContext): void;
99
+ export declare const useUploaderContext: () => IUploaderContext;
100
+ export declare const useUploaderRuntime: () => ContextRuntime;
101
+ export declare const useUploaderSource: () => ContextSource;
102
+ export declare const useUploaderI18n: () => ContextI18n;
103
+ export declare const useUploaderFiles: () => ContextFiles;
104
+ export declare const useUploaderUploadControls: () => ContextUploadControls;
105
+ export declare const useUploaderView: () => ContextView;
106
+ export declare const useUploaderEditor: () => ContextEditor;
107
+ export declare const useUploaderOptions: () => ContextProps;
108
+ export declare const useUploaderTheme: () => ContextTheme;
109
+ //# sourceMappingURL=uploader-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader-context.d.ts","sourceRoot":"","sources":["../../src/context/uploader-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ import { UploadStatus } from '@useupup/core';
3
+ export { UploadStatus };
4
+ // ─── Keys ───────────────────────────────────────────────────
5
+ const RuntimeKey = Symbol('upup-runtime');
6
+ const SourceKey = Symbol('upup-source');
7
+ const I18nKey = Symbol('upup-i18n');
8
+ const FilesKey = Symbol('upup-files');
9
+ const UploadControlsKey = Symbol('upup-upload-controls');
10
+ const ViewKey = Symbol('upup-view');
11
+ const EditorKey = Symbol('upup-editor');
12
+ const OptionsKey = Symbol('upup-options');
13
+ const ThemeKey = Symbol('upup-theme');
14
+ const RootKey = Symbol('upup-root');
15
+ // ─── Provider ───────────────────────────────────────────────
16
+ export function provideUploaderContext(value) {
17
+ setContext(RootKey, value);
18
+ setContext(RuntimeKey, {
19
+ core: value.core,
20
+ orchestrator: value.orchestrator,
21
+ mode: value.mode,
22
+ serverUrl: value.serverUrl,
23
+ registerFileInput: value.registerFileInput,
24
+ getFileInput: value.getFileInput,
25
+ openFilePicker: value.openFilePicker,
26
+ isOnline: value.isOnline,
27
+ motionMode: value.motionMode,
28
+ });
29
+ setContext(SourceKey, {
30
+ activeSource: value.activeSource,
31
+ setActiveSource: value.setActiveSource,
32
+ cloudDrives: value.cloudDrives,
33
+ });
34
+ setContext(I18nKey, {
35
+ translations: value.translations,
36
+ translator: value.translator,
37
+ lang: value.lang,
38
+ dir: value.dir,
39
+ });
40
+ setContext(FilesKey, {
41
+ files: value.files,
42
+ leavingFileIds: value.leavingFileIds,
43
+ setFiles: value.setFiles,
44
+ replaceFiles: value.replaceFiles,
45
+ resetState: value.resetState,
46
+ uploadFiles: value.uploadFiles,
47
+ handleFileRemove: value.handleFileRemove,
48
+ });
49
+ setContext(UploadControlsKey, {
50
+ upload: value.upload,
51
+ handleDone: value.handleDone,
52
+ handleCancel: value.handleCancel,
53
+ handlePause: value.handlePause,
54
+ handleResume: value.handleResume,
55
+ });
56
+ setContext(ViewKey, {
57
+ isAddingMore: value.isAddingMore,
58
+ setIsAddingMore: value.setIsAddingMore,
59
+ viewMode: value.viewMode,
60
+ setViewMode: value.setViewMode,
61
+ sourceOverlayOpen: value.sourceOverlayOpen,
62
+ sourceOverlayClosing: value.sourceOverlayClosing,
63
+ openSourceOverlay: value.openSourceOverlay,
64
+ closeSourceOverlay: value.closeSourceOverlay,
65
+ dropRejected: value.dropRejected,
66
+ flagDriveDropRejected: value.flagDriveDropRejected,
67
+ });
68
+ setContext(EditorKey, {
69
+ editingFile: value.editingFile,
70
+ openImageEditor: value.openImageEditor,
71
+ closeImageEditor: value.closeImageEditor,
72
+ saveImageEdit: value.saveImageEdit,
73
+ replaceFile: value.replaceFile,
74
+ });
75
+ setContext(OptionsKey, value.props);
76
+ setContext(ThemeKey, value.theme);
77
+ }
78
+ // ─── Consumers (throw outside <UpupUploader />) ─────────────
79
+ // `value` carries T so the generic relates the passed-in context to the return
80
+ // (a real generic, not a disguised assertion): each consumer reads its own
81
+ // typed getContext and this asserts presence at the <UpupUploader /> boundary.
82
+ function read(name, value) {
83
+ if (value === undefined)
84
+ throw new Error(`${name} must be used inside <UpupUploader />`);
85
+ return value;
86
+ }
87
+ export const useUploaderContext = () => read('useUploaderContext', getContext(RootKey));
88
+ export const useUploaderRuntime = () => read('useUploaderRuntime', getContext(RuntimeKey));
89
+ export const useUploaderSource = () => read('useUploaderSource', getContext(SourceKey));
90
+ export const useUploaderI18n = () => read('useUploaderI18n', getContext(I18nKey));
91
+ export const useUploaderFiles = () => read('useUploaderFiles', getContext(FilesKey));
92
+ export const useUploaderUploadControls = () => read('useUploaderUploadControls', getContext(UploadControlsKey));
93
+ export const useUploaderView = () => read('useUploaderView', getContext(ViewKey));
94
+ export const useUploaderEditor = () => read('useUploaderEditor', getContext(EditorKey));
95
+ export const useUploaderOptions = () => read('useUploaderOptions', getContext(OptionsKey));
96
+ export const useUploaderTheme = () => read('useUploaderTheme', getContext(ThemeKey));