@zayne-labs/ui-react 0.10.8 → 0.10.10

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 (76) hide show
  1. package/dist/esm/{cn-s-D7vHW1.js → cn-DdD3uYxA.js} +1 -1
  2. package/dist/esm/{cn-s-D7vHW1.js.map → cn-DdD3uYxA.js.map} +1 -1
  3. package/dist/esm/common/await/index.d.ts +46 -4
  4. package/dist/esm/common/await/index.js +86 -4
  5. package/dist/esm/common/await/index.js.map +1 -0
  6. package/dist/esm/common/error-boundary/index.d.ts +1 -1
  7. package/dist/esm/common/for/index.d.ts +23 -2
  8. package/dist/esm/common/for/index.js +1 -1
  9. package/dist/esm/common/presence/index.js +1 -1
  10. package/dist/esm/common/show/index.d.ts +32 -2
  11. package/dist/esm/common/slot/index.d.ts +16 -2
  12. package/dist/esm/common/suspense-with-boundary/index.d.ts +2 -2
  13. package/dist/esm/common/suspense-with-boundary/index.js +20 -3
  14. package/dist/esm/common/suspense-with-boundary/index.js.map +1 -0
  15. package/dist/esm/common/switch/index.d.ts +28 -2
  16. package/dist/esm/common/switch/index.js +37 -2
  17. package/dist/esm/common/switch/index.js.map +1 -0
  18. package/dist/esm/common/teleport/index.d.ts +14 -2
  19. package/dist/esm/common/teleport/index.js +31 -2
  20. package/dist/esm/common/teleport/index.js.map +1 -0
  21. package/dist/esm/{for-DK5rEY_m.js → for-BYsFEk3R.js} +1 -1
  22. package/dist/esm/{for-DK5rEY_m.js.map → for-BYsFEk3R.js.map} +1 -1
  23. package/dist/esm/{index-C8_O0zCb.d.ts → index-BwhRxsrZ.d.ts} +3 -3
  24. package/dist/esm/{index-B4K9g2v-.d.ts → index-C_2Onnhl.d.ts} +4 -4
  25. package/dist/esm/{presence-CL5_GHQH.js → presence-CAQElNtY.js} +1 -1
  26. package/dist/esm/{presence-CL5_GHQH.js.map → presence-CAQElNtY.js.map} +1 -1
  27. package/dist/esm/ui/card/index.d.ts +20 -2
  28. package/dist/esm/ui/card/index.js +94 -4
  29. package/dist/esm/ui/card/index.js.map +1 -0
  30. package/dist/esm/ui/carousel/index.d.ts +95 -2
  31. package/dist/esm/ui/carousel/index.js +285 -13
  32. package/dist/esm/ui/carousel/index.js.map +1 -0
  33. package/dist/esm/ui/drag-scroll/index.d.ts +23 -2
  34. package/dist/esm/ui/drag-scroll/index.js +114 -3
  35. package/dist/esm/ui/drag-scroll/index.js.map +1 -0
  36. package/dist/esm/ui/drop-zone/index.d.ts +346 -2
  37. package/dist/esm/ui/drop-zone/index.js +1026 -14
  38. package/dist/esm/ui/drop-zone/index.js.map +1 -0
  39. package/dist/esm/ui/form/index.d.ts +227 -2
  40. package/dist/esm/ui/form/index.js +573 -5
  41. package/dist/esm/ui/form/index.js.map +1 -0
  42. package/package.json +6 -8
  43. package/dist/esm/await-DDgVzpvI.js +0 -87
  44. package/dist/esm/await-DDgVzpvI.js.map +0 -1
  45. package/dist/esm/card-DDLJVCwL.js +0 -95
  46. package/dist/esm/card-DDLJVCwL.js.map +0 -1
  47. package/dist/esm/carousel-B051PAAX.js +0 -285
  48. package/dist/esm/carousel-B051PAAX.js.map +0 -1
  49. package/dist/esm/common/index.d.ts +0 -9
  50. package/dist/esm/common/index.js +0 -11
  51. package/dist/esm/common-PS3X58Pj.js +0 -0
  52. package/dist/esm/drag-scroll-Bb1SG4On.js +0 -115
  53. package/dist/esm/drag-scroll-Bb1SG4On.js.map +0 -1
  54. package/dist/esm/drop-zone-C9VpKJAD.js +0 -1013
  55. package/dist/esm/drop-zone-C9VpKJAD.js.map +0 -1
  56. package/dist/esm/form-DyGy9LnA.js +0 -574
  57. package/dist/esm/form-DyGy9LnA.js.map +0 -1
  58. package/dist/esm/index-BoZe50e8.d.ts +0 -340
  59. package/dist/esm/index-BsGxDKlt.d.ts +0 -32
  60. package/dist/esm/index-Bx2BzRRJ.d.ts +0 -16
  61. package/dist/esm/index-C1GPFYKG.d.ts +0 -23
  62. package/dist/esm/index-CZjeBSoQ.d.ts +0 -14
  63. package/dist/esm/index-CffEFE66.d.ts +0 -28
  64. package/dist/esm/index-DWl-QZ3Q.d.ts +0 -46
  65. package/dist/esm/index-DZxgPnK1.d.ts +0 -95
  66. package/dist/esm/index-DbiE_few.d.ts +0 -227
  67. package/dist/esm/index-Df39YVRj.d.ts +0 -23
  68. package/dist/esm/index-SX3cnKP6.d.ts +0 -20
  69. package/dist/esm/suspense-with-boundary-D-1NYDV4.js +0 -21
  70. package/dist/esm/suspense-with-boundary-D-1NYDV4.js.map +0 -1
  71. package/dist/esm/switch-Ch22z21e.js +0 -38
  72. package/dist/esm/switch-Ch22z21e.js.map +0 -1
  73. package/dist/esm/teleport-C8TzRm4M.js +0 -32
  74. package/dist/esm/teleport-C8TzRm4M.js.map +0 -1
  75. package/dist/esm/ui/index.d.ts +0 -6
  76. package/dist/esm/ui/index.js +0 -18
