@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.
- package/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/UpupUploader.svelte +96 -0
- package/dist/UpupUploader.svelte.d.ts +5 -0
- package/dist/UpupUploader.svelte.d.ts.map +1 -0
- package/dist/assets/logos.d.ts +5 -0
- package/dist/assets/logos.d.ts.map +1 -0
- package/dist/assets/logos.js +4 -0
- package/dist/components/AudioUploader.svelte +220 -0
- package/dist/components/AudioUploader.svelte.d.ts +4 -0
- package/dist/components/AudioUploader.svelte.d.ts.map +1 -0
- package/dist/components/AudioWaveform.svelte +72 -0
- package/dist/components/AudioWaveform.svelte.d.ts +7 -0
- package/dist/components/AudioWaveform.svelte.d.ts.map +1 -0
- package/dist/components/BoxUploader.svelte +17 -0
- package/dist/components/BoxUploader.svelte.d.ts +19 -0
- package/dist/components/BoxUploader.svelte.d.ts.map +1 -0
- package/dist/components/CameraUploader.svelte +140 -0
- package/dist/components/CameraUploader.svelte.d.ts +4 -0
- package/dist/components/CameraUploader.svelte.d.ts.map +1 -0
- package/dist/components/ClientBoxUploader.svelte +60 -0
- package/dist/components/ClientBoxUploader.svelte.d.ts +19 -0
- package/dist/components/ClientBoxUploader.svelte.d.ts.map +1 -0
- package/dist/components/ClientDropboxUploader.svelte +60 -0
- package/dist/components/ClientDropboxUploader.svelte.d.ts +19 -0
- package/dist/components/ClientDropboxUploader.svelte.d.ts.map +1 -0
- package/dist/components/ClientGoogleDriveUploader.svelte +57 -0
- package/dist/components/ClientGoogleDriveUploader.svelte.d.ts +19 -0
- package/dist/components/ClientGoogleDriveUploader.svelte.d.ts.map +1 -0
- package/dist/components/ClientOneDriveUploader.svelte +60 -0
- package/dist/components/ClientOneDriveUploader.svelte.d.ts +19 -0
- package/dist/components/ClientOneDriveUploader.svelte.d.ts.map +1 -0
- package/dist/components/DefaultAddMoreIcon.svelte +11 -0
- package/dist/components/DefaultAddMoreIcon.svelte.d.ts +8 -0
- package/dist/components/DefaultAddMoreIcon.svelte.d.ts.map +1 -0
- package/dist/components/DefaultLoaderIcon.svelte +5 -0
- package/dist/components/DefaultLoaderIcon.svelte.d.ts +19 -0
- package/dist/components/DefaultLoaderIcon.svelte.d.ts.map +1 -0
- package/dist/components/DropboxUploader.svelte +17 -0
- package/dist/components/DropboxUploader.svelte.d.ts +19 -0
- package/dist/components/DropboxUploader.svelte.d.ts.map +1 -0
- package/dist/components/EmptyIcon.svelte +3 -0
- package/dist/components/EmptyIcon.svelte.d.ts +19 -0
- package/dist/components/EmptyIcon.svelte.d.ts.map +1 -0
- package/dist/components/FileHero.svelte +152 -0
- package/dist/components/FileHero.svelte.d.ts +8 -0
- package/dist/components/FileHero.svelte.d.ts.map +1 -0
- package/dist/components/FileIcon.svelte +23 -0
- package/dist/components/FileIcon.svelte.d.ts +8 -0
- package/dist/components/FileIcon.svelte.d.ts.map +1 -0
- package/dist/components/FileItem.svelte +95 -0
- package/dist/components/FileItem.svelte.d.ts +12 -0
- package/dist/components/FileItem.svelte.d.ts.map +1 -0
- package/dist/components/FileList.svelte +442 -0
- package/dist/components/FileList.svelte.d.ts +4 -0
- package/dist/components/FileList.svelte.d.ts.map +1 -0
- package/dist/components/FilePreview.svelte +218 -0
- package/dist/components/FilePreview.svelte.d.ts +17 -0
- package/dist/components/FilePreview.svelte.d.ts.map +1 -0
- package/dist/components/FilePreviewPortal.svelte +189 -0
- package/dist/components/FilePreviewPortal.svelte.d.ts +12 -0
- package/dist/components/FilePreviewPortal.svelte.d.ts.map +1 -0
- package/dist/components/FilePreviewThumbnail.svelte +87 -0
- package/dist/components/FilePreviewThumbnail.svelte.d.ts +17 -0
- package/dist/components/FilePreviewThumbnail.svelte.d.ts.map +1 -0
- package/dist/components/FileRow.svelte +192 -0
- package/dist/components/FileRow.svelte.d.ts +10 -0
- package/dist/components/FileRow.svelte.d.ts.map +1 -0
- package/dist/components/GoogleDriveUploader.svelte +17 -0
- package/dist/components/GoogleDriveUploader.svelte.d.ts +19 -0
- package/dist/components/GoogleDriveUploader.svelte.d.ts.map +1 -0
- package/dist/components/Icon.svelte +24 -0
- package/dist/components/Icon.svelte.d.ts +10 -0
- package/dist/components/Icon.svelte.d.ts.map +1 -0
- package/dist/components/Icons.d.ts +10 -0
- package/dist/components/Icons.d.ts.map +1 -0
- package/dist/components/Icons.js +9 -0
- package/dist/components/ImageEditorStub.svelte +3 -0
- package/dist/components/ImageEditorStub.svelte.d.ts +19 -0
- package/dist/components/ImageEditorStub.svelte.d.ts.map +1 -0
- package/dist/components/OneDriveUploader.svelte +17 -0
- package/dist/components/OneDriveUploader.svelte.d.ts +19 -0
- package/dist/components/OneDriveUploader.svelte.d.ts.map +1 -0
- package/dist/components/ScreenCaptureUploader.svelte +254 -0
- package/dist/components/ScreenCaptureUploader.svelte.d.ts +4 -0
- package/dist/components/ScreenCaptureUploader.svelte.d.ts.map +1 -0
- package/dist/components/ServerModeDriveUploader.svelte +250 -0
- package/dist/components/ServerModeDriveUploader.svelte.d.ts +10 -0
- package/dist/components/ServerModeDriveUploader.svelte.d.ts.map +1 -0
- package/dist/components/SourceSelector.svelte +292 -0
- package/dist/components/SourceSelector.svelte.d.ts +19 -0
- package/dist/components/SourceSelector.svelte.d.ts.map +1 -0
- package/dist/components/SourceView.svelte +100 -0
- package/dist/components/SourceView.svelte.d.ts +4 -0
- package/dist/components/SourceView.svelte.d.ts.map +1 -0
- package/dist/components/TrashIcon.svelte +11 -0
- package/dist/components/TrashIcon.svelte.d.ts +8 -0
- package/dist/components/TrashIcon.svelte.d.ts.map +1 -0
- package/dist/components/UploaderPanel.svelte +363 -0
- package/dist/components/UploaderPanel.svelte.d.ts +4 -0
- package/dist/components/UploaderPanel.svelte.d.ts.map +1 -0
- package/dist/components/UrlUploader.svelte +71 -0
- package/dist/components/UrlUploader.svelte.d.ts +4 -0
- package/dist/components/UrlUploader.svelte.d.ts.map +1 -0
- package/dist/components/icons/AudioIcon.svelte +5 -0
- package/dist/components/icons/AudioIcon.svelte.d.ts +7 -0
- package/dist/components/icons/AudioIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/BoxIcon.svelte +5 -0
- package/dist/components/icons/BoxIcon.svelte.d.ts +7 -0
- package/dist/components/icons/BoxIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/CameraIcon.svelte +5 -0
- package/dist/components/icons/CameraIcon.svelte.d.ts +7 -0
- package/dist/components/icons/CameraIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/DropboxIcon.svelte +5 -0
- package/dist/components/icons/DropboxIcon.svelte.d.ts +7 -0
- package/dist/components/icons/DropboxIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/GoogleDriveIcon.svelte +5 -0
- package/dist/components/icons/GoogleDriveIcon.svelte.d.ts +7 -0
- package/dist/components/icons/GoogleDriveIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/LinkIcon.svelte +5 -0
- package/dist/components/icons/LinkIcon.svelte.d.ts +7 -0
- package/dist/components/icons/LinkIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/MyDeviceIcon.svelte +5 -0
- package/dist/components/icons/MyDeviceIcon.svelte.d.ts +7 -0
- package/dist/components/icons/MyDeviceIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/OneDriveIcon.svelte +5 -0
- package/dist/components/icons/OneDriveIcon.svelte.d.ts +7 -0
- package/dist/components/icons/OneDriveIcon.svelte.d.ts.map +1 -0
- package/dist/components/icons/ScreenCaptureIcon.svelte +5 -0
- package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts +7 -0
- package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts.map +1 -0
- package/dist/components/shared/DriveAuthFallback.svelte +60 -0
- package/dist/components/shared/DriveAuthFallback.svelte.d.ts +12 -0
- package/dist/components/shared/DriveAuthFallback.svelte.d.ts.map +1 -0
- package/dist/components/shared/DriveBrowser.svelte +209 -0
- package/dist/components/shared/DriveBrowser.svelte.d.ts +25 -0
- package/dist/components/shared/DriveBrowser.svelte.d.ts.map +1 -0
- package/dist/components/shared/DriveBrowserHeader.svelte +191 -0
- package/dist/components/shared/DriveBrowserHeader.svelte.d.ts +14 -0
- package/dist/components/shared/DriveBrowserHeader.svelte.d.ts.map +1 -0
- package/dist/components/shared/DriveBrowserIcon.svelte +39 -0
- package/dist/components/shared/DriveBrowserIcon.svelte.d.ts +8 -0
- package/dist/components/shared/DriveBrowserIcon.svelte.d.ts.map +1 -0
- package/dist/components/shared/DriveBrowserItem.svelte +63 -0
- package/dist/components/shared/DriveBrowserItem.svelte.d.ts +10 -0
- package/dist/components/shared/DriveBrowserItem.svelte.d.ts.map +1 -0
- package/dist/components/shared/FileSuccessCheck.svelte +47 -0
- package/dist/components/shared/FileSuccessCheck.svelte.d.ts +10 -0
- package/dist/components/shared/FileSuccessCheck.svelte.d.ts.map +1 -0
- package/dist/components/shared/ProgressBar.svelte +81 -0
- package/dist/components/shared/ProgressBar.svelte.d.ts +10 -0
- package/dist/components/shared/ProgressBar.svelte.d.ts.map +1 -0
- package/dist/components/shared/SourceViewContainer.svelte +27 -0
- package/dist/components/shared/SourceViewContainer.svelte.d.ts +10 -0
- package/dist/components/shared/SourceViewContainer.svelte.d.ts.map +1 -0
- package/dist/components/shared/UploaderHeader.svelte +156 -0
- package/dist/components/shared/UploaderHeader.svelte.d.ts +13 -0
- package/dist/components/shared/UploaderHeader.svelte.d.ts.map +1 -0
- package/dist/composables/use-tiles-per-row.d.ts +19 -0
- package/dist/composables/use-tiles-per-row.d.ts.map +1 -0
- package/dist/composables/use-tiles-per-row.js +30 -0
- package/dist/composables/useBox.d.ts +28 -0
- package/dist/composables/useBox.d.ts.map +1 -0
- package/dist/composables/useBox.js +61 -0
- package/dist/composables/useCameraUploader.d.ts +23 -0
- package/dist/composables/useCameraUploader.d.ts.map +1 -0
- package/dist/composables/useCameraUploader.js +114 -0
- package/dist/composables/useDropbox.d.ts +28 -0
- package/dist/composables/useDropbox.d.ts.map +1 -0
- package/dist/composables/useDropbox.js +61 -0
- package/dist/composables/useFetchFileByUrl.d.ts +9 -0
- package/dist/composables/useFetchFileByUrl.d.ts.map +1 -0
- package/dist/composables/useFetchFileByUrl.js +33 -0
- package/dist/composables/useGoogleDrive.d.ts +28 -0
- package/dist/composables/useGoogleDrive.d.ts.map +1 -0
- package/dist/composables/useGoogleDrive.js +65 -0
- package/dist/composables/useOneDrive.d.ts +29 -0
- package/dist/composables/useOneDrive.d.ts.map +1 -0
- package/dist/composables/useOneDrive.js +64 -0
- package/dist/composables/useSSEProcessing.d.ts +20 -0
- package/dist/composables/useSSEProcessing.d.ts.map +1 -0
- package/dist/composables/useSSEProcessing.js +17 -0
- package/dist/composables/useServerModeDrive.d.ts +17 -0
- package/dist/composables/useServerModeDrive.d.ts.map +1 -0
- package/dist/composables/useServerModeDrive.js +33 -0
- package/dist/composables/useSourceSelector.d.ts +13 -0
- package/dist/composables/useSourceSelector.d.ts.map +1 -0
- package/dist/composables/useSourceSelector.js +36 -0
- package/dist/composables/useUploaderPanel.d.ts +12 -0
- package/dist/composables/useUploaderPanel.d.ts.map +1 -0
- package/dist/composables/useUploaderPanel.js +43 -0
- package/dist/context/create-uploader-context.d.ts +4 -0
- package/dist/context/create-uploader-context.d.ts.map +1 -0
- package/dist/context/create-uploader-context.js +324 -0
- package/dist/context/source-view-header-extra.d.ts +14 -0
- package/dist/context/source-view-header-extra.d.ts.map +1 -0
- package/dist/context/source-view-header-extra.js +41 -0
- package/dist/context/uploader-context.d.ts +109 -0
- package/dist/context/uploader-context.d.ts.map +1 -0
- package/dist/context/uploader-context.js +96 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/constants.d.ts +13 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +67 -0
- package/dist/lib/to-readable.d.ts +14 -0
- package/dist/lib/to-readable.d.ts.map +1 -0
- package/dist/lib/to-readable.js +15 -0
- package/dist/lib/view-mode.d.ts +24 -0
- package/dist/lib/view-mode.d.ts.map +1 -0
- package/dist/lib/view-mode.js +31 -0
- package/dist/shared/types.d.ts +15 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +1 -0
- package/dist/styles.d.ts +4 -0
- package/dist/tailwind-prefixed.css +2479 -0
- package/dist/tailwind.css +74 -0
- package/dist/use-upup-upload.d.ts +38 -0
- package/dist/use-upup-upload.d.ts.map +1 -0
- package/dist/use-upup-upload.js +81 -0
- 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 @@
|
|
|
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));
|