@rafal.lemieszewski/tide-ui 0.88.2 → 0.90.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.
@@ -1,61 +1,71 @@
1
- import { jsx as s, jsxs as b } from "react/jsx-runtime";
2
- import * as n from "react";
1
+ import { jsx as i, jsxs as F, Fragment as Z } from "react/jsx-runtime";
2
+ import * as d from "react";
3
3
  import { cn as v } from "../../lib/utils.js";
4
- import { cva as Q } from "class-variance-authority";
5
- import { Button as P } from "./button.js";
6
- import { Progress as Y } from "./progress.js";
7
- import { Icon as z } from "./icon.js";
8
- import { X as Z } from "lucide-react";
9
- import { Badge as _ } from "./badge.js";
10
- const M = n.createContext(
4
+ import { cva as _ } from "class-variance-authority";
5
+ import { Button as z } from "./button.js";
6
+ import { Progress as ee } from "./progress.js";
7
+ import { Icon as M } from "./icon.js";
8
+ import { X as re } from "lucide-react";
9
+ import { Badge as te } from "./badge.js";
10
+ const j = d.createContext(
11
11
  null
12
- ), D = () => {
13
- const r = n.useContext(M);
12
+ ), I = () => {
13
+ const r = d.useContext(j);
14
14
  if (!r)
15
15
  throw new Error("useFileUpload must be used within a FileUpload component");
16
16
  return r;
17
- }, j = /* @__PURE__ */ n.forwardRef(
17
+ };
18
+ function oe(r) {
19
+ return r instanceof File;
20
+ }
21
+ const L = /* @__PURE__ */ d.forwardRef(
18
22
  ({
19
23
  className: r,
20
24
  files: e,
21
25
  onFilesChange: o,
22
26
  maxFiles: t = 10,
23
- maxSize: l = 10 * 1024 * 1024,
27
+ maxSize: a = 10 * 1024 * 1024,
24
28
  // 10MB
25
- accept: i,
26
- disabled: m = !1,
27
- multiple: c = !0,
28
- onUpload: p,
29
- children: u,
30
- ...x
31
- }, w) => {
32
- const g = n.useMemo(
29
+ accept: n,
30
+ disabled: p = !1,
31
+ multiple: m = !0,
32
+ onUpload: c,
33
+ onDelete: u,
34
+ uploadMode: h = "auto",
35
+ children: w,
36
+ ...N
37
+ }, U) => {
38
+ const b = d.useMemo(
33
39
  () => ({
34
40
  files: e,
35
41
  onFilesChange: o,
36
42
  maxFiles: t,
37
- maxSize: l,
38
- accept: i,
39
- disabled: m,
40
- multiple: c,
41
- onUpload: p
43
+ maxSize: a,
44
+ accept: n,
45
+ disabled: p,
46
+ multiple: m,
47
+ onUpload: c,
48
+ onDelete: u,
49
+ uploadMode: h
42
50
  }),
43
51
  [
44
52
  e,
45
53
  o,
46
54
  t,
47
- l,
48
- i,
55
+ a,
56
+ n,
57
+ p,
49
58
  m,
50
59
  c,
51
- p
60
+ u,
61
+ h
52
62
  ]
53
63
  );
54
- return /* @__PURE__ */ s(M.Provider, { value: g, children: /* @__PURE__ */ s("div", { ref: w, className: v("space-y-4", r), ...x, children: u }) });
64
+ return /* @__PURE__ */ i(j.Provider, { value: b, children: /* @__PURE__ */ i("div", { ref: U, className: v("space-y-4", r), ...N, children: w }) });
55
65
  }
56
66
  );
57
- j.displayName = "FileUploadRoot";
58
- const ee = Q(
67
+ L.displayName = "FileUploadRoot";
68
+ const ae = _(
59
69
  "relative flex flex-col items-center justify-center rounded-[var(--border-radius-l)] border-2 border-dashed p-6 text-center transition-colors duration-200",
60
70
  {
61
71
  variants: {
@@ -73,92 +83,97 @@ const ee = Q(
73
83
  disabled: !1
74
84
  }
75
85
  }
76
- ), k = /* @__PURE__ */ n.forwardRef(({ className: r, children: e, ...o }, t) => {
86
+ ), A = /* @__PURE__ */ d.forwardRef(({ className: r, children: e, ...o }, t) => {
77
87
  const {
78
- files: l,
79
- onFilesChange: i,
80
- maxFiles: m,
81
- maxSize: c,
82
- accept: p,
88
+ files: a,
89
+ onFilesChange: n,
90
+ maxFiles: p,
91
+ maxSize: m,
92
+ accept: c,
83
93
  disabled: u,
84
- multiple: x
85
- } = D(), [w, g] = n.useState(!1), y = n.useRef(null), O = (a) => {
86
- if (c && a.size > c)
87
- return `File size must be less than ${E(c)}`;
88
- if (p && p.length > 0) {
89
- const d = a.type, N = `.${a.name.split(".").pop()?.toLowerCase()}`;
90
- if (!p.some((f) => {
94
+ multiple: h,
95
+ onUpload: w,
96
+ uploadMode: N
97
+ } = I(), [U, b] = d.useState(!1), R = d.useRef(null), G = (s) => {
98
+ if (m && s.size > m)
99
+ return `File size must be less than ${S(m)}`;
100
+ if (c && c.length > 0) {
101
+ const l = s.type, y = `.${s.name.split(".").pop()?.toLowerCase()}`;
102
+ if (!c.some((f) => {
91
103
  if (f.startsWith("."))
92
- return f.toLowerCase() === N;
104
+ return f.toLowerCase() === y;
93
105
  if (f.includes("*")) {
94
- const F = f.split("/")[0];
95
- return d.startsWith(F);
106
+ const x = f.split("/")[0];
107
+ return l.startsWith(x);
96
108
  }
97
- return d === f;
109
+ return l === f;
98
110
  }))
99
- return `File type not supported. Accepted types: ${p.join(", ")}`;
111
+ return `File type not supported. Accepted types: ${c.join(", ")}`;
100
112
  }
101
113
  return null;
102
- }, I = (a) => {
103
- const d = [], N = l.length;
104
- Array.from(a).forEach((h, f) => {
105
- if (m && N + d.length >= m) return;
106
- const F = O(h), R = {
114
+ }, C = async (s) => {
115
+ const l = [], y = a.length;
116
+ if (Array.from(s).forEach((g, f) => {
117
+ if (p && y + l.length >= p) return;
118
+ const x = G(g), k = {
107
119
  id: `${Date.now()}-${f}`,
108
- file: h,
109
- status: F ? "error" : "pending",
110
- error: F || void 0,
120
+ file: g,
121
+ status: x ? "error" : "pending",
122
+ error: x || void 0,
111
123
  progress: 0
112
124
  };
113
- if (h.type.startsWith("image/")) {
114
- const C = new FileReader();
115
- C.onload = (H) => {
116
- const J = l.map(
117
- (U) => U.id === R.id ? { ...U, preview: H.target?.result } : U
125
+ if (g.type.startsWith("image/")) {
126
+ const P = new FileReader();
127
+ P.onload = (Q) => {
128
+ const Y = a.map(
129
+ (D) => D.id === k.id ? { ...D, preview: Q.target?.result } : D
118
130
  );
119
- i(J);
120
- }, C.readAsDataURL(h);
131
+ n(Y);
132
+ }, P.readAsDataURL(g);
121
133
  }
122
- d.push(R);
123
- }), d.length > 0 && i([...l, ...d]);
124
- }, S = (a) => {
125
- a.preventDefault(), a.stopPropagation(), u || g(!0);
126
- }, G = (a) => {
127
- a.preventDefault(), a.stopPropagation(), g(!1);
128
- }, K = (a) => {
129
- if (a.preventDefault(), a.stopPropagation(), g(!1), u) return;
130
- const d = a.dataTransfer.files;
131
- d.length > 0 && I(d);
132
- }, X = () => {
133
- u || y.current?.click();
134
- }, q = (a) => {
135
- const d = a.target.files;
136
- d && I(d), a.target.value = "";
134
+ l.push(k);
135
+ }), l.length > 0 && (n([...a, ...l]), N === "auto" && w)) {
136
+ const g = l.filter((f) => f.status !== "error");
137
+ g.length > 0 && await w(g);
138
+ }
139
+ }, K = (s) => {
140
+ s.preventDefault(), s.stopPropagation(), u || b(!0);
141
+ }, X = (s) => {
142
+ s.preventDefault(), s.stopPropagation(), b(!1);
143
+ }, q = (s) => {
144
+ if (s.preventDefault(), s.stopPropagation(), b(!1), u) return;
145
+ const l = s.dataTransfer.files;
146
+ l.length > 0 && C(l);
147
+ }, H = () => {
148
+ u || R.current?.click();
149
+ }, J = (s) => {
150
+ const l = s.target.files;
151
+ l && C(l), s.target.value = "";
137
152
  };
138
- return /* @__PURE__ */ b(
153
+ return /* @__PURE__ */ F(
139
154
  "div",
140
155
  {
141
156
  ref: t,
142
- className: v(ee({ isDragActive: w, disabled: u }), r),
143
- onDragOver: S,
144
- onDragLeave: G,
145
- onDrop: K,
146
- onClick: X,
157
+ className: v(ae({ isDragActive: U, disabled: u }), r),
158
+ onDragOver: K,
159
+ onDragLeave: X,
160
+ onDrop: q,
161
+ onClick: H,
147
162
  role: "button",
148
163
  tabIndex: u ? -1 : 0,
149
164
  "aria-label": "Upload files",
150
165
  ...o,
151
166
  children: [
152
- /* @__PURE__ */ s(
167
+ /* @__PURE__ */ i(
153
168
  "input",
154
169
  {
155
- ref: y,
170
+ ref: R,
156
171
  type: "file",
157
- multiple: x,
158
- accept: p?.join(","),
172
+ multiple: h,
173
+ accept: c?.join(","),
159
174
  disabled: u,
160
175
  className: "hidden",
161
- onChange: q
176
+ onChange: J
162
177
  }
163
178
  ),
164
179
  e
@@ -166,21 +181,26 @@ const ee = Q(
166
181
  }
167
182
  );
168
183
  });
169
- k.displayName = "FileUploadDropzone";
170
- const L = /* @__PURE__ */ n.forwardRef(({ children: r, ...e }, o) => {
171
- const { disabled: t } = D();
172
- return /* @__PURE__ */ s(P, { ref: o, disabled: t, ...e, children: r });
184
+ A.displayName = "FileUploadDropzone";
185
+ const B = /* @__PURE__ */ d.forwardRef(({ children: r, onClick: e, ...o }, t) => {
186
+ const { disabled: a, files: n, onUpload: p } = I();
187
+ return /* @__PURE__ */ i(z, { ref: t, disabled: a, onClick: async (c) => {
188
+ if (e?.(c), p) {
189
+ const u = n.filter((h) => h.status === "pending");
190
+ u.length > 0 && await p(u);
191
+ }
192
+ }, ...o, children: r });
173
193
  });
174
- L.displayName = "FileUploadTrigger";
175
- const A = /* @__PURE__ */ n.forwardRef(
176
- ({ className: r, children: e, ...o }, t) => /* @__PURE__ */ s("div", { ref: t, className: v("space-y-2", r), ...o, children: e })
194
+ B.displayName = "FileUploadTrigger";
195
+ const W = /* @__PURE__ */ d.forwardRef(
196
+ ({ className: r, children: e, ...o }, t) => /* @__PURE__ */ i("div", { ref: t, className: v("space-y-2", r), ...o, children: e })
177
197
  );
178
- A.displayName = "FileUploadList";
179
- const B = /* @__PURE__ */ n.forwardRef(
180
- ({ className: r, file: e, children: o, ...t }, l) => /* @__PURE__ */ s(
198
+ W.displayName = "FileUploadList";
199
+ const $ = /* @__PURE__ */ d.forwardRef(
200
+ ({ className: r, file: e, children: o, ...t }, a) => /* @__PURE__ */ i(
181
201
  "div",
182
202
  {
183
- ref: l,
203
+ ref: a,
184
204
  className: v(
185
205
  "flex items-center gap-3 rounded-[var(--border-radius-l)] border p-3",
186
206
  "border-[var(--color-border-primary)]",
@@ -193,10 +213,10 @@ const B = /* @__PURE__ */ n.forwardRef(
193
213
  }
194
214
  )
195
215
  );
196
- B.displayName = "FileUploadItem";
197
- const W = /* @__PURE__ */ n.forwardRef(({ className: r, file: e, ...o }, t) => {
198
- const l = (i) => i.startsWith("image/") ? "image" : i.startsWith("video/") ? "video" : i.startsWith("audio/") ? "volume-2" : i.includes("pdf") || i.includes("text/") || i.includes("application/json") ? "file-text" : "file";
199
- return /* @__PURE__ */ s(
216
+ $.displayName = "FileUploadItem";
217
+ const V = /* @__PURE__ */ d.forwardRef(({ className: r, file: e, ...o }, t) => {
218
+ const a = (n) => n.startsWith("image/") ? "image" : n.startsWith("video/") ? "video" : n.startsWith("audio/") ? "volume-2" : n.includes("pdf") || n.includes("text/") || n.includes("application/json") ? "file-text" : "file";
219
+ return /* @__PURE__ */ i(
200
220
  "div",
201
221
  {
202
222
  ref: t,
@@ -205,86 +225,92 @@ const W = /* @__PURE__ */ n.forwardRef(({ className: r, file: e, ...o }, t) => {
205
225
  r
206
226
  ),
207
227
  ...o,
208
- children: e.preview ? /* @__PURE__ */ s(
228
+ children: e.preview && oe(e.file) ? /* @__PURE__ */ i(
209
229
  "img",
210
230
  {
211
231
  src: e.preview,
212
232
  alt: e.file.name,
213
233
  className: "h-full w-full rounded object-cover"
214
234
  }
215
- ) : /* @__PURE__ */ s(
216
- z,
235
+ ) : /* @__PURE__ */ i(
236
+ M,
217
237
  {
218
- name: l(e.file.type),
238
+ name: a(e.file.type ?? ""),
219
239
  className: "h-5 w-5 text-[var(--color-text-secondary)]"
220
240
  }
221
241
  )
222
242
  }
223
243
  );
224
244
  });
225
- W.displayName = "FileUploadItemPreview";
226
- const $ = /* @__PURE__ */ n.forwardRef(({ className: r, file: e, ...o }, t) => /* @__PURE__ */ b("div", { ref: t, className: v("flex-1 space-y-1", r), ...o, children: [
227
- /* @__PURE__ */ b("div", { className: "flex items-center gap-2", children: [
228
- /* @__PURE__ */ s("p", { className: "text-body-sm truncate font-medium", children: e.file.name }),
229
- /* @__PURE__ */ s(_, { children: e.status })
245
+ V.displayName = "FileUploadItemPreview";
246
+ const T = /* @__PURE__ */ d.forwardRef(({ className: r, file: e, children: o, ...t }, a) => /* @__PURE__ */ i("div", { ref: a, className: v("flex-1 space-y-1", r), ...t, children: o ?? /* @__PURE__ */ F(Z, { children: [
247
+ /* @__PURE__ */ F("div", { className: "flex items-center gap-2", children: [
248
+ /* @__PURE__ */ i("p", { className: "text-body-sm truncate font-medium", children: e.file.name }),
249
+ /* @__PURE__ */ i(te, { children: e.status })
230
250
  ] }),
231
- /* @__PURE__ */ s("p", { className: "text-caption-sm text-[var(--color-text-secondary)]", children: E(e.file.size) }),
232
- e.error && /* @__PURE__ */ s("p", { className: "text-caption-sm text-[var(--color-text-error-bold)]", children: e.error })
233
- ] }));
234
- $.displayName = "FileUploadItemMetadata";
235
- const V = /* @__PURE__ */ n.forwardRef(({ className: r, file: e, variant: o = "linear", ...t }, l) => e.status !== "uploading" || e.progress === void 0 ? null : /* @__PURE__ */ b("div", { ref: l, className: v("w-full", r), ...t, children: [
236
- /* @__PURE__ */ s(Y, { value: e.progress, className: "h-2" }),
237
- /* @__PURE__ */ b("p", { className: "text-caption-sm mt-1 text-[var(--color-text-secondary)]", children: [
251
+ /* @__PURE__ */ i("p", { className: "text-caption-sm text-[var(--color-text-secondary)]", children: S(e.file.size) }),
252
+ e.error && /* @__PURE__ */ i("p", { className: "text-caption-sm text-[var(--color-text-error-bold)]", children: e.error })
253
+ ] }) }));
254
+ T.displayName = "FileUploadItemMetadata";
255
+ const E = /* @__PURE__ */ d.forwardRef(({ className: r, file: e, variant: o = "linear", ...t }, a) => e.status !== "uploading" || e.progress === void 0 ? null : /* @__PURE__ */ F("div", { ref: a, className: v("w-full", r), ...t, children: [
256
+ /* @__PURE__ */ i(ee, { value: e.progress, className: "h-2" }),
257
+ /* @__PURE__ */ F("p", { className: "text-caption-sm mt-1 text-[var(--color-text-secondary)]", children: [
238
258
  Math.round(e.progress),
239
259
  "%"
240
260
  ] })
241
261
  ] }));
242
- V.displayName = "FileUploadItemProgress";
243
- const T = /* @__PURE__ */ n.forwardRef(({ file: r, ...e }, o) => {
244
- const { files: t, onFilesChange: l } = D();
245
- return /* @__PURE__ */ s(
246
- P,
262
+ E.displayName = "FileUploadItemProgress";
263
+ const O = /* @__PURE__ */ d.forwardRef(({ file: r, ...e }, o) => {
264
+ const { files: t, onFilesChange: a, onDelete: n } = I();
265
+ return /* @__PURE__ */ i(
266
+ z,
247
267
  {
248
268
  ref: o,
249
269
  variant: "ghost",
250
270
  size: "s",
251
- onClick: () => {
271
+ onClick: async () => {
272
+ if (n)
273
+ try {
274
+ await n(r);
275
+ } catch {
276
+ return;
277
+ }
252
278
  const m = t.filter((c) => c.id !== r.id);
253
- l(m);
279
+ a(m);
254
280
  },
255
281
  "aria-label": `Remove ${r.file.name}`,
256
282
  ...e,
257
- children: /* @__PURE__ */ s(z, { name: Z, className: "h-4 w-4" })
283
+ children: /* @__PURE__ */ i(M, { name: re, className: "h-4 w-4" })
258
284
  }
259
285
  );
260
286
  });
261
- T.displayName = "FileUploadItemDelete";
262
- const E = (r) => {
287
+ O.displayName = "FileUploadItemDelete";
288
+ const S = (r) => {
263
289
  if (r === 0) return "0 Bytes";
264
290
  const e = 1024, o = ["Bytes", "KB", "MB", "GB"], t = Math.floor(Math.log(r) / Math.log(e));
265
291
  return parseFloat((r / Math.pow(e, t)).toFixed(2)) + " " + o[t];
266
- }, de = {
267
- Root: j,
268
- Dropzone: k,
269
- Trigger: L,
270
- List: A,
271
- Item: B,
272
- ItemPreview: W,
273
- ItemMetadata: $,
274
- ItemProgress: V,
275
- ItemDelete: T
292
+ }, me = {
293
+ Root: L,
294
+ Dropzone: A,
295
+ Trigger: B,
296
+ List: W,
297
+ Item: $,
298
+ ItemPreview: V,
299
+ ItemMetadata: T,
300
+ ItemProgress: E,
301
+ ItemDelete: O
276
302
  };
277
303
  export {
278
- de as FileUpload,
279
- k as FileUploadDropzone,
280
- B as FileUploadItem,
281
- T as FileUploadItemDelete,
282
- $ as FileUploadItemMetadata,
283
- W as FileUploadItemPreview,
284
- V as FileUploadItemProgress,
285
- A as FileUploadList,
286
- j as FileUploadRoot,
287
- L as FileUploadTrigger,
288
- E as formatFileSize,
289
- D as useFileUpload
304
+ me as FileUpload,
305
+ A as FileUploadDropzone,
306
+ $ as FileUploadItem,
307
+ O as FileUploadItemDelete,
308
+ T as FileUploadItemMetadata,
309
+ V as FileUploadItemPreview,
310
+ E as FileUploadItemProgress,
311
+ W as FileUploadList,
312
+ L as FileUploadRoot,
313
+ B as FileUploadTrigger,
314
+ S as formatFileSize,
315
+ I as useFileUpload
290
316
  };