@alixpartners/ui-components 2.4.3 → 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DragAndDrop/DragAndDrop.d.ts +3 -2
- package/dist/components/DragAndDrop/DragAndDrop.js +76 -78
- package/dist/components/DragAndDrop/DragAndDrop.test.js +16 -12
- package/dist/components/FilePicker/FilePicker.d.ts +2 -2
- package/dist/components/FilePicker/FilePicker.js +110 -112
- package/dist/components/FilePicker/FilePicker.test.js +90 -86
- package/package.json +1 -1
|
@@ -45,9 +45,10 @@ type DragAndDropProps = {
|
|
|
45
45
|
onUpload?: (files: UploadFile[]) => void;
|
|
46
46
|
/**
|
|
47
47
|
* Callback fired when a file is removed.
|
|
48
|
-
* @param
|
|
48
|
+
* @param removedFile - The file that was removed
|
|
49
|
+
* @param remaining - The list of files remaining after removal
|
|
49
50
|
*/
|
|
50
|
-
onRemoveFile?: (
|
|
51
|
+
onRemoveFile?: (removedFile: File, remaining: UploadFile[]) => void;
|
|
51
52
|
queueFiles?: boolean;
|
|
52
53
|
maxSizeErrorMessage?: string;
|
|
53
54
|
fileExtensionInvalidErrorMessage?: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs as _, jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { useId as vr, useRef as Lr, useState as J, useCallback as
|
|
2
|
+
import { useId as vr, useRef as Lr, useState as J, useCallback as g, useMemo as A } from "react";
|
|
3
3
|
import K from "../Button/Button.js";
|
|
4
4
|
import { c as U } from "../../clsx-OuTLNxxd.js";
|
|
5
5
|
import x from "../Icon/Icon.js";
|
|
6
|
-
import '../../assets/DragAndDrop.css';const Cr = "DragAndDrop-module__disabled___h47do", br = "DragAndDrop-module__required___z3cHB", Or = "DragAndDrop-module__active___ZMuEx",
|
|
6
|
+
import '../../assets/DragAndDrop.css';const Cr = "DragAndDrop-module__disabled___h47do", br = "DragAndDrop-module__required___z3cHB", Or = "DragAndDrop-module__active___ZMuEx", d = {
|
|
7
7
|
"drag-and-drop-container": "DragAndDrop-module__drag-and-drop-container___WHqGh",
|
|
8
8
|
disabled: Cr,
|
|
9
9
|
required: br,
|
|
@@ -24,23 +24,23 @@ import '../../assets/DragAndDrop.css';const Cr = "DragAndDrop-module__disabled__
|
|
|
24
24
|
"drag-and-drop-files-list-item-error": "DragAndDrop-module__drag-and-drop-files-list-item-error___yR0DY",
|
|
25
25
|
"drag-and-drop-files-list-item-icon-error": "DragAndDrop-module__drag-and-drop-files-list-item-icon-error___17EE-",
|
|
26
26
|
"drag-and-drop-files-list-item-icon-delete": "DragAndDrop-module__drag-and-drop-files-list-item-icon-delete___Z1l-B"
|
|
27
|
-
}, Br = (
|
|
27
|
+
}, Br = (u) => `File size is too large. Must be up to ${u}MB.`, Sr = (u) => `The file format is incorrect. Please make sure it is one of the extensions: ${u}.`;
|
|
28
28
|
function Rr({
|
|
29
|
-
label:
|
|
30
|
-
type:
|
|
29
|
+
label: u,
|
|
30
|
+
type: i = "single",
|
|
31
31
|
disabled: q,
|
|
32
32
|
required: rr,
|
|
33
33
|
fileExtensionsAllowed: c,
|
|
34
|
-
maxSize:
|
|
34
|
+
maxSize: p = Number.POSITIVE_INFINITY,
|
|
35
35
|
maxFiles: l = Number.POSITIVE_INFINITY,
|
|
36
|
-
value:
|
|
36
|
+
value: D,
|
|
37
37
|
onUpload: m,
|
|
38
|
-
onRemoveFile:
|
|
38
|
+
onRemoveFile: I,
|
|
39
39
|
queueFiles: P,
|
|
40
40
|
className: er,
|
|
41
|
-
maxSizeErrorMessage:
|
|
42
|
-
fileExtensionInvalidErrorMessage:
|
|
43
|
-
texts:
|
|
41
|
+
maxSizeErrorMessage: T,
|
|
42
|
+
fileExtensionInvalidErrorMessage: v,
|
|
43
|
+
texts: a,
|
|
44
44
|
fileIcon: ar = "ap-icon-document",
|
|
45
45
|
errorIcon: nr = "ap-icon-alert",
|
|
46
46
|
deleteIcon: dr = "ap-icon-delete",
|
|
@@ -49,27 +49,27 @@ function Rr({
|
|
|
49
49
|
fileSizeFormatter: O,
|
|
50
50
|
browseButtonProps: or,
|
|
51
51
|
validator: B,
|
|
52
|
-
errors:
|
|
52
|
+
errors: L,
|
|
53
53
|
...sr
|
|
54
54
|
}) {
|
|
55
|
-
const j = vr(), y = Lr(null), [
|
|
55
|
+
const j = vr(), y = Lr(null), [C, Y] = J([]), [G, S] = J(!1), h = D !== void 0, M = c.join(", "), X = p ? `up to ${p}MB` : "", tr = c.map((r) => `.${r.replace(/^\./, "")}`).join(","), Z = g((r, e) => {
|
|
56
56
|
if (!r) return r || "";
|
|
57
|
-
if (
|
|
58
|
-
if (
|
|
59
|
-
return typeof
|
|
60
|
-
if (
|
|
61
|
-
return typeof
|
|
57
|
+
if (a != null && a.errors && e) {
|
|
58
|
+
if (e === "SIZE_TOO_LARGE" && a.errors.sizeTooLarge)
|
|
59
|
+
return typeof a.errors.sizeTooLarge == "function" ? a.errors.sizeTooLarge(p) : a.errors.sizeTooLarge;
|
|
60
|
+
if (e === "INVALID_EXTENSION" && a.errors.invalidExtension)
|
|
61
|
+
return typeof a.errors.invalidExtension == "function" ? a.errors.invalidExtension(c) : a.errors.invalidExtension;
|
|
62
62
|
}
|
|
63
63
|
return r;
|
|
64
|
-
}, [
|
|
64
|
+
}, [a, p, c]), lr = g(() => a != null && a.browse ? typeof a.browse == "function" ? a.browse(i) : a.browse : i === "single" ? "Browse file" : "Browse files", [a, i]), cr = g(() => a != null && a.drag ? typeof a.drag == "function" ? a.drag(i) : a.drag : i === "single" ? "or drag your file" : "or drag multiple files", [a, i]), _r = g(() => a != null && a.constraints ? a.constraints({
|
|
65
65
|
extensions: c,
|
|
66
|
-
maxSize:
|
|
67
|
-
type:
|
|
68
|
-
}) : `${M} ${
|
|
66
|
+
maxSize: p,
|
|
67
|
+
type: i
|
|
68
|
+
}) : `${M} ${i === "single" ? "file" : "files"} ${X}`, [a, c, M, p, X, i]), gr = () => {
|
|
69
69
|
var r;
|
|
70
70
|
N || (r = y.current) == null || r.click();
|
|
71
|
-
},
|
|
72
|
-
const s =
|
|
71
|
+
}, $ = A(() => new Set(c.map((r) => r.toLowerCase().replace(/^\./, ""))), [c]), H = g((r, e) => {
|
|
72
|
+
const s = e.maxSize ? e.maxSize * 1024 * 1024 : Number.POSITIVE_INFINITY, o = e.fileExtensionsAllowed.join(", "), f = (T == null ? void 0 : T.replace(/\{maxSize\}/g, String(e.maxSize))) ?? Br(e.maxSize), Nr = (v == null ? void 0 : v.replace(/\{fileExtensionsAllowed\}/g, o)) ?? Sr(o), Ar = r.size <= s, Q = r.name.toLowerCase(), Ir = Q.includes(".") ? Q.split(".").pop() ?? "" : "", Tr = $.size === 0 || $.has(Ir);
|
|
73
73
|
return Ar ? Tr ? {
|
|
74
74
|
file: r
|
|
75
75
|
} : {
|
|
@@ -78,60 +78,58 @@ function Rr({
|
|
|
78
78
|
errorCode: "INVALID_EXTENSION"
|
|
79
79
|
} : {
|
|
80
80
|
file: r,
|
|
81
|
-
error:
|
|
81
|
+
error: f,
|
|
82
82
|
errorCode: "SIZE_TOO_LARGE"
|
|
83
83
|
};
|
|
84
|
-
}, [
|
|
85
|
-
maxSize:
|
|
84
|
+
}, [$, T, v]), k = A(() => ({
|
|
85
|
+
maxSize: p,
|
|
86
86
|
fileExtensionsAllowed: c,
|
|
87
|
-
type:
|
|
87
|
+
type: i,
|
|
88
88
|
maxFiles: l
|
|
89
|
-
}), [
|
|
90
|
-
let
|
|
91
|
-
B ?
|
|
92
|
-
let s =
|
|
93
|
-
const
|
|
89
|
+
}), [p, c, i, l]), b = g((r) => {
|
|
90
|
+
let e;
|
|
91
|
+
B ? e = r.map((o) => B(o, k)) : e = r.map((o) => H(o, k));
|
|
92
|
+
let s = e.map((o) => {
|
|
93
|
+
const f = o.error ? Z(o.error, o.errorCode) : void 0;
|
|
94
94
|
return {
|
|
95
95
|
file: o.file,
|
|
96
96
|
// Don't merge external errors here - that happens in files useMemo
|
|
97
|
-
error:
|
|
97
|
+
error: f
|
|
98
98
|
};
|
|
99
99
|
});
|
|
100
|
-
return
|
|
100
|
+
return i === "single" && s.length > 1 ? s.slice(0, 1) : (l && l > 0 && s.length > l && (s = s.map((o, f) => f < l ? o : {
|
|
101
101
|
...o,
|
|
102
102
|
error: o.error ?? `Maximum ${l} file${l === 1 ? "" : "s"} allowed.`
|
|
103
103
|
})), s);
|
|
104
|
-
}, [
|
|
104
|
+
}, [i, l, B, k, Z, H]), n = A(() => {
|
|
105
105
|
let r;
|
|
106
106
|
if (h) {
|
|
107
|
-
const
|
|
108
|
-
r = b(
|
|
107
|
+
const e = Array.isArray(D) ? D : D ? [D] : [];
|
|
108
|
+
r = b(e);
|
|
109
109
|
} else
|
|
110
|
-
r =
|
|
111
|
-
return r.map((
|
|
112
|
-
...
|
|
110
|
+
r = C;
|
|
111
|
+
return r.map((e) => ({
|
|
112
|
+
...e,
|
|
113
113
|
// Validator errors take precedence over external errors
|
|
114
|
-
error:
|
|
114
|
+
error: e.error ?? (L == null ? void 0 : L[e.file.name])
|
|
115
115
|
}));
|
|
116
|
-
}, [h,
|
|
117
|
-
const
|
|
116
|
+
}, [h, D, b, C, L]), pr = g((r) => O ? O(r) : (r / 1024).toFixed(2) + " KB", [O]), N = A(() => q || (n == null ? void 0 : n.length) >= l || i === "single" && (n == null ? void 0 : n.length) > 0, [q, n, l, i]), W = g((r) => {
|
|
117
|
+
const e = b(r);
|
|
118
118
|
if (h)
|
|
119
|
-
m == null || m(
|
|
119
|
+
m == null || m(e);
|
|
120
120
|
else {
|
|
121
|
-
const s = P ? [...
|
|
121
|
+
const s = P ? [...C, ...e] : e;
|
|
122
122
|
Y(s), m == null || m(s);
|
|
123
123
|
}
|
|
124
|
-
}, [b, h, P,
|
|
124
|
+
}, [b, h, P, C, m]), mr = (r) => {
|
|
125
125
|
if (!r.target.files) return;
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
},
|
|
129
|
-
if (!
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
T == null || T(r);
|
|
134
|
-
}, [h, D, T]), W = I(() => new Map(i.map((r) => [r.file.name, () => k(r.file.name)])), [i, k]), {
|
|
126
|
+
const e = Array.from(r.target.files);
|
|
127
|
+
W(e), r.target.value = "";
|
|
128
|
+
}, w = g((r) => {
|
|
129
|
+
if (!(n != null && n.length) || r < 0 || r >= n.length) return;
|
|
130
|
+
const e = n[r], s = n.filter((o, f) => f !== r);
|
|
131
|
+
h || Y(s), I == null || I(e.file, s);
|
|
132
|
+
}, [h, n, I]), F = A(() => new Map(n.map((r, e) => [e, () => w(e)])), [n, w]), {
|
|
135
133
|
onDragOver: E,
|
|
136
134
|
onDragLeave: z,
|
|
137
135
|
onDrop: R,
|
|
@@ -143,41 +141,41 @@ function Rr({
|
|
|
143
141
|
}, hr = (r) => {
|
|
144
142
|
if (N) return;
|
|
145
143
|
r.preventDefault();
|
|
146
|
-
const
|
|
147
|
-
|
|
144
|
+
const e = Array.from(r.dataTransfer.files);
|
|
145
|
+
W(e), r.dataTransfer.clearData(), S(!1), R == null || R(r);
|
|
148
146
|
};
|
|
149
|
-
return /* @__PURE__ */ _("div", { className: U(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
rr && /* @__PURE__ */ t("span", { "aria-hidden": "true", className:
|
|
147
|
+
return /* @__PURE__ */ _("div", { className: U(d["drag-and-drop-container"], N && d.disabled, er), ...fr, children: [
|
|
148
|
+
u && /* @__PURE__ */ _("label", { htmlFor: j, children: [
|
|
149
|
+
u,
|
|
150
|
+
rr && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: d.required, children: "*" })
|
|
153
151
|
] }),
|
|
154
|
-
/* @__PURE__ */ _("div", { className: U(
|
|
155
|
-
/* @__PURE__ */ t(K, { type: "secondary", variant: "default", size: "sm", ...or, disabled: N, onClick:
|
|
152
|
+
/* @__PURE__ */ _("div", { className: U(d["drag-and-drop-space"], G && d.active), onDragOver: ur, onDragLeave: Dr, onDrop: hr, children: [
|
|
153
|
+
/* @__PURE__ */ t(K, { type: "secondary", variant: "default", size: "sm", ...or, disabled: N, onClick: gr, icon: ir, children: lr() }),
|
|
156
154
|
/* @__PURE__ */ t("input", { id: j, ref: y, type: "file", style: {
|
|
157
155
|
display: "none"
|
|
158
|
-
}, multiple:
|
|
159
|
-
/* @__PURE__ */ _("div", { className:
|
|
160
|
-
/* @__PURE__ */ t("span", { className:
|
|
161
|
-
/* @__PURE__ */ _("span", { className:
|
|
156
|
+
}, multiple: i === "multiple", accept: tr, onChange: mr }),
|
|
157
|
+
/* @__PURE__ */ _("div", { className: d["drag-and-drop-space-text"], children: [
|
|
158
|
+
/* @__PURE__ */ t("span", { className: d["drag-and-drop-space-text-message"], children: cr() }),
|
|
159
|
+
/* @__PURE__ */ _("span", { className: d["drag-and-drop-space-text-constraints"], children: [
|
|
162
160
|
" ",
|
|
163
161
|
_r()
|
|
164
162
|
] })
|
|
165
163
|
] })
|
|
166
164
|
] }),
|
|
167
|
-
(
|
|
168
|
-
/* @__PURE__ */ t("span", { className:
|
|
169
|
-
/* @__PURE__ */ _("div", { className:
|
|
170
|
-
/* @__PURE__ */ _("div", { className:
|
|
171
|
-
/* @__PURE__ */ t("span", { className:
|
|
172
|
-
/* @__PURE__ */ t("span", { className:
|
|
173
|
-
r.error && /* @__PURE__ */ _("span", { className:
|
|
174
|
-
/* @__PURE__ */ t(x, { icon: nr, className:
|
|
165
|
+
(n == null ? void 0 : n.length) > 0 && /* @__PURE__ */ t("ul", { className: d["drag-and-drop-files-list"], children: n == null ? void 0 : n.map((r, e) => V ? /* @__PURE__ */ t("li", { children: V(r, e, F.get(e) ?? (() => w(e))) }, e) : /* @__PURE__ */ t("li", { className: d["drag-and-drop-files-list-item"], children: /* @__PURE__ */ _("div", { className: d["drag-and-drop-files-list-item-content"], children: [
|
|
166
|
+
/* @__PURE__ */ t("span", { className: d["drag-and-drop-files-list-item-icon-container"], children: /* @__PURE__ */ t(x, { icon: ar, className: d["drag-and-drop-files-list-item-icon"] }) }),
|
|
167
|
+
/* @__PURE__ */ _("div", { className: d["drag-and-drop-files-list-item-content-data"], children: [
|
|
168
|
+
/* @__PURE__ */ _("div", { className: d["drag-and-drop-files-list-item-text"], children: [
|
|
169
|
+
/* @__PURE__ */ t("span", { className: d["drag-and-drop-files-list-item-name"], children: r.file.name }),
|
|
170
|
+
/* @__PURE__ */ t("span", { className: d["drag-and-drop-files-list-item-size"], children: pr(r.file.size) }),
|
|
171
|
+
r.error && /* @__PURE__ */ _("span", { className: d["drag-and-drop-files-list-item-error"], children: [
|
|
172
|
+
/* @__PURE__ */ t(x, { icon: nr, className: d["drag-and-drop-files-list-item-icon-error"] }),
|
|
175
173
|
r.error
|
|
176
174
|
] })
|
|
177
175
|
] }),
|
|
178
|
-
/* @__PURE__ */ t(K, { type: "tertiary", variant: "default", size: "sm", onClick:
|
|
176
|
+
/* @__PURE__ */ t(K, { type: "tertiary", variant: "default", size: "sm", onClick: F.get(e), icon: dr, iconClassName: d["drag-and-drop-files-list-item-icon-delete"], "aria-label": `Remove ${r.file.name}` })
|
|
179
177
|
] })
|
|
180
|
-
] }) },
|
|
178
|
+
] }) }, e)) })
|
|
181
179
|
] });
|
|
182
180
|
}
|
|
183
181
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as v, jsx as i } from "react/jsx-runtime";
|
|
2
2
|
import { d as y, i as l, r as p, g as e, s as o, v as c, w as f, f as B } from "../../vi.bdSIJ99Y-017e_Pkz.js";
|
|
3
3
|
import d from "./DragAndDrop.js";
|
|
4
|
-
import { c as
|
|
4
|
+
import { c as T, d as I } from "../../DragAndDrop.utils-D3xTV9EK.js";
|
|
5
5
|
import { u as w } from "../../index-DkTDHhag.js";
|
|
6
6
|
y("DragAndDrop", () => {
|
|
7
7
|
y("Rendering", () => {
|
|
@@ -223,7 +223,9 @@ y("DragAndDrop", () => {
|
|
|
223
223
|
e(o.getByTestId("drag-and-drop-files-list")).toBeInTheDocument();
|
|
224
224
|
});
|
|
225
225
|
const r = o.getByTestId("drag-and-drop-remove-0");
|
|
226
|
-
B.click(r), e(n).toHaveBeenCalledTimes(1)
|
|
226
|
+
B.click(r), e(n).toHaveBeenCalledTimes(1);
|
|
227
|
+
const [u, g] = n.mock.calls[0];
|
|
228
|
+
e(u).toBe(t), e(g).toHaveLength(0), await f(() => {
|
|
227
229
|
e(o.queryByTestId("drag-and-drop-files-list")).not.toBeInTheDocument();
|
|
228
230
|
});
|
|
229
231
|
}), l("should queue files when queueFiles is true", async () => {
|
|
@@ -389,8 +391,8 @@ y("DragAndDrop", () => {
|
|
|
389
391
|
let n = [];
|
|
390
392
|
const s = c.fn((m) => {
|
|
391
393
|
n = m;
|
|
392
|
-
}), r = c.fn((m) => {
|
|
393
|
-
n =
|
|
394
|
+
}), r = c.fn((m, h) => {
|
|
395
|
+
n = h;
|
|
394
396
|
}), {
|
|
395
397
|
rerender: u
|
|
396
398
|
} = p(/* @__PURE__ */ i(d, { type: "multiple", fileExtensionsAllowed: ["pdf"], maxSize: 5, value: n.map((m) => m.file), onUpload: s, onRemoveFile: r })), g = o.getByTestId("drag-and-drop-input");
|
|
@@ -401,7 +403,9 @@ y("DragAndDrop", () => {
|
|
|
401
403
|
});
|
|
402
404
|
const x = o.getByTestId("drag-and-drop-remove-0");
|
|
403
405
|
B.click(x), await f(() => {
|
|
404
|
-
e(r).toHaveBeenCalledTimes(1)
|
|
406
|
+
e(r).toHaveBeenCalledTimes(1);
|
|
407
|
+
const [m, h] = r.mock.calls[0];
|
|
408
|
+
e(m).toBe(t), e(h).toHaveLength(1), e(h[0].file).toBe(a);
|
|
405
409
|
}), e(n.length).toBe(1), e(n.find((m) => m.file.name === "test1.pdf")).toBeUndefined(), u(/* @__PURE__ */ i(d, { type: "multiple", fileExtensionsAllowed: ["pdf"], maxSize: 5, value: n.map((m) => m.file), onUpload: s, onRemoveFile: r })), await f(() => {
|
|
406
410
|
e(o.getByTestId("drag-and-drop-files-list")).toBeInTheDocument();
|
|
407
411
|
const m = n[0];
|
|
@@ -519,7 +523,7 @@ y("DragAndDrop", () => {
|
|
|
519
523
|
error: "Validator 2 error"
|
|
520
524
|
} : {
|
|
521
525
|
file: m
|
|
522
|
-
}), n =
|
|
526
|
+
}), n = T(t, a), s = {
|
|
523
527
|
maxSize: 5,
|
|
524
528
|
fileExtensionsAllowed: ["pdf"],
|
|
525
529
|
type: "single",
|
|
@@ -539,7 +543,7 @@ y("DragAndDrop", () => {
|
|
|
539
543
|
})), a = c.fn((g) => ({
|
|
540
544
|
file: g,
|
|
541
545
|
error: "Second error"
|
|
542
|
-
})), n =
|
|
546
|
+
})), n = T(t, a), s = {
|
|
543
547
|
maxSize: 5,
|
|
544
548
|
fileExtensionsAllowed: ["pdf"],
|
|
545
549
|
type: "single",
|
|
@@ -553,7 +557,7 @@ y("DragAndDrop", () => {
|
|
|
553
557
|
file: g
|
|
554
558
|
})), a = c.fn((g) => ({
|
|
555
559
|
file: g
|
|
556
|
-
})), n =
|
|
560
|
+
})), n = T(t, a), s = {
|
|
557
561
|
maxSize: 5,
|
|
558
562
|
fileExtensionsAllowed: ["pdf"],
|
|
559
563
|
type: "single",
|
|
@@ -564,14 +568,14 @@ y("DragAndDrop", () => {
|
|
|
564
568
|
e(u.error).toBeUndefined(), e(t).toHaveBeenCalledTimes(1), e(a).toHaveBeenCalledTimes(1);
|
|
565
569
|
}), l("should work with defaultValidator in composition", () => {
|
|
566
570
|
const t = c.fn((x, m) => {
|
|
567
|
-
const
|
|
568
|
-
return
|
|
571
|
+
const h = I(x, m);
|
|
572
|
+
return h.error ? h : x.name.startsWith("reject") ? {
|
|
569
573
|
file: x,
|
|
570
574
|
error: "Custom rejection error"
|
|
571
575
|
} : {
|
|
572
576
|
file: x
|
|
573
577
|
};
|
|
574
|
-
}), a =
|
|
578
|
+
}), a = T(I, t), n = {
|
|
575
579
|
maxSize: 1,
|
|
576
580
|
fileExtensionsAllowed: ["pdf"],
|
|
577
581
|
type: "single",
|
|
@@ -593,7 +597,7 @@ y("DragAndDrop", () => {
|
|
|
593
597
|
} : {
|
|
594
598
|
file: u
|
|
595
599
|
};
|
|
596
|
-
}), a =
|
|
600
|
+
}), a = T(I, t), n = new File(["test"], "blocked.pdf", {
|
|
597
601
|
type: "application/pdf"
|
|
598
602
|
}), s = c.fn();
|
|
599
603
|
p(/* @__PURE__ */ i(d, { fileExtensionsAllowed: ["pdf"], maxSize: 5, onUpload: s, validator: a }));
|
|
@@ -31,7 +31,7 @@ export type FilePickerContextValue = {
|
|
|
31
31
|
inputRef: React.RefObject<HTMLInputElement | null>;
|
|
32
32
|
triggerInput: () => void;
|
|
33
33
|
handleKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void;
|
|
34
|
-
handleRemoveFile: (
|
|
34
|
+
handleRemoveFile: (index: number) => void;
|
|
35
35
|
displayFileSize: (size: number) => string;
|
|
36
36
|
uploadedFileAppendedRow?: (item: UploadFile, index: number) => ReactNode;
|
|
37
37
|
};
|
|
@@ -59,7 +59,7 @@ type FilePickerProps = {
|
|
|
59
59
|
labelTooltip?: InputLabelTooltipProps;
|
|
60
60
|
uploadedFileAppendedRow?: (item: UploadFile, index: number) => ReactNode;
|
|
61
61
|
onUpload?: (files: UploadFile[]) => void;
|
|
62
|
-
onRemoveFile?: (
|
|
62
|
+
onRemoveFile?: (removedFile: File, remaining: UploadFile[]) => void;
|
|
63
63
|
children?: ReactNode;
|
|
64
64
|
} & InteractiveEventHandlers;
|
|
65
65
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { createContext as ae, useId as pe, useRef as ue, useState as
|
|
1
|
+
import { jsxs as r, jsx as t, Fragment as ce } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as ae, useId as pe, useRef as ue, useState as A, useCallback as _, useEffect as me, useContext as de } from "react";
|
|
3
3
|
import _e from "../Tooltip/Tooltip.js";
|
|
4
|
-
import
|
|
4
|
+
import R from "../Icon/Icon.js";
|
|
5
5
|
import y from "../Button/Button.js";
|
|
6
6
|
import { c as D } from "../../clsx-OuTLNxxd.js";
|
|
7
7
|
import '../../assets/FilePicker.css';const Fe = "FilePicker-module__container___knCCi", Ie = "FilePicker-module__containerMultiple___Psi5u", Le = "FilePicker-module__label___al7Xe", he = "FilePicker-module__required___41Vjd", ke = "FilePicker-module__labelTooltipIcon___Cc1QF", ge = "FilePicker-module__helpers___79-g5", fe = "FilePicker-module__helperText___ja9Rr", Ne = "FilePicker-module__errorMessage___TvHrL", Pe = "FilePicker-module__singleFileHelpLinkContainer___mpjUf", Ce = "FilePicker-module__singleFileHelpLinkReservedSpace___r8j2b", Te = "FilePicker-module__helpLink___uu45D", be = "FilePicker-module__input___cL1Hs", xe = "FilePicker-module__singleFileContainer___OFSDt", ye = "FilePicker-module__singleFileInputContainer___MOkES", De = "FilePicker-module__inputFileName___sMs7R", Se = "FilePicker-module__inputFileNamePlaceholder___-mkDD", we = "FilePicker-module__inputButton___ghLlD", Be = "FilePicker-module__multipleHelpText___5tnnn", Re = "FilePicker-module__multipleInputButton___WCJp9", He = "FilePicker-module__multipleFilesList___Kim0I", ve = "FilePicker-module__multipleFilesListItem___01PDS", Me = "FilePicker-module__multipleFilesListItemContent___pKbho", Ae = "FilePicker-module__multipleFilesListItemContentData___5GC-C", Ee = "FilePicker-module__multipleFilesListItemIconContainer___7sUL5", ze = "FilePicker-module__multipleFilesListItemIcon___nfMX9", je = "FilePicker-module__multipleFilesListItemText___nPqrL", Oe = "FilePicker-module__multipleFilesListItemName___NjHhX", Ve = "FilePicker-module__multipleFilesListItemSize___wc8LJ", Ke = "FilePicker-module__multipleFilesListItemError___x9qkT", qe = "FilePicker-module__multipleFilesListItemIconError___0RO46", Xe = "FilePicker-module__multipleFilesListItemAppendedRow___nzls7", $e = "FilePicker-module__multipleFilesListItemIconDelete___9Z9Dl", Ye = "FilePicker-module__disabled___szMiq", i = {
|
|
@@ -38,9 +38,9 @@ import '../../assets/FilePicker.css';const Fe = "FilePicker-module__container___
|
|
|
38
38
|
multipleFilesListItemAppendedRow: Xe,
|
|
39
39
|
multipleFilesListItemIconDelete: $e,
|
|
40
40
|
disabled: Ye
|
|
41
|
-
},
|
|
42
|
-
function
|
|
43
|
-
const e = de(
|
|
41
|
+
}, E = ae(null);
|
|
42
|
+
function m() {
|
|
43
|
+
const e = de(E);
|
|
44
44
|
if (!e)
|
|
45
45
|
throw new Error("FilePicker compound components must be used within a FilePicker.");
|
|
46
46
|
return e;
|
|
@@ -56,103 +56,103 @@ function Qe({
|
|
|
56
56
|
fileExtensionsAllowed: s,
|
|
57
57
|
maxSize: o = Number.POSITIVE_INFINITY,
|
|
58
58
|
queueFiles: I = !1,
|
|
59
|
-
disabled:
|
|
60
|
-
isUploadDisabled:
|
|
61
|
-
value:
|
|
62
|
-
label:
|
|
63
|
-
required:
|
|
64
|
-
placeholder:
|
|
65
|
-
errorMessage:
|
|
66
|
-
maxSizeErrorMessage:
|
|
67
|
-
fileExtensionInvalidErrorMessage:
|
|
68
|
-
helpText:
|
|
69
|
-
helpLink:
|
|
70
|
-
helpLinkText:
|
|
71
|
-
multipleHelpText:
|
|
72
|
-
multipleButtonHelpText:
|
|
73
|
-
labelTooltip:
|
|
74
|
-
uploadedFileAppendedRow:
|
|
59
|
+
disabled: c = !1,
|
|
60
|
+
isUploadDisabled: j = !1,
|
|
61
|
+
value: k,
|
|
62
|
+
label: O,
|
|
63
|
+
required: V = !1,
|
|
64
|
+
placeholder: K,
|
|
65
|
+
errorMessage: q,
|
|
66
|
+
maxSizeErrorMessage: g,
|
|
67
|
+
fileExtensionInvalidErrorMessage: f,
|
|
68
|
+
helpText: X,
|
|
69
|
+
helpLink: $,
|
|
70
|
+
helpLinkText: Y,
|
|
71
|
+
multipleHelpText: G,
|
|
72
|
+
multipleButtonHelpText: J,
|
|
73
|
+
labelTooltip: Z,
|
|
74
|
+
uploadedFileAppendedRow: Q,
|
|
75
75
|
onUpload: d,
|
|
76
|
-
onRemoveFile:
|
|
77
|
-
children:
|
|
76
|
+
onRemoveFile: N,
|
|
77
|
+
children: P
|
|
78
78
|
}) {
|
|
79
|
-
const
|
|
79
|
+
const H = pe(), C = ue(null), [a, T] = A(k ? k.map((n) => ({
|
|
80
80
|
file: n
|
|
81
|
-
})) : []), [
|
|
82
|
-
const
|
|
83
|
-
return n.map((
|
|
84
|
-
const oe =
|
|
85
|
-
let
|
|
86
|
-
return oe || (
|
|
87
|
-
file:
|
|
88
|
-
error:
|
|
81
|
+
})) : []), [U, S] = A(!1), b = s.join(", "), v = s.map((n) => `.${n.replace(/^\./, "")}`).join(","), x = _((n) => {
|
|
82
|
+
const p = o ? o * 1024 * 1024 : Number.POSITIVE_INFINITY, u = new Set(s.map((h) => h.toLowerCase().replace(/^\./, ""))), L = (g == null ? void 0 : g.replace(/\{maxSize\}/g, String(o))) ?? Ge(o), w = (f == null ? void 0 : f.replace(/\{fileExtensionsAllowed\}/g, b)) ?? Je(b);
|
|
83
|
+
return n.map((h) => {
|
|
84
|
+
const oe = h.size <= p, re = u.size === 0 || u.has(Ze(h));
|
|
85
|
+
let B;
|
|
86
|
+
return oe || (B = L), re || (B = w), {
|
|
87
|
+
file: h,
|
|
88
|
+
error: B
|
|
89
89
|
};
|
|
90
90
|
});
|
|
91
|
-
}, [s,
|
|
92
|
-
const
|
|
93
|
-
return S(
|
|
94
|
-
}, [l,
|
|
91
|
+
}, [s, b, o, g, f]), M = _((n) => {
|
|
92
|
+
const p = a.length;
|
|
93
|
+
return S(p + n.length > l), x(n);
|
|
94
|
+
}, [l, a.length, x]);
|
|
95
95
|
me(() => {
|
|
96
|
-
const n =
|
|
97
|
-
|
|
98
|
-
}, [
|
|
99
|
-
const
|
|
96
|
+
const n = x(k ?? []);
|
|
97
|
+
T(n), S(n.length > l);
|
|
98
|
+
}, [k, l, x]);
|
|
99
|
+
const W = _((n) => (n / 1024).toFixed(2) + " KB", []), ee = _(() => {
|
|
100
100
|
var n;
|
|
101
|
-
|
|
102
|
-
}, [
|
|
103
|
-
var
|
|
104
|
-
|
|
105
|
-
}, [
|
|
106
|
-
if (
|
|
107
|
-
const
|
|
101
|
+
c || (n = C.current) == null || n.click();
|
|
102
|
+
}, [c]), le = _((n) => {
|
|
103
|
+
var p;
|
|
104
|
+
c || n.key === "Enter" && ((p = C.current) == null || p.click());
|
|
105
|
+
}, [c]), ie = _((n) => {
|
|
106
|
+
if (c) return;
|
|
107
|
+
const p = n.target.files, u = M(Array.from(p ?? []));
|
|
108
108
|
if (e === "multiple" && I) {
|
|
109
|
-
const
|
|
110
|
-
|
|
109
|
+
const L = [...a, ...u];
|
|
110
|
+
T(L), d == null || d(L);
|
|
111
111
|
} else
|
|
112
|
-
|
|
112
|
+
T(u), d == null || d(u);
|
|
113
113
|
n.target.value = "";
|
|
114
|
-
}, [
|
|
115
|
-
if (a ||
|
|
116
|
-
const
|
|
117
|
-
S(
|
|
118
|
-
}, [
|
|
119
|
-
id:
|
|
114
|
+
}, [c, e, I, a, M, d]), te = _((n) => {
|
|
115
|
+
if (c || !a || n < 0 || n >= a.length) return;
|
|
116
|
+
const p = a[n], u = a.filter((L, w) => w !== n);
|
|
117
|
+
S(u.length > l), T(u), N == null || N(p.file, u);
|
|
118
|
+
}, [c, a, l, N]), ne = {
|
|
119
|
+
id: H,
|
|
120
120
|
type: e,
|
|
121
121
|
maxFiles: l,
|
|
122
122
|
fileExtensionsAllowed: s,
|
|
123
|
-
fileExtensionsAllowedText:
|
|
123
|
+
fileExtensionsAllowedText: b,
|
|
124
124
|
maxSize: o,
|
|
125
125
|
queueFiles: I,
|
|
126
|
-
disabled:
|
|
127
|
-
isUploadDisabled:
|
|
128
|
-
uploadedFiles:
|
|
129
|
-
isMaxFilesExceeded:
|
|
130
|
-
label:
|
|
131
|
-
required:
|
|
132
|
-
placeholder:
|
|
133
|
-
errorMessage:
|
|
134
|
-
helpText:
|
|
135
|
-
helpLink:
|
|
136
|
-
helpLinkText:
|
|
137
|
-
multipleHelpText:
|
|
138
|
-
multipleButtonHelpText:
|
|
139
|
-
labelTooltip:
|
|
140
|
-
accept:
|
|
141
|
-
inputRef:
|
|
142
|
-
triggerInput:
|
|
143
|
-
handleKeyDown:
|
|
144
|
-
handleRemoveFile:
|
|
145
|
-
displayFileSize:
|
|
146
|
-
uploadedFileAppendedRow:
|
|
147
|
-
},
|
|
148
|
-
return /* @__PURE__ */
|
|
149
|
-
/* @__PURE__ */ t("input", { accept:
|
|
150
|
-
/* @__PURE__ */ t("div", { className: D(i.container, e === "multiple" && i.containerMultiple,
|
|
126
|
+
disabled: c,
|
|
127
|
+
isUploadDisabled: j,
|
|
128
|
+
uploadedFiles: a,
|
|
129
|
+
isMaxFilesExceeded: U,
|
|
130
|
+
label: O,
|
|
131
|
+
required: V,
|
|
132
|
+
placeholder: K,
|
|
133
|
+
errorMessage: q,
|
|
134
|
+
helpText: X,
|
|
135
|
+
helpLink: $,
|
|
136
|
+
helpLinkText: Y,
|
|
137
|
+
multipleHelpText: G,
|
|
138
|
+
multipleButtonHelpText: J,
|
|
139
|
+
labelTooltip: Z,
|
|
140
|
+
accept: v,
|
|
141
|
+
inputRef: C,
|
|
142
|
+
triggerInput: ee,
|
|
143
|
+
handleKeyDown: le,
|
|
144
|
+
handleRemoveFile: te,
|
|
145
|
+
displayFileSize: W,
|
|
146
|
+
uploadedFileAppendedRow: Q
|
|
147
|
+
}, se = P != null && (Array.isArray(P) ? P.length > 0 : !0);
|
|
148
|
+
return /* @__PURE__ */ r(E.Provider, { value: ne, children: [
|
|
149
|
+
/* @__PURE__ */ t("input", { accept: v, multiple: e === "multiple", ref: C, type: "file", id: H, className: i.input, onChange: ie }),
|
|
150
|
+
/* @__PURE__ */ t("div", { className: D(i.container, e === "multiple" && i.containerMultiple, c && i.disabled), children: se ? P : /* @__PURE__ */ t(Ue, {}) })
|
|
151
151
|
] });
|
|
152
152
|
}
|
|
153
153
|
function Ue() {
|
|
154
|
-
const e =
|
|
155
|
-
return /* @__PURE__ */
|
|
154
|
+
const e = m();
|
|
155
|
+
return /* @__PURE__ */ r(ce, { children: [
|
|
156
156
|
/* @__PURE__ */ t(F.Label, {}),
|
|
157
157
|
e.type === "single" && /* @__PURE__ */ t(F.SingleFileRow, { children: /* @__PURE__ */ t(F.BrowseButton, {}) }),
|
|
158
158
|
e.type === "single" && e.uploadedFiles.length > 0 && /* @__PURE__ */ t("span", { className: i.singleFileHelpLinkReservedSpace, children: /* @__PURE__ */ t(F.SingleFileDeleteButton, {}) }),
|
|
@@ -164,11 +164,11 @@ function Ue() {
|
|
|
164
164
|
function We({
|
|
165
165
|
children: e
|
|
166
166
|
}) {
|
|
167
|
-
const l =
|
|
168
|
-
return /* @__PURE__ */
|
|
167
|
+
const l = m(), s = e ?? l.label;
|
|
168
|
+
return /* @__PURE__ */ r("label", { htmlFor: l.id, onClick: (o) => o.preventDefault(), className: D(i.label, l.type === "multiple" && i.labelMultiple), children: [
|
|
169
169
|
/* @__PURE__ */ t("span", { title: l.label, className: i.labelText, children: s }),
|
|
170
170
|
l.required && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: i.required, children: "*" }),
|
|
171
|
-
l.labelTooltip && /* @__PURE__ */ t(_e, { content: l.labelTooltip.content, size: l.labelTooltip.size, theme: l.labelTooltip.theme, tipSide: l.labelTooltip.tipSide, tipAlignment: l.labelTooltip.tipAlignment, startVisible: l.labelTooltip.startVisible, children: /* @__PURE__ */ t(
|
|
171
|
+
l.labelTooltip && /* @__PURE__ */ t(_e, { content: l.labelTooltip.content, size: l.labelTooltip.size, theme: l.labelTooltip.theme, tipSide: l.labelTooltip.tipSide, tipAlignment: l.labelTooltip.tipAlignment, startVisible: l.labelTooltip.startVisible, children: /* @__PURE__ */ t(R, { icon: "ap-icon-info", className: i.labelTooltipIcon }) }),
|
|
172
172
|
l.type === "multiple" && l.multipleHelpText && /* @__PURE__ */ t("span", { className: i.multipleHelpText, children: l.multipleHelpText })
|
|
173
173
|
] });
|
|
174
174
|
}
|
|
@@ -176,7 +176,7 @@ function el({
|
|
|
176
176
|
children: e,
|
|
177
177
|
className: l
|
|
178
178
|
}) {
|
|
179
|
-
const s =
|
|
179
|
+
const s = m();
|
|
180
180
|
return s.type === "multiple" ? /* @__PURE__ */ t(y, { type: "secondary", variant: "default", size: "md", icon: "ap-icon-upload", className: D(i.multipleInputButton, l), onClick: s.triggerInput, onKeyDown: s.handleKeyDown, disabled: s.disabled || s.isUploadDisabled, children: /* @__PURE__ */ t("span", { children: e ?? `Browse files ${s.multipleButtonHelpText ?? ""}` }) }) : /* @__PURE__ */ t(y, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-upload", className: D(i.inputButton, l), tabIndex: -1, disabled: s.disabled || s.isUploadDisabled, onClick: (o) => {
|
|
181
181
|
o.preventDefault(), o.stopPropagation(), s.triggerInput();
|
|
182
182
|
}, children: /* @__PURE__ */ t("span", { children: e ?? "Browse file" }) });
|
|
@@ -184,52 +184,50 @@ function el({
|
|
|
184
184
|
function ll({
|
|
185
185
|
children: e
|
|
186
186
|
}) {
|
|
187
|
-
return
|
|
187
|
+
return m().type !== "single" ? null : /* @__PURE__ */ t("div", { className: i.singleFileContainer, children: e });
|
|
188
188
|
}
|
|
189
189
|
function il({
|
|
190
190
|
children: e
|
|
191
191
|
}) {
|
|
192
|
-
const l =
|
|
193
|
-
return l.type !== "single" ? null : /* @__PURE__ */
|
|
192
|
+
const l = m();
|
|
193
|
+
return l.type !== "single" ? null : /* @__PURE__ */ r("div", { tabIndex: l.disabled ? -1 : 0, onClick: l.triggerInput, onKeyDown: l.handleKeyDown, className: i.singleFileInputContainer, children: [
|
|
194
194
|
/* @__PURE__ */ t("span", { className: i.inputFileName, children: l.uploadedFiles.length > 0 ? /* @__PURE__ */ t("span", { className: i.inputFileNameText, children: l.uploadedFiles[0].file.name }) : /* @__PURE__ */ t("span", { className: i.inputFileNamePlaceholder, children: l.placeholder }) }),
|
|
195
195
|
e
|
|
196
196
|
] });
|
|
197
197
|
}
|
|
198
198
|
function tl() {
|
|
199
|
-
return
|
|
199
|
+
return m().type !== "single" ? null : /* @__PURE__ */ t("span", { className: i.singleFileHelpLinkReservedSpace, children: /* @__PURE__ */ t(z, {}) });
|
|
200
200
|
}
|
|
201
|
-
function
|
|
202
|
-
const e =
|
|
203
|
-
|
|
204
|
-
const l = e.uploadedFiles[0].file.name;
|
|
205
|
-
return /* @__PURE__ */ t(y, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-delete", className: i.singleFileDeleteButton, onClick: () => e.handleRemoveFile(l), disabled: e.disabled });
|
|
201
|
+
function z() {
|
|
202
|
+
const e = m();
|
|
203
|
+
return e.type !== "single" || e.uploadedFiles.length === 0 ? null : /* @__PURE__ */ t(y, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-delete", className: i.singleFileDeleteButton, onClick: () => e.handleRemoveFile(0), disabled: e.disabled });
|
|
206
204
|
}
|
|
207
205
|
function nl() {
|
|
208
206
|
var o, I;
|
|
209
|
-
const e =
|
|
210
|
-
return e.type === "multiple" && !s ? null : /* @__PURE__ */
|
|
207
|
+
const e = m(), l = e.errorMessage || e.isMaxFilesExceeded || e.type === "single" && ((o = e.uploadedFiles[0]) == null ? void 0 : o.error), s = e.type === "single" ? e.errorMessage || ((I = e.uploadedFiles[0]) == null ? void 0 : I.error) : e.errorMessage || (e.isMaxFilesExceeded ? `You can only upload up to ${e.maxFiles} files.` : "");
|
|
208
|
+
return e.type === "multiple" && !s ? null : /* @__PURE__ */ r("div", { className: i.helpers, children: [
|
|
211
209
|
l ? /* @__PURE__ */ t("span", { title: e.errorMessage, className: i.errorMessage, children: s }) : e.helpText && e.type === "single" && /* @__PURE__ */ t("span", { title: e.helpText, className: i.helperText, children: e.helpText }),
|
|
212
|
-
e.type === "single" && e.helpLink && e.helpLinkText && /* @__PURE__ */
|
|
210
|
+
e.type === "single" && e.helpLink && e.helpLinkText && /* @__PURE__ */ r("span", { className: i.singleFileHelpLinkContainer, children: [
|
|
213
211
|
/* @__PURE__ */ t("a", { href: e.helpLink, className: i.helpLink, target: "_blank", rel: "noopener noreferrer", tabIndex: e.disabled ? -1 : 0, children: e.helpLinkText }),
|
|
214
212
|
/* @__PURE__ */ t("span", { className: i.singleFileHelpLinkReservedSpace })
|
|
215
213
|
] })
|
|
216
214
|
] });
|
|
217
215
|
}
|
|
218
216
|
function sl() {
|
|
219
|
-
const e =
|
|
220
|
-
return e.type !== "multiple" || !e.uploadedFiles.length ? null : /* @__PURE__ */ t("ul", { className: i.multipleFilesList, children: e.uploadedFiles.map((l, s) => /* @__PURE__ */
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
/* @__PURE__ */ t("span", { className: i.multipleFilesListItemIconContainer, children: /* @__PURE__ */ t(
|
|
223
|
-
/* @__PURE__ */
|
|
224
|
-
/* @__PURE__ */
|
|
217
|
+
const e = m();
|
|
218
|
+
return e.type !== "multiple" || !e.uploadedFiles.length ? null : /* @__PURE__ */ t("ul", { className: i.multipleFilesList, children: e.uploadedFiles.map((l, s) => /* @__PURE__ */ r("li", { className: i.multipleFilesListItem, children: [
|
|
219
|
+
/* @__PURE__ */ r("div", { className: i.multipleFilesListItemContent, children: [
|
|
220
|
+
/* @__PURE__ */ t("span", { className: i.multipleFilesListItemIconContainer, children: /* @__PURE__ */ t(R, { icon: "ap-icon-document", className: i.multipleFilesListItemIcon }) }),
|
|
221
|
+
/* @__PURE__ */ r("div", { className: i.multipleFilesListItemContentData, children: [
|
|
222
|
+
/* @__PURE__ */ r("div", { className: i.multipleFilesListItemText, children: [
|
|
225
223
|
/* @__PURE__ */ t("span", { className: i.multipleFilesListItemName, children: l.file.name }),
|
|
226
224
|
/* @__PURE__ */ t("span", { className: i.multipleFilesListItemSize, children: e.displayFileSize(l.file.size) }),
|
|
227
|
-
l.error && /* @__PURE__ */
|
|
228
|
-
/* @__PURE__ */ t(
|
|
225
|
+
l.error && /* @__PURE__ */ r("span", { className: i.multipleFilesListItemError, children: [
|
|
226
|
+
/* @__PURE__ */ t(R, { icon: "ap-icon-alert", className: i.multipleFilesListItemIconError }),
|
|
229
227
|
l.error
|
|
230
228
|
] })
|
|
231
229
|
] }),
|
|
232
|
-
/* @__PURE__ */ t(y, { type: "tertiary", variant: "default", size: "sm", onClick: () => e.handleRemoveFile(
|
|
230
|
+
/* @__PURE__ */ t(y, { type: "tertiary", variant: "default", size: "sm", onClick: () => e.handleRemoveFile(s), icon: "ap-icon-delete", iconClassName: i.multipleFilesListItemIconDelete, disabled: e.disabled })
|
|
233
231
|
] })
|
|
234
232
|
] }),
|
|
235
233
|
e.uploadedFileAppendedRow && /* @__PURE__ */ t("div", { className: i.multipleFilesListItemAppendedRow, children: e.uploadedFileAppendedRow(l, s) })
|
|
@@ -243,9 +241,9 @@ const F = Object.assign(Qe, {
|
|
|
243
241
|
SingleFileContainer: ll,
|
|
244
242
|
SingleFileRow: il,
|
|
245
243
|
SingleFileActions: tl,
|
|
246
|
-
SingleFileDeleteButton:
|
|
244
|
+
SingleFileDeleteButton: z
|
|
247
245
|
});
|
|
248
246
|
export {
|
|
249
247
|
F as default,
|
|
250
|
-
|
|
248
|
+
m as useFilePickerContext
|
|
251
249
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { d as
|
|
1
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
2
|
+
import { d as B, i as n, r as s, g as e, s as l, w as m, v as f, f as T } from "../../vi.bdSIJ99Y-017e_Pkz.js";
|
|
3
3
|
import { u as r } from "../../index-DkTDHhag.js";
|
|
4
|
-
import
|
|
5
|
-
const
|
|
4
|
+
import a from "./FilePicker.js";
|
|
5
|
+
const c = {
|
|
6
6
|
fileExtensionsAllowed: ["xlsx", "csv"],
|
|
7
7
|
maxSize: 5,
|
|
8
8
|
maxFiles: 10,
|
|
@@ -13,141 +13,145 @@ const a = {
|
|
|
13
13
|
helpLink: "https://example.com",
|
|
14
14
|
helpLinkText: "Help link"
|
|
15
15
|
};
|
|
16
|
-
function d(t,
|
|
17
|
-
return new File(["x".repeat(
|
|
16
|
+
function d(t, i = 100, u = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
|
|
17
|
+
return new File(["x".repeat(i)], t, {
|
|
18
18
|
type: u
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}),
|
|
26
|
-
|
|
21
|
+
B("FilePicker", () => {
|
|
22
|
+
B("Rendering", () => {
|
|
23
|
+
n("should render with required props", () => {
|
|
24
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c })), e(l.getByText("Upload files")).toBeInTheDocument(), e(l.getByText("Select a file")).toBeInTheDocument(), e(l.getByText("Browse file")).toBeInTheDocument();
|
|
25
|
+
}), n("should render required asterisk when required is true", () => {
|
|
26
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, required: !0 }));
|
|
27
27
|
const t = document.querySelector('[aria-hidden="true"]');
|
|
28
28
|
e(t).toBeInTheDocument(), e(t).toHaveTextContent("*");
|
|
29
|
-
}),
|
|
30
|
-
|
|
31
|
-
}),
|
|
32
|
-
|
|
33
|
-
}),
|
|
34
|
-
|
|
35
|
-
}),
|
|
36
|
-
|
|
37
|
-
}),
|
|
38
|
-
|
|
39
|
-
}),
|
|
40
|
-
|
|
29
|
+
}), n("should render single mode with Browse file button", () => {
|
|
30
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c })), e(l.getByText("Browse file")).toBeInTheDocument(), e(l.queryByText(/Browse files \(max/)).not.toBeInTheDocument();
|
|
31
|
+
}), n("should render multiple mode with Browse files button and max count", () => {
|
|
32
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, maxFiles: 5, multipleHelpText: "Only xlsx, csv files with max size of 5MB", multipleButtonHelpText: "(max 5 files)" })), e(l.getByText("Browse files (max 5 files)")).toBeInTheDocument(), e(l.getByText(/Only xlsx, csv files with max size of 5MB/)).toBeInTheDocument();
|
|
33
|
+
}), n("should display custom multipleHelpText when provided in multiple mode", () => {
|
|
34
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, multipleHelpText: "Custom extensions and size info" })), e(l.getByText("Custom extensions and size info")).toBeInTheDocument();
|
|
35
|
+
}), n("should not render multipleHelpText in single mode", () => {
|
|
36
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, multipleHelpText: "This should not appear" })), e(l.queryByText("This should not appear")).not.toBeInTheDocument();
|
|
37
|
+
}), n("should display custom multipleButtonHelpText in button when provided in multiple mode", () => {
|
|
38
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, multipleButtonHelpText: "(max 3 files, 2MB each)" })), e(l.getByText("Browse files (max 3 files, 2MB each)")).toBeInTheDocument();
|
|
39
|
+
}), n("should render file input with correct accept and multiple attributes", () => {
|
|
40
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c }));
|
|
41
41
|
const t = l.getByTestId("file-picker-input");
|
|
42
42
|
e(t).toHaveAttribute("accept", ".xlsx,.csv"), e(t).toHaveAttribute("multiple");
|
|
43
|
-
}),
|
|
44
|
-
|
|
43
|
+
}), n("should render single file input without multiple attribute", () => {
|
|
44
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c }));
|
|
45
45
|
const t = l.getByTestId("file-picker-input");
|
|
46
46
|
e(t).not.toHaveAttribute("multiple");
|
|
47
|
-
}),
|
|
47
|
+
}), n("should display selected file name in single mode", async () => {
|
|
48
48
|
const t = d("report.xlsx");
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
await r.upload(
|
|
49
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c }));
|
|
50
|
+
const i = l.getByTestId("file-picker-input");
|
|
51
|
+
await r.upload(i, t), await m(() => {
|
|
52
52
|
e(l.getByText("report.xlsx")).toBeInTheDocument();
|
|
53
53
|
});
|
|
54
|
-
}),
|
|
55
|
-
|
|
54
|
+
}), n("should display error message when provided", () => {
|
|
55
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, errorMessage: "Please select a file" })), e(l.getByText("Please select a file")).toBeInTheDocument();
|
|
56
56
|
});
|
|
57
|
-
}),
|
|
58
|
-
|
|
59
|
-
const t = f.fn(),
|
|
60
|
-
|
|
57
|
+
}), B("onUpload", () => {
|
|
58
|
+
n("should call onUpload with uploaded file when single file is selected", async () => {
|
|
59
|
+
const t = f.fn(), i = d("document.xlsx");
|
|
60
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, onUpload: t }));
|
|
61
61
|
const u = l.getByTestId("file-picker-input");
|
|
62
|
-
await r.upload(u,
|
|
62
|
+
await r.upload(u, i), await m(() => {
|
|
63
63
|
e(t).toHaveBeenCalledTimes(1), e(t).toHaveBeenCalledWith([e.objectContaining({
|
|
64
64
|
file: e.any(File),
|
|
65
65
|
error: void 0
|
|
66
66
|
})]), e(t.mock.calls[0][0][0].file.name).toBe("document.xlsx");
|
|
67
67
|
});
|
|
68
|
-
}),
|
|
69
|
-
const t = f.fn(),
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
await r.upload(
|
|
68
|
+
}), n("should call onUpload with all selected files when multiple files selected (non-queue)", async () => {
|
|
69
|
+
const t = f.fn(), i = d("a.xlsx"), u = d("b.xlsx");
|
|
70
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", queueFiles: !1, ...c, onUpload: t }));
|
|
71
|
+
const x = l.getByTestId("file-picker-input");
|
|
72
|
+
await r.upload(x, [i, u]), await m(() => {
|
|
73
73
|
e(t).toHaveBeenCalledTimes(1);
|
|
74
74
|
const p = t.mock.calls[0][0];
|
|
75
75
|
e(p).toHaveLength(2), e(p[0].file.name).toBe("a.xlsx"), e(p[1].file.name).toBe("b.xlsx");
|
|
76
76
|
});
|
|
77
|
-
}),
|
|
78
|
-
const t = f.fn(),
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
await r.upload(
|
|
77
|
+
}), n("should call onUpload with accumulated files when queueFiles is true", async () => {
|
|
78
|
+
const t = f.fn(), i = d("first.xlsx"), u = d("second.xlsx");
|
|
79
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", queueFiles: !0, ...c, maxFiles: 10, onUpload: t }));
|
|
80
|
+
const x = l.getByTestId("file-picker-input");
|
|
81
|
+
await r.upload(x, i), await m(() => {
|
|
82
82
|
e(t).toHaveBeenCalledTimes(1);
|
|
83
83
|
const p = t.mock.calls[0][0];
|
|
84
84
|
e(p).toHaveLength(1), e(p[0].file.name).toBe("first.xlsx");
|
|
85
|
-
}), await r.upload(
|
|
85
|
+
}), await r.upload(x, u), await m(() => {
|
|
86
86
|
e(t).toHaveBeenCalledTimes(2);
|
|
87
87
|
const p = t.mock.calls[1][0];
|
|
88
88
|
e(p).toHaveLength(2), e(p[0].file.name).toBe("first.xlsx"), e(p[1].file.name).toBe("second.xlsx");
|
|
89
89
|
});
|
|
90
|
-
}),
|
|
91
|
-
const t = f.fn(),
|
|
92
|
-
|
|
90
|
+
}), n("should include validation error in onUpload when file extension is invalid", async () => {
|
|
91
|
+
const t = f.fn(), i = d("document.pdf", 100, "application/pdf");
|
|
92
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, fileExtensionsAllowed: ["xlsx"], onUpload: t }));
|
|
93
93
|
const u = l.getByTestId("file-picker-input");
|
|
94
|
-
|
|
94
|
+
T.change(u, {
|
|
95
95
|
target: {
|
|
96
|
-
files: [
|
|
96
|
+
files: [i]
|
|
97
97
|
}
|
|
98
|
-
}), await
|
|
98
|
+
}), await m(() => {
|
|
99
99
|
e(t).toHaveBeenCalledWith([e.objectContaining({
|
|
100
100
|
file: e.any(File),
|
|
101
101
|
error: e.stringContaining("file format is incorrect")
|
|
102
102
|
})]);
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
|
-
}),
|
|
106
|
-
|
|
107
|
-
const t = f.fn(),
|
|
108
|
-
|
|
105
|
+
}), B("onRemoveFile", () => {
|
|
106
|
+
n("should call onRemoveFile when remove button is clicked in single mode", async () => {
|
|
107
|
+
const t = f.fn(), i = d("to-remove.xlsx");
|
|
108
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, onRemoveFile: t }));
|
|
109
109
|
const u = l.getByTestId("file-picker-input");
|
|
110
|
-
await r.upload(u,
|
|
110
|
+
await r.upload(u, i), await m(() => {
|
|
111
111
|
e(l.getByText("to-remove.xlsx")).toBeInTheDocument();
|
|
112
112
|
});
|
|
113
|
-
const
|
|
114
|
-
await r.click(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
113
|
+
const x = l.getByTestId("file-picker-remove-single");
|
|
114
|
+
await r.click(x), e(t).toHaveBeenCalledTimes(1);
|
|
115
|
+
const [p, h] = t.mock.calls[0];
|
|
116
|
+
e(p).toBe(i), e(h).toHaveLength(0);
|
|
117
|
+
}), n("should call onRemoveFile when remove button is clicked in multiple mode", async () => {
|
|
118
|
+
const t = f.fn(), i = d("one.xlsx"), u = d("two.xlsx");
|
|
119
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, onRemoveFile: t }));
|
|
120
|
+
const x = l.getByTestId("file-picker-input");
|
|
121
|
+
await r.upload(x, [i, u]), await m(() => {
|
|
120
122
|
e(l.getByText("one.xlsx")).toBeInTheDocument(), e(l.getByText("two.xlsx")).toBeInTheDocument();
|
|
121
123
|
});
|
|
122
|
-
const p = l.getByTestId("file-picker-remove-
|
|
123
|
-
await r.click(p), e(t).
|
|
124
|
+
const p = l.getByTestId("file-picker-remove-1");
|
|
125
|
+
await r.click(p), e(t).toHaveBeenCalledTimes(1);
|
|
126
|
+
const [h, y] = t.mock.calls[0];
|
|
127
|
+
e(h).toBe(u), e(y).toHaveLength(1), e(y[0].file).toBe(i);
|
|
124
128
|
});
|
|
125
|
-
}),
|
|
126
|
-
|
|
127
|
-
const t = f.fn(),
|
|
128
|
-
|
|
129
|
+
}), B("Disabled state", () => {
|
|
130
|
+
n("should not call onUpload when disabled and file is selected", async () => {
|
|
131
|
+
const t = f.fn(), i = d("doc.xlsx");
|
|
132
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, disabled: !0, onUpload: t }));
|
|
129
133
|
const u = l.getByTestId("file-picker-input");
|
|
130
|
-
await r.upload(u,
|
|
131
|
-
}),
|
|
132
|
-
const t = f.fn(),
|
|
133
|
-
|
|
134
|
+
await r.upload(u, i), e(t).not.toHaveBeenCalled();
|
|
135
|
+
}), n("should not call onRemoveFile when disabled and remove is clicked", async () => {
|
|
136
|
+
const t = f.fn(), i = d("doc.xlsx");
|
|
137
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, disabled: !0, value: [i], onRemoveFile: t })), e(l.getByText("doc.xlsx")).toBeInTheDocument();
|
|
134
138
|
const u = l.getByTestId("file-picker-remove-single");
|
|
135
139
|
e(u).toBeDisabled(), await r.click(u), e(t).not.toHaveBeenCalled();
|
|
136
140
|
});
|
|
137
|
-
}),
|
|
138
|
-
|
|
141
|
+
}), B("Controlled value", () => {
|
|
142
|
+
n("should display files from value prop", () => {
|
|
139
143
|
const t = d("controlled.xlsx");
|
|
140
|
-
|
|
141
|
-
}),
|
|
144
|
+
s(/* @__PURE__ */ o(a, { type: "single", ...c, value: [t] })), e(l.getByText("controlled.xlsx")).toBeInTheDocument();
|
|
145
|
+
}), n("should display multiple files from value prop", () => {
|
|
142
146
|
const t = [d("a.xlsx"), d("b.xlsx")];
|
|
143
|
-
|
|
147
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, value: t })), e(l.getByText("a.xlsx")).toBeInTheDocument(), e(l.getByText("b.xlsx")).toBeInTheDocument();
|
|
144
148
|
});
|
|
145
|
-
}),
|
|
146
|
-
|
|
149
|
+
}), B("Max files exceeded", () => {
|
|
150
|
+
n("should show max files exceeded message when over limit in multiple mode", async () => {
|
|
147
151
|
const t = [d("1.xlsx"), d("2.xlsx"), d("3.xlsx")];
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
await r.upload(
|
|
152
|
+
s(/* @__PURE__ */ o(a, { type: "multiple", ...c, maxFiles: 2 }));
|
|
153
|
+
const i = l.getByTestId("file-picker-input");
|
|
154
|
+
await r.upload(i, t), await m(() => {
|
|
151
155
|
e(l.getByText(/You can only upload up to 2 files/)).toBeInTheDocument();
|
|
152
156
|
});
|
|
153
157
|
});
|