@@ -1,1013 +0,0 @@
1
- import { __export } from "./chunk-CTAAG5j7.js";
2
- import { SlotRoot } from "./slot-WVWfOlr3.js";
3
- import { For } from "./for-DK5rEY_m.js";
4
- import { cnMerge } from "./cn-s-D7vHW1.js";
5
- import { Presence } from "./presence-CL5_GHQH.js";
6
- import { composeRefs, composeTwoEventHandlers } from "@zayne-labs/toolkit-react/utils";
7
- import { isFile, isFunction, isNumber, isObject, isString } from "@zayne-labs/toolkit-type-helpers";
8
- import { useCallback, useMemo, useRef } from "react";
9
- import { createCustomContext, useCallbackRef, useConstant, useShallowCompSelector, useShallowCompValue, useStore, useUnmountEffect } from "@zayne-labs/toolkit-react";
10
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
- import { createFileUrl, createStore, dataAttr, formatBytes, generateFileID, handleFileValidationAsync, toArray } from "@zayne-labs/toolkit-core";
12
- import { createZustandContext } from "@zayne-labs/toolkit-react/zustand";
13
-
14
- //#region src/components/ui/drop-zone/drop-zone-context.ts
15
- const [DropZoneStoreContextProvider, useDropZoneStoreContext] = createZustandContext({
16
- hookName: "useDropZoneStoreContext",
17
- name: "DropZoneStoreContext",
18
- providerName: "DropZoneRoot"
19
- });
20
- const [DropZoneRootContextProvider, useDropZoneRootContext] = createCustomContext({
21
- hookName: "useDropZoneRootContext",
22
- name: "DropZoneRootContext",
23
- providerName: "DropZoneRoot"
24
- });
25
- const [FileItemContextProvider, useFileItemContext] = createCustomContext({
26
- defaultValue: null,
27
- hookName: "useFileItemContext",
28
- name: "FileItemContext",
29
- providerName: "FileItem",
30
- strict: false
31
- });
32
-
33
- //#endregion
34
- //#region src/components/ui/drop-zone/icons.tsx
35
- const FileVideoIcon = (props) => /* @__PURE__ */ jsx("svg", {
36
- xmlns: "http://www.w3.org/2000/svg",
37
- width: "1em",
38
- height: "1em",
39
- viewBox: "0 0 24 24",
40
- ...props,
41
- children: /* @__PURE__ */ jsxs("g", {
42
- fill: "none",
43
- stroke: "currentColor",
44
- strokeLinecap: "round",
45
- strokeLinejoin: "round",
46
- strokeWidth: "2",
47
- children: [/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }), /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4m-10 3l5 3l-5 3z" })]
48
- })
49
- });
50
- const FileAudioIcon = (props) => /* @__PURE__ */ jsx("svg", {
51
- xmlns: "http://www.w3.org/2000/svg",
52
- width: "1em",
53
- height: "1em",
54
- viewBox: "0 0 24 24",
55
- ...props,
56
- children: /* @__PURE__ */ jsxs("g", {
57
- fill: "none",
58
- stroke: "currentColor",
59
- strokeLinecap: "round",
60
- strokeLinejoin: "round",
61
- strokeWidth: "2",
62
- children: [/* @__PURE__ */ jsx("path", { d: "M17.5 22h.5a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3" }), /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M2 19a2 2 0 1 1 4 0v1a2 2 0 1 1-4 0v-4a6 6 0 0 1 12 0v4a2 2 0 1 1-4 0v-1a2 2 0 1 1 4 0" })]
63
- })
64
- });
65
- const FileTextIcon = (props) => /* @__PURE__ */ jsx("svg", {
66
- xmlns: "http://www.w3.org/2000/svg",
67
- width: "1em",
68
- height: "1em",
69
- viewBox: "0 0 24 24",
70
- ...props,
71
- children: /* @__PURE__ */ jsxs("g", {
72
- fill: "none",
73
- stroke: "currentColor",
74
- strokeLinecap: "round",
75
- strokeLinejoin: "round",
76
- strokeWidth: "2",
77
- children: [/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }), /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M10 9H8m8 4H8m8 4H8" })]
78
- })
79
- });
80
- const FileCodeIcon = (props) => /* @__PURE__ */ jsx("svg", {
81
- xmlns: "http://www.w3.org/2000/svg",
82
- width: "1em",
83
- height: "1em",
84
- viewBox: "0 0 24 24",
85
- ...props,
86
- children: /* @__PURE__ */ jsxs("g", {
87
- fill: "none",
88
- stroke: "currentColor",
89
- strokeLinecap: "round",
90
- strokeLinejoin: "round",
91
- strokeWidth: "2",
92
- children: [/* @__PURE__ */ jsx("path", { d: "M10 12.5L8 15l2 2.5m4-5l2 2.5l-2 2.5M14 2v4a2 2 0 0 0 2 2h4" }), /* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z" })]
93
- })
94
- });
95
- const FileArchiveIcon = (props) => /* @__PURE__ */ jsx("svg", {
96
- xmlns: "http://www.w3.org/2000/svg",
97
- width: "1em",
98
- height: "1em",
99
- viewBox: "0 0 24 24",
100
- ...props,
101
- children: /* @__PURE__ */ jsxs("g", {
102
- fill: "none",
103
- stroke: "currentColor",
104
- strokeLinecap: "round",
105
- strokeLinejoin: "round",
106
- strokeWidth: "2",
107
- children: [
108
- /* @__PURE__ */ jsx("path", { d: "M10 12v-1m0 7v-2m0-9V6m4-4v4a2 2 0 0 0 2 2h4" }),
109
- /* @__PURE__ */ jsx("path", { d: "M15.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v16a2 2 0 0 0 .274 1.01" }),
110
- /* @__PURE__ */ jsx("circle", {
111
- cx: "10",
112
- cy: "20",
113
- r: "2"
114
- })
115
- ]
116
- })
117
- });
118
- const FileCogIcon = (props) => /* @__PURE__ */ jsx("svg", {
119
- xmlns: "http://www.w3.org/2000/svg",
120
- width: "1em",
121
- height: "1em",
122
- viewBox: "0 0 24 24",
123
- ...props,
124
- children: /* @__PURE__ */ jsxs("g", {
125
- fill: "none",
126
- stroke: "currentColor",
127
- strokeLinecap: "round",
128
- strokeLinejoin: "round",
129
- strokeWidth: "2",
130
- children: [
131
- /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M3.2 12.9l-.9-.4m.9 2.6l-.9.4" }),
132
- /* @__PURE__ */ jsx("path", { d: "M4.677 21.5a2 2 0 0 0 1.313.5H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v2.5m.9 4.7l-.4-.9m.4 6.5l-.4.9m3-7.4l-.4.9m.4 6.5l-.4-.9m2.6-4.3l-.9.4m.9 2.6l-.9-.4" }),
133
- /* @__PURE__ */ jsx("circle", {
134
- cx: "6",
135
- cy: "14",
136
- r: "3"
137
- })
138
- ]
139
- })
140
- });
141
- const FileIcon = (props) => /* @__PURE__ */ jsx("svg", {
142
- xmlns: "http://www.w3.org/2000/svg",
143
- width: "1em",
144
- height: "1em",
145
- viewBox: "0 0 24 24",
146
- ...props,
147
- children: /* @__PURE__ */ jsxs("g", {
148
- fill: "none",
149
- stroke: "currentColor",
150
- strokeLinecap: "round",
151
- strokeLinejoin: "round",
152
- strokeWidth: "2",
153
- children: [/* @__PURE__ */ jsx("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }), /* @__PURE__ */ jsx("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })]
154
- })
155
- });
156
-
157
- //#endregion
158
- //#region src/components/ui/drop-zone/utils.ts
159
- const generateFileID$1 = generateFileID;
160
- const createObjectURL = (file, disallowPreviewForNonImageFiles) => {
161
- if (disallowPreviewForNonImageFiles && !file.type?.startsWith("image/")) return;
162
- return createFileUrl(file);
163
- };
164
- const clearObjectURL = (fileState, disallowPreviewForNonImageFiles) => {
165
- if (!isFile(fileState?.file)) return;
166
- if (disallowPreviewForNonImageFiles && !fileState.file.type.startsWith("image/")) return;
167
- if (!fileState.preview) return;
168
- URL.revokeObjectURL(fileState.preview);
169
- };
170
- const isMatchingFile = (options) => {
171
- const { fileState, fileStateOrID } = options;
172
- const fileID = isFile(fileState) ? generateFileID$1(fileState) : fileState.id;
173
- if (isString(fileStateOrID)) return fileID === fileStateOrID;
174
- if (isFile(fileStateOrID)) {
175
- const generatedFileID = generateFileID$1(fileStateOrID);
176
- return fileID === generatedFileID;
177
- }
178
- return fileID === fileStateOrID.id;
179
- };
180
- const getScopeAttrs = (part) => {
181
- return {
182
- "data-slot": `dropzone-${part}`,
183
- "data-scope": "dropzone",
184
- "data-part": part
185
- };
186
- };
187
- const dropZoneErrorSymbol = Symbol("DropZoneError");
188
- var DropZoneError = class DropZoneError extends Error {
189
- dropZoneErrorSymbol = dropZoneErrorSymbol;
190
- file;
191
- name = "DropZoneError";
192
- constructor(ctx) {
193
- const { file, message } = ctx;
194
- super(message);
195
- this.file = file;
196
- }
197
- static isError(error) {
198
- if (!isObject(error)) return false;
199
- if (error instanceof DropZoneError) return true;
200
- const actualError = error;
201
- return actualError.dropZoneErrorSymbol === dropZoneErrorSymbol && actualError.name === "DropZoneError";
202
- }
203
- };
204
- const getErrorContext = (error) => {
205
- if (DropZoneError.isError(error)) return {
206
- cause: "custom-error",
207
- code: "upload-error",
208
- file: error.file ?? {},
209
- message: error.message,
210
- originalError: error.cause ?? error
211
- };
212
- const actualError = Error.isError(error) ? error : new Error("File upload failed", { cause: error });
213
- return {
214
- cause: "custom-error",
215
- code: "upload-error",
216
- file: isFile(actualError.cause) ? actualError.cause : {},
217
- message: Error.isError(error) ? actualError.message : String(actualError),
218
- originalError: actualError
219
- };
220
- };
221
-
222
- //#endregion
223
- //#region src/components/ui/drop-zone/drop-zone-store.ts
224
- const createDropZoneStore = (initStoreValues) => {
225
- const { allowedFileTypes, disablePreviewForNonImageFiles, initialFiles, inputRef, maxFileCount, maxFileSize, multiple, onFilesChange, onUpload, onValidationError, onValidationSuccess, rejectDuplicateFiles, validator } = initStoreValues;
226
- const initialFileArray = toArray(initialFiles).filter(Boolean);
227
- const clearInputValue = () => {
228
- if (!inputRef.current) return;
229
- inputRef.current.value = "";
230
- };
231
- const initFileStateArray = initialFileArray.map((fileMeta) => ({
232
- file: fileMeta,
233
- id: fileMeta.id,
234
- preview: isString(fileMeta.url) ? fileMeta.url : void 0,
235
- progress: 0,
236
- status: "idle"
237
- }));
238
- const store = createStore((set, get) => ({
239
- disabled: false,
240
- errors: [],
241
- fileStateArray: initFileStateArray,
242
- isDraggingOver: false,
243
- isInvalid: false,
244
- actions: {
245
- addFiles: async (files) => {
246
- if (!files || files.length === 0) {
247
- console.warn("No file selected!");
248
- return;
249
- }
250
- const { actions, fileStateArray } = get();
251
- const resolvedNewFiles = !multiple ? [files[0]] : files;
252
- const { errors, validFiles } = await handleFileValidationAsync({
253
- existingFiles: fileStateArray.map((fileWithPreview) => fileWithPreview.file),
254
- hooks: {
255
- onErrorEach: onValidationError,
256
- onSuccessBatch: onValidationSuccess
257
- },
258
- newFiles: resolvedNewFiles,
259
- settings: {
260
- allowedFileTypes,
261
- maxFileCount,
262
- maxFileSize,
263
- rejectDuplicateFiles,
264
- validator
265
- }
266
- });
267
- if (validFiles.length === 0) {
268
- set({
269
- errors,
270
- isDraggingOver: false
271
- });
272
- return;
273
- }
274
- const newFileStateArray = validFiles.map((file) => ({
275
- file,
276
- id: generateFileID$1(file),
277
- preview: createObjectURL(file, disablePreviewForNonImageFiles),
278
- progress: 0,
279
- status: "idle"
280
- }));
281
- set({
282
- errors,
283
- fileStateArray: !multiple ? newFileStateArray : [...fileStateArray, ...newFileStateArray],
284
- isDraggingOver: false
285
- });
286
- await actions.handleFileUpload({ newFileStateArray });
287
- },
288
- clearErrors: () => {
289
- set({
290
- errors: [],
291
- isInvalid: false
292
- });
293
- },
294
- clearFiles: () => {
295
- const { actions } = get();
296
- actions.clearObjectURLs();
297
- set({
298
- errors: [],
299
- fileStateArray: [],
300
- isInvalid: false
301
- });
302
- },
303
- clearObjectURLs: () => {
304
- const { fileStateArray } = get();
305
- for (const fileState of fileStateArray) clearObjectURL(fileState, disablePreviewForNonImageFiles);
306
- },
307
- handleChange: async (event) => {
308
- const fileList = event.target.files;
309
- const { actions } = get();
310
- await actions.addFiles(fileList);
311
- clearInputValue();
312
- },
313
- handleDragEnter: (event) => {
314
- event.preventDefault();
315
- event.stopPropagation();
316
- set({ isDraggingOver: true });
317
- },
318
- handleDragLeave: (event) => {
319
- event.preventDefault();
320
- event.stopPropagation();
321
- set({ isDraggingOver: false });
322
- },
323
- handleDragOver: (event) => {
324
- event.preventDefault();
325
- event.stopPropagation();
326
- },
327
- handleDrop: async (event) => {
328
- event.preventDefault();
329
- event.stopPropagation();
330
- const { actions } = get();
331
- const fileList = event.dataTransfer.files;
332
- await actions.addFiles(fileList);
333
- },
334
- handleFileUpload: async (context) => {
335
- const { newFileStateArray } = context;
336
- const { actions } = get();
337
- if (!onUpload) {
338
- for (const fileState of newFileStateArray) actions.updateFileState({
339
- fileStateOrID: fileState,
340
- progress: 100,
341
- status: "success"
342
- });
343
- return;
344
- }
345
- try {
346
- await onUpload({
347
- fileStateArray: newFileStateArray,
348
- onError: (ctx) => {
349
- const { error, fileStateOrID } = ctx;
350
- const errorContext = getErrorContext(error);
351
- actions.updateFileState({
352
- error: errorContext,
353
- fileStateOrID,
354
- status: "error"
355
- });
356
- },
357
- onProgress: (ctx) => {
358
- const { fileStateOrID, progress } = ctx;
359
- actions.updateFileState({
360
- fileStateOrID,
361
- progress
362
- });
363
- },
364
- onSuccess: (ctx) => {
365
- const { fileStateOrID } = ctx;
366
- actions.updateFileState({
367
- fileStateOrID,
368
- progress: 100,
369
- status: "success"
370
- });
371
- }
372
- });
373
- } catch (error) {
374
- const errorContext = getErrorContext(error);
375
- for (const fileState of newFileStateArray) actions.updateFileState({
376
- error: errorContext,
377
- fileStateOrID: fileState,
378
- status: "error"
379
- });
380
- }
381
- },
382
- handleKeyDown: (event) => {
383
- const isEnterKey = event.key === "Enter";
384
- const isSpaceKey = event.key === " ";
385
- if (!(isEnterKey || isSpaceKey)) return;
386
- event.preventDefault();
387
- const { actions } = get();
388
- actions.openFilePicker();
389
- },
390
- handlePaste: async (event) => {
391
- event.preventDefault();
392
- event.stopPropagation();
393
- const { actions } = get();
394
- const fileList = event.clipboardData.files;
395
- await actions.addFiles(fileList);
396
- },
397
- openFilePicker: () => {
398
- inputRef.current?.click();
399
- },
400
- removeFile: (ctx) => {
401
- const { fileStateOrID } = ctx;
402
- const { fileStateArray } = get();
403
- const updatedFileStateArray = fileStateArray.flatMap((fileState) => {
404
- if (isMatchingFile({
405
- fileState,
406
- fileStateOrID
407
- })) {
408
- clearObjectURL(fileState, disablePreviewForNonImageFiles);
409
- return [];
410
- }
411
- return fileState;
412
- });
413
- set({
414
- errors: [],
415
- fileStateArray: updatedFileStateArray
416
- });
417
- },
418
- updateFileState: (ctx) => {
419
- const { fileStateOrID,...updatedFileState } = ctx;
420
- const { fileStateArray } = get();
421
- const updatedFileStateArray = fileStateArray.map((fileState) => {
422
- if (isMatchingFile({
423
- fileState,
424
- fileStateOrID
425
- })) return {
426
- ...fileState,
427
- ...updatedFileState
428
- };
429
- return fileState;
430
- });
431
- set({ fileStateArray: updatedFileStateArray });
432
- }
433
- }
434
- }));
435
- store.subscribe.withSelector((state) => state.fileStateArray, (fileStateArray) => onFilesChange?.({ fileStateArray }));
436
- store.subscribe.withSelector((state) => state.errors, (errors) => {
437
- if (errors.length === 0) return;
438
- store.setState({ isInvalid: true });
439
- });
440
- store.subscribe.withSelector((state) => state.isInvalid, (isInvalid) => {
441
- if (!isInvalid) return;
442
- setTimeout(() => store.setState({ isInvalid: !isInvalid }), 1500);
443
- });
444
- return store;
445
- };
446
-
447
- //#endregion
448
- //#region src/components/ui/drop-zone/use-drop-zone.ts
449
- const useDropZone = (props) => {
450
- const { allowedFileTypes, disabled = false, disableInternalStateSubscription = false, disablePreviewForNonImageFiles = true, initialFiles, maxFileCount, maxFileSize, multiple, onFilesChange, onUpload, onValidationError, onValidationSuccess, rejectDuplicateFiles = true, shouldOpenFilePickerOnAreaClick = true, validator } = props ?? {};
451
- const inputRef = useRef(null);
452
- const savedOnFilesChange = useCallbackRef(onFilesChange);
453
- const savedOnUpload = useCallbackRef(onUpload);
454
- const savedOnUploadError = useCallbackRef(onValidationError);
455
- const savedOnUploadSuccess = useCallbackRef(onValidationSuccess);
456
- const savedValidator = useCallbackRef(validator);
457
- const constantInitialFiles = useConstant(() => initialFiles);
458
- const shallowComparedMaxFileSize = useShallowCompValue(maxFileSize);
459
- const shallowComparedAllowedFileTypes = useShallowCompValue(allowedFileTypes);
460
- const storeApi = useMemo(() => {
461
- return createDropZoneStore({
462
- allowedFileTypes: shallowComparedAllowedFileTypes,
463
- disablePreviewForNonImageFiles,
464
- initialFiles: constantInitialFiles,
465
- inputRef,
466
- maxFileCount,
467
- maxFileSize: shallowComparedMaxFileSize,
468
- multiple,
469
- onFilesChange: savedOnFilesChange,
470
- onUpload: savedOnUpload,
471
- onValidationError: savedOnUploadError,
472
- onValidationSuccess: savedOnUploadSuccess,
473
- rejectDuplicateFiles,
474
- validator: savedValidator
475
- });
476
- }, [
477
- shallowComparedAllowedFileTypes,
478
- disablePreviewForNonImageFiles,
479
- constantInitialFiles,
480
- maxFileCount,
481
- shallowComparedMaxFileSize,
482
- multiple,
483
- savedOnFilesChange,
484
- savedOnUpload,
485
- savedOnUploadError,
486
- savedOnUploadSuccess,
487
- rejectDuplicateFiles,
488
- savedValidator
489
- ]);
490
- const actions = storeApi.getState().actions;
491
- useUnmountEffect(() => {
492
- actions.clearObjectURLs();
493
- });
494
- const useDropZoneStore = (selector) => {
495
- return useStore(storeApi, selector);
496
- };
497
- const isDraggingOver = useDropZoneStore((state) => !disableInternalStateSubscription ? state.isDraggingOver : null);
498
- const hasFiles = useDropZoneStore((state) => !disableInternalStateSubscription ? state.fileStateArray.length > 0 : null);
499
- const isInvalid = useDropZoneStore((state) => !disableInternalStateSubscription ? state.isInvalid : null);
500
- const getContainerProps = useCallback((innerProps) => {
501
- const isDisabled = disabled;
502
- const onFileDrop = !isDisabled ? actions.handleDrop : void 0;
503
- const onFilePaste = !isDisabled ? actions.handlePaste : void 0;
504
- const onKeyDown = !isDisabled ? actions.handleKeyDown : void 0;
505
- const tabIndex = !isDisabled ? 0 : void 0;
506
- const onAreaClick = !isDisabled && shouldOpenFilePickerOnAreaClick ? actions.openFilePicker : void 0;
507
- return {
508
- ...getScopeAttrs("container"),
509
- role: "region",
510
- ...!disableInternalStateSubscription && {
511
- "data-drag-over": dataAttr(isDraggingOver),
512
- "data-invalid": dataAttr(isInvalid)
513
- },
514
- ...innerProps,
515
- className: cnMerge(`relative flex flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed
516
- p-6 transition-colors duration-250 ease-out outline-none select-none hover:bg-zu-accent/30
517
- focus-visible:border-zu-ring/50`, `data-[disabled]:pointer-events-none data-[drag-over]:border-zu-primary/30
518
- data-[drag-over]:bg-zu-accent/30 data-[dragging]:bg-zu-accent/30
519
- data-[invalid]:border-zu-destructive data-[invalid]:ring-zu-destructive/20`, innerProps.className),
520
- "data-disabled": dataAttr(isDisabled),
521
- onClick: composeTwoEventHandlers(onAreaClick, innerProps.onClick),
522
- onDragEnter: composeTwoEventHandlers(actions.handleDragEnter, innerProps.onDragEnter),
523
- onDragLeave: composeTwoEventHandlers(actions.handleDragLeave, innerProps.onDragLeave),
524
- onDragOver: composeTwoEventHandlers(actions.handleDragOver, innerProps.onDragOver),
525
- onDrop: composeTwoEventHandlers(onFileDrop, innerProps.onDrop),
526
- onKeyDown: composeTwoEventHandlers(onKeyDown, innerProps.onKeyDown),
527
- onPaste: composeTwoEventHandlers(onFilePaste, innerProps.onPaste),
528
- tabIndex
529
- };
530
- }, [
531
- actions.handleDragEnter,
532
- actions.handleDragLeave,
533
- actions.handleDragOver,
534
- actions.handleDrop,
535
- actions.handleKeyDown,
536
- actions.handlePaste,
537
- actions.openFilePicker,
538
- disableInternalStateSubscription,
539
- disabled,
540
- isDraggingOver,
541
- isInvalid,
542
- shouldOpenFilePickerOnAreaClick
543
- ]);
544
- const getInputProps = useCallback((innerProps) => {
545
- const isDisabled = innerProps.disabled ?? disabled;
546
- const onFileChange = !isDisabled ? actions.handleChange : void 0;
547
- return {
548
- ...getScopeAttrs("input"),
549
- ...!disableInternalStateSubscription && { "data-drag-over": dataAttr(isDraggingOver) },
550
- ...innerProps,
551
- accept: allowedFileTypes ? allowedFileTypes.join(", ") : innerProps.accept,
552
- className: cnMerge("hidden", innerProps.className),
553
- "data-disabled": dataAttr(isDisabled),
554
- disabled: isDisabled,
555
- multiple: multiple ?? innerProps.multiple,
556
- onChange: composeTwoEventHandlers(onFileChange, innerProps.onChange),
557
- ref: composeRefs(inputRef, innerProps.ref),
558
- type: "file"
559
- };
560
- }, [
561
- actions.handleChange,
562
- allowedFileTypes,
563
- disableInternalStateSubscription,
564
- disabled,
565
- isDraggingOver,
566
- multiple
567
- ]);
568
- const getTriggerProps = useCallback((innerProps) => {
569
- const isDisabled = innerProps.disabled ?? disabled;
570
- return {
571
- ...getScopeAttrs("trigger"),
572
- type: "button",
573
- ...innerProps,
574
- "data-disabled": dataAttr(isDisabled),
575
- disabled: isDisabled,
576
- onClick: composeTwoEventHandlers(actions.openFilePicker, innerProps.onClick)
577
- };
578
- }, [actions.openFilePicker, disabled]);
579
- const getFileListProps = useCallback((innerProps) => {
580
- const { orientation = "vertical",...restOfInnerProps } = innerProps;
581
- return {
582
- ...getScopeAttrs("file-list"),
583
- "data-orientation": orientation,
584
- ...!disableInternalStateSubscription && { "data-state": hasFiles ? "active" : "inactive" },
585
- ...restOfInnerProps,
586
- className: cnMerge(`flex flex-col gap-2 data-[state=active]:animate-files-in data-[state=inactive]:animate-out
587
- data-[state=inactive]:fade-out-0 data-[state=inactive]:slide-out-to-top-2`, orientation === "horizontal" && "flex-row overflow-x-auto p-1.5", innerProps.className)
588
- };
589
- }, [disableInternalStateSubscription, hasFiles]);
590
- const getFileItemProps = useCallbackRef((innerProps) => {
591
- return {
592
- ...getScopeAttrs("file-item"),
593
- ...innerProps,
594
- className: cnMerge("relative flex items-center gap-2.5 rounded-md border p-2", innerProps.className)
595
- };
596
- });
597
- const getFileItemProgressProps = useCallbackRef((innerProps) => {
598
- const { variant = "linear",...restOfInnerProps } = innerProps;
599
- return {
600
- ...getScopeAttrs("file-item-progress"),
601
- role: "progressbar",
602
- ...restOfInnerProps,
603
- className: cnMerge("inline-flex", variant === "circular" && "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2", variant === "fill" && `absolute inset-0 bg-zu-primary/50 transition-[clip-path] duration-300 ease-linear
604
- [clip-path:var(--clip-path)]`, variant === "linear" && "relative h-1.5 w-full overflow-hidden rounded-full bg-zu-primary/20", restOfInnerProps.className)
605
- };
606
- });
607
- const getFileItemDeleteProps = useCallback((innerProps) => {
608
- const { fileStateOrID,...restOfInnerProps } = innerProps;
609
- const isDisabled = innerProps.disabled ?? disabled;
610
- const onRemoveFile = () => fileStateOrID && actions.removeFile({ fileStateOrID });
611
- return {
612
- ...getScopeAttrs("file-item-delete"),
613
- type: "button",
614
- ...restOfInnerProps,
615
- "data-disabled": dataAttr(isDisabled),
616
- disabled: isDisabled,
617
- onClick: composeTwoEventHandlers(onRemoveFile, restOfInnerProps.onClick)
618
- };
619
- }, [actions, disabled]);
620
- const getFileItemPreviewProps = useCallbackRef((innerProps) => {
621
- return {
622
- ...getScopeAttrs("file-item-preview"),
623
- ...innerProps,
624
- className: cnMerge(`relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-md
625
- bg-zu-accent/50 [&>svg]:size-10`, innerProps.className)
626
- };
627
- });
628
- const getFileItemMetadataProps = useCallbackRef((innerProps) => {
629
- return {
630
- ...getScopeAttrs("file-item-metadata"),
631
- ...innerProps,
632
- className: cnMerge("flex min-w-0 grow flex-col", innerProps.className)
633
- };
634
- });
635
- const getFileItemClearProps = useCallback((innerProps) => {
636
- const isDisabled = innerProps.disabled ?? disabled;
637
- return {
638
- ...getScopeAttrs("file-item-clear"),
639
- type: "button",
640
- ...innerProps,
641
- "data-disabled": dataAttr(isDisabled),
642
- disabled: isDisabled,
643
- onClick: composeTwoEventHandlers(actions.clearFiles, innerProps.onClick)
644
- };
645
- }, [actions.clearFiles, disabled]);
646
- const propGetters = useMemo(() => ({
647
- getContainerProps,
648
- getFileItemClearProps,
649
- getFileItemDeleteProps,
650
- getFileItemMetadataProps,
651
- getFileItemPreviewProps,
652
- getFileItemProgressProps,
653
- getFileItemProps,
654
- getFileListProps,
655
- getInputProps,
656
- getTriggerProps
657
- }), [
658
- getContainerProps,
659
- getFileListProps,
660
- getFileItemClearProps,
661
- getFileItemDeleteProps,
662
- getFileItemMetadataProps,
663
- getFileItemPreviewProps,
664
- getFileItemProgressProps,
665
- getFileItemProps,
666
- getInputProps,
667
- getTriggerProps
668
- ]);
669
- const savedUseDropZoneStore = useCallbackRef(useDropZoneStore);
670
- return useMemo(() => ({
671
- disabled,
672
- disableInternalStateSubscription,
673
- inputRef,
674
- propGetters,
675
- storeApi,
676
- useDropZoneStore: savedUseDropZoneStore
677
- }), [
678
- disabled,
679
- disableInternalStateSubscription,
680
- propGetters,
681
- storeApi,
682
- savedUseDropZoneStore
683
- ]);
684
- };
685
-
686
- //#endregion
687
- //#region src/components/ui/drop-zone/drop-zone.tsx
688
- function DropZoneRoot(props) {
689
- const { children,...restOfProps } = props;
690
- const { disabled, disableInternalStateSubscription, inputRef, propGetters, storeApi } = useDropZone(restOfProps);
691
- const rootContextValue = useMemo(() => ({
692
- disabled,
693
- disableInternalStateSubscription,
694
- inputRef,
695
- propGetters
696
- }), [
697
- disableInternalStateSubscription,
698
- disabled,
699
- inputRef,
700
- propGetters
701
- ]);
702
- return /* @__PURE__ */ jsx(DropZoneStoreContextProvider, {
703
- store: storeApi,
704
- children: /* @__PURE__ */ jsx(DropZoneRootContextProvider, {
705
- value: rootContextValue,
706
- children
707
- })
708
- });
709
- }
710
- function DropZoneContext(props) {
711
- const { children, selector } = props;
712
- const dropZoneCtx = useDropZoneStoreContext(useShallowCompSelector(selector));
713
- return isFunction(children) ? children(dropZoneCtx) : children;
714
- }
715
- function DropZoneContainer(props) {
716
- const { as: Element = "div", asChild,...restOfProps } = props;
717
- const { disableInternalStateSubscription, propGetters } = useDropZoneRootContext();
718
- const isDraggingOver = useDropZoneStoreContext((store) => disableInternalStateSubscription ? store.isDraggingOver : null);
719
- const isInvalid = useDropZoneStoreContext((store) => disableInternalStateSubscription ? store.isInvalid : null);
720
- const Component$1 = asChild ? SlotRoot : Element;
721
- return /* @__PURE__ */ jsx(Component$1, { ...propGetters.getContainerProps({
722
- ...disableInternalStateSubscription && {
723
- "data-drag-over": dataAttr(isDraggingOver),
724
- "data-invalid": dataAttr(isInvalid)
725
- },
726
- ...restOfProps
727
- }) });
728
- }
729
- function DropZoneInput(props) {
730
- const { asChild,...restOfProps } = props;
731
- const { disableInternalStateSubscription, propGetters } = useDropZoneRootContext();
732
- const isDraggingOver = useDropZoneStoreContext((store) => disableInternalStateSubscription ? store.isDraggingOver : null);
733
- const Component$1 = asChild ? SlotRoot : "input";
734
- return /* @__PURE__ */ jsx(Component$1, { ...propGetters.getInputProps({
735
- ...disableInternalStateSubscription && { "data-drag-over": dataAttr(isDraggingOver) },
736
- ...restOfProps
737
- }) });
738
- }
739
- function DropZoneArea(props) {
740
- const { children, classNames, extraProps, selector } = props;
741
- return /* @__PURE__ */ jsxs(DropZoneContainer, {
742
- ...extraProps?.container,
743
- className: classNames?.container,
744
- children: [/* @__PURE__ */ jsx(DropZoneInput, {
745
- ...extraProps?.input,
746
- className: classNames?.input
747
- }), /* @__PURE__ */ jsx(DropZoneContext, {
748
- selector,
749
- children
750
- })]
751
- });
752
- }
753
- function DropZoneTrigger(props) {
754
- const { asChild,...restOfProps } = props;
755
- const { propGetters } = useDropZoneRootContext();
756
- const Component$1 = asChild ? SlotRoot : "button";
757
- return /* @__PURE__ */ jsx(Component$1, { ...propGetters.getTriggerProps(restOfProps) });
758
- }
759
- function DropZoneFileList(props) {
760
- const { as: Element = "ul", asChild, children, forceMount = false, renderMode = "per-item",...restOfProps } = props;
761
- const fileStateArray = useDropZoneStoreContext((store) => store.fileStateArray);
762
- const actions = useDropZoneStoreContext((store) => store.actions);
763
- const { disableInternalStateSubscription, propGetters } = useDropZoneRootContext();
764
- const childrenMap = {
765
- "manual-list": () => {
766
- return children({
767
- actions,
768
- fileStateArray
769
- });
770
- },
771
- "per-item": () => {
772
- const childrenFn = children;
773
- return /* @__PURE__ */ jsx(For, {
774
- each: fileStateArray,
775
- renderItem: (fileState, index, array) => childrenFn({
776
- actions,
777
- array,
778
- fileState,
779
- index
780
- })
781
- });
782
- }
783
- };
784
- const hasFiles = fileStateArray.length > 0;
785
- const Component$1 = asChild ? SlotRoot : Element;
786
- return /* @__PURE__ */ jsx(Presence, {
787
- present: hasFiles,
788
- forceMount,
789
- children: /* @__PURE__ */ jsx(Component$1, {
790
- ...propGetters.getFileListProps({
791
- ...disableInternalStateSubscription && { "data-state": hasFiles ? "active" : "inactive" },
792
- ...restOfProps
793
- }),
794
- children: isFunction(children) ? childrenMap[renderMode]() : children
795
- })
796
- });
797
- }
798
- function DropZoneFileItem(props) {
799
- const { as: Element = "li", asChild, fileState,...restOfProps } = props;
800
- const { propGetters } = useDropZoneRootContext();
801
- const Component$1 = asChild ? SlotRoot : Element;
802
- const contextValue = useMemo(() => ({ fileState }), [fileState]);
803
- return /* @__PURE__ */ jsx(FileItemContextProvider, {
804
- value: contextValue,
805
- children: /* @__PURE__ */ jsx(Component$1, { ...propGetters.getFileItemProps(restOfProps) })
806
- });
807
- }
808
- function DropZoneFileItemDelete(props) {
809
- const { asChild, fileStateOrID,...restOfProps } = props;
810
- const { propGetters } = useDropZoneRootContext();
811
- const fileItemContextValue = useFileItemContext();
812
- const Component$1 = asChild ? SlotRoot : "button";
813
- const resolvedFileStateOrID = fileStateOrID ?? fileItemContextValue?.fileState;
814
- return /* @__PURE__ */ jsx(Component$1, { ...propGetters.getFileItemDeleteProps({
815
- fileStateOrID: resolvedFileStateOrID,
816
- ...restOfProps
817
- }) });
818
- }
819
- function DropZoneFileItemProgress(props) {
820
- const { as: Element = "span", asChild, forceMount = false, size = 40, variant = "linear",...restOfProps } = props;
821
- const fileState = useFileItemContext()?.fileState;
822
- const { propGetters } = useDropZoneRootContext();
823
- if (!fileState) return null;
824
- const currentProgress = fileState.progress;
825
- if (!(forceMount || fileState.progress !== 100)) return null;
826
- const Component$1 = asChild ? SlotRoot : Element;
827
- const componentProps = propGetters.getFileItemProgressProps({
828
- variant,
829
- ...restOfProps
830
- });
831
- switch (variant) {
832
- case "circular": {
833
- const circumference = 2 * Math.PI * ((size - 4) / 2);
834
- const strokeDashoffset = circumference - currentProgress / 100 * circumference;
835
- return /* @__PURE__ */ jsx(Component$1, {
836
- ...componentProps,
837
- children: /* @__PURE__ */ jsxs("svg", {
838
- className: "-rotate-90",
839
- width: size,
840
- height: size,
841
- viewBox: `0 0 ${size} ${size}`,
842
- fill: "none",
843
- stroke: "currentColor",
844
- children: [/* @__PURE__ */ jsx("circle", {
845
- className: "text-zu-primary/20",
846
- strokeWidth: "2",
847
- cx: size / 2,
848
- cy: size / 2,
849
- r: (size - 4) / 2
850
- }), /* @__PURE__ */ jsx("circle", {
851
- className: "text-zu-primary transition-[stroke-dashoffset] duration-300 ease-linear",
852
- strokeWidth: "2",
853
- strokeLinecap: "round",
854
- strokeDasharray: circumference,
855
- strokeDashoffset,
856
- cx: size / 2,
857
- cy: size / 2,
858
- r: (size - 4) / 2
859
- })]
860
- })
861
- });
862
- }
863
- case "fill": {
864
- const topInset = 100 - currentProgress;
865
- return /* @__PURE__ */ jsx(Component$1, {
866
- ...componentProps,
867
- style: { "--clip-path": `inset(${topInset}% 0% 0% 0%)` }
868
- });
869
- }
870
- case "linear": return /* @__PURE__ */ jsx(Component$1, {
871
- ...componentProps,
872
- children: /* @__PURE__ */ jsx("span", {
873
- className: "inline-block size-full grow translate-x-(--translate-distance) bg-zu-primary transition-transform duration-300 ease-linear",
874
- style: { "--translate-distance": `-${100 - currentProgress}%` }
875
- })
876
- });
877
- default: return null;
878
- }
879
- }
880
- function DropZoneFileItemPreview(props) {
881
- const { as: Element = "span", asChild, children, fileState: fileStateProp, renderPreview = true,...restOfProps } = props;
882
- const fileItemContextValue = useFileItemContext();
883
- const { propGetters } = useDropZoneRootContext();
884
- const fileState = fileStateProp ?? fileItemContextValue?.fileState;
885
- if (!fileState) return null;
886
- const Component$1 = asChild ? SlotRoot : Element;
887
- const resolvedChildren = isFunction(children) ? children({ fileState }) : children;
888
- return /* @__PURE__ */ jsxs(Component$1, {
889
- ...propGetters.getFileItemPreviewProps(restOfProps),
890
- children: [renderPreview && getFilePreviewOrIcon({
891
- fileState,
892
- renderPreview
893
- }), resolvedChildren]
894
- });
895
- }
896
- const getFilePreviewOrIcon = (context) => {
897
- const { fileState, renderPreview } = context;
898
- const type = fileState?.file.type;
899
- const extension = fileState?.file.name?.split(".").pop()?.toLowerCase() ?? "";
900
- const renderPreviewObject = isFunction(renderPreview) ? renderPreview({ fileState }) : {};
901
- const getDefaultPreview = () => {
902
- return renderPreviewObject.default?.node ?? /* @__PURE__ */ jsx(FileIcon, { className: renderPreviewObject.default?.className });
903
- };
904
- if (!type) return getDefaultPreview();
905
- switch (true) {
906
- case type.startsWith("image/"): return renderPreviewObject.image?.node ?? /* @__PURE__ */ jsx("img", {
907
- src: fileState.preview,
908
- alt: fileState.file.name,
909
- className: cnMerge("size-full object-cover", renderPreviewObject.image?.className)
910
- });
911
- case type.startsWith("video/"): return renderPreviewObject.video?.node ?? /* @__PURE__ */ jsx(FileVideoIcon, { className: cnMerge("size-full object-cover", renderPreviewObject.video?.className) });
912
- case type.startsWith("audio/"): return renderPreviewObject.audio?.node ?? /* @__PURE__ */ jsx(FileAudioIcon, { className: cnMerge("size-full object-cover", renderPreviewObject.audio?.className) });
913
- case type.startsWith("text/") || [
914
- "md",
915
- "pdf",
916
- "rtf",
917
- "txt"
918
- ].includes(extension): return renderPreviewObject.text?.node ?? /* @__PURE__ */ jsx(FileTextIcon, { className: renderPreviewObject.text?.className });
919
- case [
920
- "c",
921
- "cpp",
922
- "cs",
923
- "css",
924
- "html",
925
- "java",
926
- "js",
927
- "json",
928
- "jsx",
929
- "php",
930
- "py",
931
- "rb",
932
- "ts",
933
- "tsx",
934
- "xml"
935
- ].includes(extension): return renderPreviewObject.code?.node ?? /* @__PURE__ */ jsx(FileCodeIcon, { className: renderPreviewObject.code?.className });
936
- case [
937
- "7z",
938
- "bz2",
939
- "gz",
940
- "rar",
941
- "tar",
942
- "zip"
943
- ].includes(extension): return renderPreviewObject.archive?.node ?? /* @__PURE__ */ jsx(FileArchiveIcon, { className: renderPreviewObject.archive?.className });
944
- case [
945
- "apk",
946
- "app",
947
- "deb",
948
- "exe",
949
- "msi",
950
- "rpm"
951
- ].includes(extension): return renderPreviewObject.executable?.node ?? /* @__PURE__ */ jsx(FileCogIcon, { className: renderPreviewObject.executable?.className });
952
- default: return getDefaultPreview();
953
- }
954
- };
955
- function DropZoneFileItemMetadata(props) {
956
- const { asChild, children, classNames, fileState: fileStateProp, size = "default",...restOfProps } = props;
957
- const fileItemContextValue = useFileItemContext();
958
- const { propGetters } = useDropZoneRootContext();
959
- const fileState = fileStateProp ?? fileItemContextValue?.fileState;
960
- if (!fileState) return null;
961
- const Component$1 = asChild ? SlotRoot : "div";
962
- const resolvedChildren = isFunction(children) ? children({ fileState }) : children;
963
- const getDefaultMetadataChildren = () => {
964
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
965
- /* @__PURE__ */ jsx("p", {
966
- className: cnMerge("truncate", size === "default" && "text-[14px] font-medium", size === "sm" && "text-[13px] leading-snug", classNames?.name),
967
- children: fileState.file.name
968
- }),
969
- /* @__PURE__ */ jsx("p", {
970
- className: cnMerge("truncate text-zu-muted-foreground", size === "default" && "text-[12px]", size === "sm" && "text-[11px] leading-snug", classNames?.size),
971
- children: isNumber(fileState.file.size) && formatBytes(fileState.file.size)
972
- }),
973
- fileState.error && /* @__PURE__ */ jsx("p", {
974
- className: "text-[12px] text-zu-destructive",
975
- children: fileState.error.message
976
- })
977
- ] });
978
- };
979
- return /* @__PURE__ */ jsx(Component$1, {
980
- ...propGetters.getFileItemMetadataProps(restOfProps),
981
- children: resolvedChildren ?? getDefaultMetadataChildren()
982
- });
983
- }
984
- function DropZoneFileClear(props) {
985
- const { asChild, forceMount = false,...restOfProps } = props;
986
- const { propGetters } = useDropZoneRootContext();
987
- const fileCount = useDropZoneStoreContext((state) => state.fileStateArray.length);
988
- if (!(forceMount || fileCount > 0)) return null;
989
- const Component$1 = asChild ? SlotRoot : "button";
990
- return /* @__PURE__ */ jsx(Component$1, { ...propGetters.getFileItemClearProps(restOfProps) });
991
- }
992
-
993
- //#endregion
994
- //#region src/components/ui/drop-zone/drop-zone-parts.ts
995
- var drop_zone_parts_exports = __export({
996
- Area: () => DropZoneArea,
997
- Container: () => DropZoneContainer,
998
- Context: () => DropZoneContext,
999
- FileClear: () => DropZoneFileClear,
1000
- FileItem: () => DropZoneFileItem,
1001
- FileItemDelete: () => DropZoneFileItemDelete,
1002
- FileItemMetadata: () => DropZoneFileItemMetadata,
1003
- FileItemPreview: () => DropZoneFileItemPreview,
1004
- FileItemProgress: () => DropZoneFileItemProgress,
1005
- FileList: () => DropZoneFileList,
1006
- Input: () => DropZoneInput,
1007
- Root: () => DropZoneRoot,
1008
- Trigger: () => DropZoneTrigger
1009
- });
1010
-
1011
- //#endregion
1012
- export { DropZoneArea, DropZoneContainer, DropZoneContext, DropZoneError, DropZoneFileClear, DropZoneFileItem, DropZoneFileItemDelete, DropZoneFileItemMetadata, DropZoneFileItemPreview, DropZoneFileItemProgress, DropZoneFileList, DropZoneInput, DropZoneRoot, DropZoneTrigger, drop_zone_parts_exports, useDropZone, useDropZoneStoreContext };
1013
- //# sourceMappingURL=drop-zone-C9VpKJAD.js.map