@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,292 @@
1
+ <script lang="ts">
2
+ import { formatUiMessage as t, pluralUiMessage as plural } from '@useupup/core'
3
+ import { cn } from '@useupup/core/internal'
4
+ import {
5
+ useUploaderFiles,
6
+ useUploaderI18n,
7
+ useUploaderOptions,
8
+ useUploaderRuntime,
9
+ useUploaderTheme,
10
+ } from '../context/uploader-context'
11
+ import useSourceSelector from '../composables/useSourceSelector'
12
+ import Icon from './Icon.svelte'
13
+
14
+ // Regular chips fit at most 4 per row inside the max-w-[420px] grid, so up to 8
15
+ // sources wrap into balanced rows; 9 would wrap 4/4/1. Past this count the chips
16
+ // switch to the compact size, which fits 5 per row (5/4).
17
+ const COMPACT_SOURCE_THRESHOLD = 8
18
+
19
+ const { core, getFileInput, openFilePicker } = useUploaderRuntime()
20
+ const { translations: tr } = useUploaderI18n()
21
+ const { setFiles } = useUploaderFiles()
22
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()
23
+ const {
24
+ mini,
25
+ allowedFileTypes,
26
+ limit,
27
+ maxFileSize,
28
+ folderPickerButtonVisible,
29
+ } = useUploaderOptions()
30
+
31
+ // Idle limits caption (data-upup-slot="limits-caption"): iconified file-count
32
+ // and per-file size limits, plus a leading text-only type-restriction segment
33
+ // so no constraint the consumer configured is dropped.
34
+ const typeConstraint = (() => {
35
+ if (allowedFileTypes && allowedFileTypes !== '*/*' && allowedFileTypes !== '*') {
36
+ const humanized = allowedFileTypes
37
+ .split(',')
38
+ .map((s) => s.trim())
39
+ .map((m) => {
40
+ if (m.startsWith('.')) return m
41
+ const [type, sub] = m.split('/')
42
+ if (!type || !sub) return m
43
+ if (sub === '*') return type.charAt(0).toUpperCase() + type.slice(1) + 's'
44
+ return sub.toUpperCase()
45
+ })
46
+ .join(', ')
47
+ return humanized + ' only'
48
+ }
49
+ return null
50
+ })()
51
+ const showFilesLimit = limit > 1
52
+ const showSizeLimit = !!(maxFileSize?.size && maxFileSize?.unit)
53
+ const hasLimitsCaption = !!typeConstraint || showFilesLimit || showSizeLimit
54
+
55
+ const { chosenSources, handleSourceClick } = useSourceSelector()
56
+ const compact = chosenSources.length > COMPACT_SOURCE_THRESHOLD
57
+
58
+ function handleBrowseFilesClick() {
59
+ const el = getFileInput()
60
+ if (el) {
61
+ el.removeAttribute('webkitdirectory')
62
+ el.removeAttribute('directory')
63
+ }
64
+ openFilePicker()
65
+ core?.emit('browse-files', {})
66
+ }
67
+
68
+ async function handleSelectFolderClick() {
69
+ const fsWindow = window as Window & { showDirectoryPicker?: () => Promise<FileSystemDirectoryHandle> }
70
+ if (fsWindow.showDirectoryPicker) {
71
+ try {
72
+ const directoryHandle = await fsWindow.showDirectoryPicker()
73
+ const collectedFiles: File[] = []
74
+
75
+ type IterableDirHandle = { values(): AsyncIterableIterator<FileSystemHandle & { kind: string; getFile: () => Promise<File> }> }
76
+ async function getFiles(dirHandle: IterableDirHandle, path = '') {
77
+ for await (const entry of dirHandle.values()) {
78
+ const newPath = path ? `${path}/${entry.name}` : entry.name
79
+ if (entry.kind === 'file') {
80
+ const pickedFile = await entry.getFile()
81
+ const file = new File(
82
+ [await pickedFile.arrayBuffer()],
83
+ pickedFile.name,
84
+ { type: pickedFile.type, lastModified: pickedFile.lastModified },
85
+ )
86
+ try {
87
+ Object.defineProperty(file, 'webkitRelativePath', {
88
+ value: newPath, configurable: true, writable: true,
89
+ })
90
+ Object.defineProperty(file, 'relativePath', {
91
+ value: newPath, configurable: true, writable: true,
92
+ })
93
+ } catch {
94
+ Object.assign(file, { relativePath: newPath })
95
+ }
96
+ collectedFiles.push(file)
97
+ } else if (entry.kind === 'directory') {
98
+ await getFiles(entry as unknown as IterableDirHandle, newPath)
99
+ }
100
+ }
101
+ }
102
+ await getFiles(directoryHandle as unknown as IterableDirHandle)
103
+ if (collectedFiles.length > 0) {
104
+ setFiles(collectedFiles)
105
+ core?.emit('folder-select', { count: collectedFiles.length })
106
+ const el = getFileInput()
107
+ if (el) el.value = ''
108
+ }
109
+ } catch (error) {
110
+ const name = error instanceof DOMException ? error.name : ''
111
+ if (name !== 'AbortError') throw error
112
+ }
113
+ } else {
114
+ const el = getFileInput()
115
+ if (el) {
116
+ el.setAttribute('webkitdirectory', 'true')
117
+ el.setAttribute('directory', 'true')
118
+ }
119
+ openFilePicker()
120
+ core?.emit('folder-select', { count: 0 })
121
+ }
122
+ }
123
+ </script>
124
+
125
+ <div
126
+ data-testid="upup-source-selector"
127
+ data-upup-slot="source-selector"
128
+ class="upup-animate-fx-view upup-relative upup-flex upup-h-full upup-flex-col upup-items-center upup-justify-center upup-gap-6 upup-rounded-lg upup-px-4 upup-py-6"
129
+ >
130
+ {#if !mini}
131
+ <div
132
+ class={cn(
133
+ 'upup-flex upup-flex-wrap upup-items-center upup-justify-center upup-gap-x-1.5 upup-gap-y-1 upup-px-2 upup-text-center upup-text-base upup-font-medium md:upup-text-lg',
134
+ {
135
+ 'upup-text-[#242634]': !$dark,
136
+ 'upup-text-[#e2e8f0] dark:upup-text-[#e2e8f0]': $dark,
137
+ },
138
+ )}
139
+ >
140
+ <span>{tr.dropFilesHere}</span>
141
+ <button
142
+ type="button"
143
+ data-testid="upup-browse-files"
144
+ class={cn(
145
+ 'upup-cursor-pointer upup-rounded upup-font-semibold focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8]',
146
+ {
147
+ 'upup-text-[#0284c7]': !$dark,
148
+ 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]': $dark,
149
+ },
150
+ )}
151
+ onclick={handleBrowseFilesClick}
152
+ >
153
+ {tr.browseFiles}
154
+ </button>
155
+ {#if folderPickerButtonVisible}
156
+ <span>{tr.or}</span>
157
+ <button
158
+ type="button"
159
+ class={cn(
160
+ 'upup-cursor-pointer upup-rounded upup-font-semibold focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8]',
161
+ {
162
+ 'upup-text-[#0284c7]': !$dark,
163
+ 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]': $dark,
164
+ },
165
+ )}
166
+ onclick={handleSelectFolderClick}
167
+ >
168
+ {tr.selectAFolder}
169
+ </button>
170
+ {/if}
171
+ <span>{tr.orImportFrom}</span>
172
+ </div>
173
+ <div
174
+ class={cn(
175
+ compact
176
+ ? 'upup-flex upup-max-w-[420px] upup-flex-wrap upup-items-start upup-justify-center upup-gap-x-3 upup-gap-y-4'
177
+ : 'upup-flex upup-max-w-[420px] upup-flex-wrap upup-items-start upup-justify-center upup-gap-x-6 upup-gap-y-5',
178
+ $slotClasses.sourceButtonList,
179
+ )}
180
+ >
181
+ {#each chosenSources as { Icon: SourceIcon, id, name } (id)}
182
+ <button
183
+ type="button"
184
+ data-testid={`upup-source-${id}`}
185
+ class={cn(
186
+ compact
187
+ ? 'upup-fx-hover-lift upup-fx-press upup-fx-icon-nudge upup-group upup-flex upup-w-[62px] upup-cursor-pointer upup-flex-col upup-items-center upup-gap-[7px] upup-rounded-[12px] focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8] hover:upup-shadow-none'
188
+ : 'upup-fx-hover-lift upup-fx-press upup-fx-icon-nudge upup-group upup-flex upup-w-[66px] upup-cursor-pointer upup-flex-col upup-items-center upup-gap-[9px] upup-rounded-[14px] focus-visible:upup-outline-none focus-visible:upup-ring-2 focus-visible:upup-ring-[#38bdf8] hover:upup-shadow-none',
189
+ $slotClasses.sourceButton,
190
+ )}
191
+ onclick={() => handleSourceClick(id)}
192
+ >
193
+ <span
194
+ class={cn(
195
+ compact
196
+ ? 'upup-flex upup-h-[42px] upup-w-[42px] upup-items-center upup-justify-center upup-rounded-[12px] upup-ring-1 upup-transition-colors'
197
+ : 'upup-flex upup-h-[52px] upup-w-[52px] upup-items-center upup-justify-center upup-rounded-[14px] upup-ring-1 upup-transition-colors',
198
+ {
199
+ 'upup-bg-white upup-ring-black/[0.07] group-hover:upup-bg-slate-50': !$dark,
200
+ 'upup-bg-white/[0.055] upup-ring-white/[0.06] group-hover:upup-bg-white/[0.09] dark:upup-bg-white/[0.055] dark:upup-ring-white/[0.06]': $dark,
201
+ },
202
+ )}
203
+ >
204
+ <SourceIcon
205
+ class={cn(
206
+ compact ? 'upup-h-8 upup-w-8' : 'upup-h-10 upup-w-10',
207
+ $slotClasses.sourceButtonIcon,
208
+ )}
209
+ />
210
+ </span>
211
+ <span
212
+ class={cn(
213
+ 'upup-text-xs upup-leading-none',
214
+ {
215
+ 'upup-text-[#6D6D6D]': !$dark,
216
+ 'upup-text-[#94a3b8] dark:upup-text-[#94a3b8]': $dark,
217
+ },
218
+ $slotClasses.sourceButtonText,
219
+ )}
220
+ >
221
+ {name}
222
+ </span>
223
+ </button>
224
+ {/each}
225
+ </div>
226
+ {/if}
227
+
228
+ {#if mini}
229
+ <button
230
+ type="button"
231
+ onclick={handleBrowseFilesClick}
232
+ class="upup-flex upup-cursor-pointer upup-flex-col upup-items-center upup-justify-center upup-gap-2 upup-rounded-lg upup-p-2"
233
+ >
234
+ <Icon
235
+ name="upload"
236
+ size={32}
237
+ class={cn(
238
+ 'upup-h-16 upup-w-16 md:upup-h-20 md:upup-w-20',
239
+ {
240
+ 'upup-text-[#0B0B0B]': !$dark,
241
+ 'upup-text-white dark:upup-text-white': $dark,
242
+ },
243
+ )}
244
+ />
245
+ <p
246
+ class={cn('px-6 upup-text-center upup-text-xs', {
247
+ 'upup-text-[#6D6D6D] dark:upup-text-gray-400': !$dark,
248
+ 'upup-text-gray-400 dark:upup-text-gray-500': $dark,
249
+ })}
250
+ >
251
+ Drag or browse to upload
252
+ </p>
253
+ </button>
254
+ {:else if hasLimitsCaption}
255
+ <div
256
+ data-upup-slot="limits-caption"
257
+ class={cn(
258
+ 'upup-flex upup-flex-wrap upup-items-center upup-justify-center upup-gap-x-2.5 upup-gap-y-1 upup-px-3 upup-text-center upup-text-xs',
259
+ {
260
+ 'upup-text-[#6D6D6D]': !$dark,
261
+ 'upup-text-[#94a3b8] dark:upup-text-[#94a3b8]': $dark,
262
+ },
263
+ )}
264
+ >
265
+ {#if typeConstraint}
266
+ <span>{typeConstraint}</span>
267
+ {/if}
268
+ {#if typeConstraint && (showFilesLimit || showSizeLimit)}
269
+ <span aria-hidden="true">&middot;</span>
270
+ {/if}
271
+ {#if showFilesLimit}
272
+ <span class="upup-inline-flex upup-items-center upup-gap-1.5">
273
+ <span aria-hidden="true" class="upup-inline-flex">
274
+ <Icon name="stacked-files" class="upup-h-4 upup-w-4" />
275
+ </span>
276
+ {t(plural(tr, 'filesMax', limit), { count: limit })}
277
+ </span>
278
+ {/if}
279
+ {#if showFilesLimit && showSizeLimit}
280
+ <span aria-hidden="true">&middot;</span>
281
+ {/if}
282
+ {#if showSizeLimit}
283
+ <span class="upup-inline-flex upup-items-center upup-gap-1.5">
284
+ <span aria-hidden="true" class="upup-inline-flex">
285
+ <Icon name="storage" class="upup-h-4 upup-w-4" />
286
+ </span>
287
+ {t(tr.sizeEach, { size: maxFileSize?.size ?? 0, unit: maxFileSize?.unit ?? '' })}
288
+ </span>
289
+ {/if}
290
+ </div>
291
+ {/if}
292
+ </div>
@@ -0,0 +1,19 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const SourceSelector: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type SourceSelector = InstanceType<typeof SourceSelector>;
18
+ export default SourceSelector;
19
+ //# sourceMappingURL=SourceSelector.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourceSelector.svelte.d.ts","sourceRoot":"","sources":["../../src/components/SourceSelector.svelte.ts"],"names":[],"mappings":"AAuQA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,cAAc;;kBAA+E,CAAC;AAClF,KAAK,cAAc,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;AAC5D,eAAe,cAAc,CAAC"}
@@ -0,0 +1,100 @@
1
+ <script lang="ts">
2
+ import {
3
+ useUploaderI18n,
4
+ useUploaderOptions,
5
+ useUploaderRuntime,
6
+ useUploaderSource,
7
+ useUploaderTheme,
8
+ } from '../context/uploader-context'
9
+ import { provideSourceViewHeaderExtra } from '../context/source-view-header-extra'
10
+ import { uploadSourceObject } from '../lib/constants'
11
+ import { cn } from '@useupup/core/internal'
12
+ import DefaultLoaderIcon from './DefaultLoaderIcon.svelte'
13
+
14
+ const { core } = useUploaderRuntime()
15
+ const { activeSource, setActiveSource } = useUploaderSource()
16
+ const { translations: tr } = useUploaderI18n()
17
+ const { mini } = useUploaderOptions()
18
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme()
19
+
20
+ // Portal host for a source view's header extras (drive avatar + log out); lives
21
+ // left of Back. `empty:upup-hidden` keeps the flex gap from showing when no
22
+ // view portals anything in.
23
+ const headerExtraStore = provideSourceViewHeaderExtra()
24
+ let headerExtraHost: HTMLElement | null = $state(null)
25
+ $effect(() => {
26
+ headerExtraStore.set(headerExtraHost)
27
+ })
28
+
29
+ const activeComponent = $derived(
30
+ $activeSource ? uploadSourceObject[$activeSource]?.Component : undefined,
31
+ )
32
+ const SourceIcon = $derived(
33
+ $activeSource ? uploadSourceObject[$activeSource]?.Icon : undefined,
34
+ )
35
+ const sourceName = $derived.by(() => {
36
+ const s = $activeSource
37
+ const entry = s ? uploadSourceObject[s] : undefined
38
+ return entry ? tr[entry.nameKey] : ''
39
+ })
40
+
41
+ const shouldRender = $derived(
42
+ !!activeComponent && !mini && !!$activeSource && !!SourceIcon,
43
+ )
44
+
45
+ function handleCancel() {
46
+ core?.emit('source-view-cancel', { sourceId: $activeSource })
47
+ setActiveSource(undefined)
48
+ }
49
+ </script>
50
+
51
+ {#if shouldRender}
52
+ <div
53
+ class="upup-animate-fx-view upup-grid upup-h-full upup-w-full upup-grid-rows-[auto,1fr]"
54
+ data-upup-slot="source-view"
55
+ >
56
+ <!-- Transparent header on the panel gradient (no inner box): the
57
+ provider icon + name fill the row; "Back" returns to sources. -->
58
+ <div
59
+ class={cn(
60
+ 'upup-flex upup-items-center upup-justify-between upup-gap-2 upup-px-3 upup-py-2 upup-text-sm upup-font-medium',
61
+ $dark ? 'upup-text-[#FAFAFA]' : 'upup-text-[#0f172a]',
62
+ $slotClasses.sourceViewHeader,
63
+ )}
64
+ >
65
+ <span class="upup-flex upup-items-center upup-gap-2">
66
+ {#if SourceIcon}
67
+ <SourceIcon />
68
+ {/if}
69
+ <span>{sourceName}</span>
70
+ </span>
71
+ <span class="upup-flex upup-items-center upup-gap-2.5">
72
+ <span
73
+ bind:this={headerExtraHost}
74
+ data-upup-slot="source-view-header-extra"
75
+ class="upup-flex upup-items-center upup-gap-2.5 empty:upup-hidden"
76
+ ></span>
77
+ <button
78
+ class={cn(
79
+ 'upup-rounded-md upup-p-1 upup-text-[#0284c7] upup-transition-all upup-duration-300',
80
+ { 'upup-text-[#38bdf8] dark:upup-text-[#38bdf8]': $dark },
81
+ $slotClasses.sourceViewCancelButton,
82
+ )}
83
+ onclick={handleCancel}
84
+ type="button"
85
+ >
86
+ {tr.overlayBack}
87
+ </button>
88
+ </span>
89
+ </div>
90
+ {#if activeComponent}
91
+ {#await activeComponent()}
92
+ <div class="upup-flex upup-h-full upup-items-center upup-justify-center">
93
+ <DefaultLoaderIcon />
94
+ </div>
95
+ {:then mod}
96
+ <mod.default />
97
+ {/await}
98
+ {/if}
99
+ </div>
100
+ {/if}
@@ -0,0 +1,4 @@
1
+ declare const SourceView: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type SourceView = ReturnType<typeof SourceView>;
3
+ export default SourceView;
4
+ //# sourceMappingURL=SourceView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SourceView.svelte.d.ts","sourceRoot":"","sources":["../../src/components/SourceView.svelte.ts"],"names":[],"mappings":"AAkGA,QAAA,MAAM,UAAU,2DAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ // Default file-delete glyph — renders the shared registry 'trash' icon (parity with
3
+ // React's react-icons TbTrash default). Forwards the consumer's class/size to the svg.
4
+ import Icon from './Icon.svelte'
5
+ let {
6
+ class: className = '',
7
+ size = undefined,
8
+ }: { class?: string; size?: number } = $props()
9
+ </script>
10
+
11
+ <Icon name="trash" class={className} {size} />
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ class?: string;
3
+ size?: number;
4
+ };
5
+ declare const TrashIcon: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type TrashIcon = ReturnType<typeof TrashIcon>;
7
+ export default TrashIcon;
8
+ //# sourceMappingURL=TrashIcon.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrashIcon.svelte.d.ts","sourceRoot":"","sources":["../../src/components/TrashIcon.svelte.ts"],"names":[],"mappings":"AAOC,KAAK,gBAAgB,GAAI;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAe5D,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}