@alixpartners/ui-components 2.4.2 → 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.
@@ -39,16 +39,19 @@ type DragAndDropProps = {
39
39
  label?: string;
40
40
  required?: boolean;
41
41
  fileExtensionsAllowed: string[];
42
- maxSize: number;
42
+ maxSize?: number;
43
43
  maxFiles?: number;
44
44
  value?: File | File[];
45
45
  onUpload?: (files: UploadFile[]) => void;
46
46
  /**
47
47
  * Callback fired when a file is removed.
48
- * @param fileName - Name of the file to remove
48
+ * @param removedFile - The file that was removed
49
+ * @param remaining - The list of files remaining after removal
49
50
  */
50
- onRemoveFile?: (fileName: string) => void;
51
+ onRemoveFile?: (removedFile: File, remaining: UploadFile[]) => void;
51
52
  queueFiles?: boolean;
53
+ maxSizeErrorMessage?: string;
54
+ fileExtensionInvalidErrorMessage?: string;
52
55
  /**
53
56
  * Customizable text content for the component.
54
57
  * @note Should be memoized (e.g., using `useMemo`) to prevent unnecessary re-renders.
@@ -83,12 +86,12 @@ type DragAndDropProps = {
83
86
  * @param {string} [props.label] - Optional label displayed above the drop area
84
87
  * @param {boolean} [props.required] - Whether the field is required; shows an asterisk
85
88
  * @param {string[]} props.fileExtensionsAllowed - Allowed file extensions (e.g. ['pdf','png'])
86
- * @param {number} props.maxSize - Maximum file size in MB
89
+ * @param {number} [props.maxSize] - Maximum file size in MB; default no limit
87
90
  * @param {number} [props.maxFiles] - Maximum number of files when type is 'multiple'
88
91
  * @param {File | File[]} [props.value] - Controlled value for the component; accepts a single File or array of Files
89
92
  * @param {(files: UploadFile[]) => void} [props.onUpload] - Callback fired with validated files upon selection or drop
90
93
  * @param {boolean} [props.queueFiles] - When true, newly selected files are appended to the existing list
91
94
  * @returns {JSX.Element} The rendered DragAndDrop component
92
95
  */
93
- export default function DragAndDrop({ label, type, disabled, required, fileExtensionsAllowed, maxSize, maxFiles, value, onUpload, onRemoveFile, queueFiles, className, texts, fileIcon, errorIcon, deleteIcon, browseButtonIcon, renderFileItem, fileSizeFormatter, browseButtonProps, validator, errors: externalErrors, ...props }: DragAndDropProps): import("react/jsx-runtime").JSX.Element;
96
+ export default function DragAndDrop({ label, type, disabled, required, fileExtensionsAllowed, maxSize, maxFiles, value, onUpload, onRemoveFile, queueFiles, className, maxSizeErrorMessage, fileExtensionInvalidErrorMessage, texts, fileIcon, errorIcon, deleteIcon, browseButtonIcon, renderFileItem, fileSizeFormatter, browseButtonProps, validator, errors: externalErrors, ...props }: DragAndDropProps): import("react/jsx-runtime").JSX.Element;
94
97
  export {};
@@ -1,16 +1,16 @@
1
- import { jsxs as g, jsx as t } from "react/jsx-runtime";
2
- import { useId as hr, useRef as Nr, useState as Q, useCallback as m, useMemo as A } from "react";
3
- import R from "../Button/Button.js";
4
- import { c as J } from "../../clsx-OuTLNxxd.js";
5
- import K from "../Icon/Icon.js";
6
- import '../../assets/DragAndDrop.css';const Ar = "DragAndDrop-module__disabled___h47do", vr = "DragAndDrop-module__required___z3cHB", Ir = "DragAndDrop-module__active___ZMuEx", n = {
1
+ import { jsxs as _, jsx as t } from "react/jsx-runtime";
2
+ import { useId as vr, useRef as Lr, useState as J, useCallback as g, useMemo as A } from "react";
3
+ import K from "../Button/Button.js";
4
+ import { c as U } from "../../clsx-OuTLNxxd.js";
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", d = {
7
7
  "drag-and-drop-container": "DragAndDrop-module__drag-and-drop-container___WHqGh",
8
- disabled: Ar,
9
- required: vr,
8
+ disabled: Cr,
9
+ required: br,
10
10
  "drag-and-drop-space-text-message": "DragAndDrop-module__drag-and-drop-space-text-message___fL-Ac",
11
11
  "drag-and-drop-space-text-constraints": "DragAndDrop-module__drag-and-drop-space-text-constraints___YrL7J",
12
12
  "drag-and-drop-space": "DragAndDrop-module__drag-and-drop-space___09a0I",
13
- active: Ir,
13
+ active: Or,
14
14
  "drag-and-drop-space-text": "DragAndDrop-module__drag-and-drop-space-text___-8rqC",
15
15
  "drag-and-drop-files-list": "DragAndDrop-module__drag-and-drop-files-list___7WNCk",
16
16
  "drag-and-drop-files-list-item": "DragAndDrop-module__drag-and-drop-files-list-item___vQO6M",
@@ -24,160 +24,160 @@ import '../../assets/DragAndDrop.css';const Ar = "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
- };
28
- function Or({
29
- label: k,
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
+ function Rr({
29
+ label: u,
30
30
  type: i = "single",
31
- disabled: w,
32
- required: F,
31
+ disabled: q,
32
+ required: rr,
33
33
  fileExtensionsAllowed: c,
34
- maxSize: p,
34
+ maxSize: p = Number.POSITIVE_INFINITY,
35
35
  maxFiles: l = Number.POSITIVE_INFINITY,
36
- value: f,
37
- onUpload: _,
38
- onRemoveFile: v,
39
- queueFiles: q,
40
- className: U,
41
- texts: e,
42
- fileIcon: x = "ap-icon-document",
43
- errorIcon: rr = "ap-icon-alert",
44
- deleteIcon: er = "ap-icon-delete",
45
- browseButtonIcon: ar,
46
- renderFileItem: j,
47
- fileSizeFormatter: C,
48
- browseButtonProps: nr,
49
- validator: b,
50
- errors: I,
51
- ...ir
36
+ value: D,
37
+ onUpload: m,
38
+ onRemoveFile: I,
39
+ queueFiles: P,
40
+ className: er,
41
+ maxSizeErrorMessage: T,
42
+ fileExtensionInvalidErrorMessage: v,
43
+ texts: a,
44
+ fileIcon: ar = "ap-icon-document",
45
+ errorIcon: nr = "ap-icon-alert",
46
+ deleteIcon: dr = "ap-icon-delete",
47
+ browseButtonIcon: ir,
48
+ renderFileItem: V,
49
+ fileSizeFormatter: O,
50
+ browseButtonProps: or,
51
+ validator: B,
52
+ errors: L,
53
+ ...sr
52
54
  }) {
53
- const y = hr(), P = Nr(null), [u, S] = Q([]), [V, L] = Q(!1), D = f !== void 0, Y = c.join(", "), Z = p ? `up to ${p}MB` : "", dr = c.map((r) => `.${r.replace(/^\./, "")}`).join(","), G = m((r, a) => {
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) => {
54
56
  if (!r) return r || "";
55
- if (e != null && e.errors && a) {
56
- if (a === "SIZE_TOO_LARGE" && e.errors.sizeTooLarge)
57
- return typeof e.errors.sizeTooLarge == "function" ? e.errors.sizeTooLarge(p) : e.errors.sizeTooLarge;
58
- if (a === "INVALID_EXTENSION" && e.errors.invalidExtension)
59
- return typeof e.errors.invalidExtension == "function" ? e.errors.invalidExtension(c) : e.errors.invalidExtension;
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;
60
62
  }
61
63
  return r;
62
- }, [e, p, c]), or = m(() => e != null && e.browse ? typeof e.browse == "function" ? e.browse(i) : e.browse : i === "single" ? "Browse file" : "Browse files", [e, i]), sr = m(() => e != null && e.drag ? typeof e.drag == "function" ? e.drag(i) : e.drag : i === "single" ? "or drag your file" : "or drag multiple files", [e, i]), tr = m(() => e != null && e.constraints ? e.constraints({
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({
63
65
  extensions: c,
64
66
  maxSize: p,
65
67
  type: i
66
- }) : `${Y} ${i === "single" ? "file" : "files"} ${Z}`, [e, c, Y, p, Z, i]), lr = () => {
68
+ }) : `${M} ${i === "single" ? "file" : "files"} ${X}`, [a, c, M, p, X, i]), gr = () => {
67
69
  var r;
68
- N || (r = P.current) == null || r.click();
69
- }, B = A(() => new Set(c.map((r) => r.toLowerCase().replace(/^\./, ""))), [c]), H = m((r, a) => {
70
- const s = a.maxSize ? a.maxSize * 1024 * 1024 : Number.POSITIVE_INFINITY, o = r.size <= s, h = r.name.toLowerCase(), ur = h.includes(".") ? h.split(".").pop() ?? "" : "", Dr = B.size === 0 || B.has(ur);
71
- return o ? Dr ? {
70
+ N || (r = y.current) == null || r.click();
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
+ return Ar ? Tr ? {
72
74
  file: r
73
75
  } : {
74
76
  file: r,
75
- error: `The file format is incorrect. Please make sure it is one of the extensions: ${a.fileExtensionsAllowed.join(", ")}.`,
77
+ error: Nr,
76
78
  errorCode: "INVALID_EXTENSION"
77
79
  } : {
78
80
  file: r,
79
- error: `File size is too large. Must be up to ${a.maxSize}MB.`,
81
+ error: f,
80
82
  errorCode: "SIZE_TOO_LARGE"
81
83
  };
82
- }, [B]), O = A(() => ({
84
+ }, [$, T, v]), k = A(() => ({
83
85
  maxSize: p,
84
86
  fileExtensionsAllowed: c,
85
87
  type: i,
86
88
  maxFiles: l
87
- }), [p, c, i, l]), T = m((r) => {
88
- let a;
89
- b ? a = r.map((o) => b(o, O)) : a = r.map((o) => H(o, O));
90
- let s = a.map((o) => {
91
- const h = o.error ? G(o.error, o.errorCode) : void 0;
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;
92
94
  return {
93
95
  file: o.file,
94
96
  // Don't merge external errors here - that happens in files useMemo
95
- error: h
97
+ error: f
96
98
  };
97
99
  });
98
- return i === "single" && s.length > 1 ? s.slice(0, 1) : (l && l > 0 && s.length > l && (s = s.map((o, h) => h < l ? o : {
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 : {
99
101
  ...o,
100
102
  error: o.error ?? `Maximum ${l} file${l === 1 ? "" : "s"} allowed.`
101
103
  })), s);
102
- }, [i, l, b, O, G, H]), d = A(() => {
104
+ }, [i, l, B, k, Z, H]), n = A(() => {
103
105
  let r;
104
- if (D) {
105
- const a = Array.isArray(f) ? f : f ? [f] : [];
106
- r = T(a);
106
+ if (h) {
107
+ const e = Array.isArray(D) ? D : D ? [D] : [];
108
+ r = b(e);
107
109
  } else
108
- r = u;
109
- return r.map((a) => ({
110
- ...a,
110
+ r = C;
111
+ return r.map((e) => ({
112
+ ...e,
111
113
  // Validator errors take precedence over external errors
112
- error: a.error ?? (I == null ? void 0 : I[a.file.name])
114
+ error: e.error ?? (L == null ? void 0 : L[e.file.name])
113
115
  }));
114
- }, [D, f, T, u, I]), cr = m((r) => C ? C(r) : (r / 1024).toFixed(2) + " KB", [C]), N = A(() => w || (d == null ? void 0 : d.length) >= l || i === "single" && (d == null ? void 0 : d.length) > 0, [w, d, l, i]), W = m((r) => {
115
- const a = T(r);
116
- if (D)
117
- _ == null || _(a);
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
+ if (h)
119
+ m == null || m(e);
118
120
  else {
119
- const s = q ? [...u, ...a] : a;
120
- S(s), _ == null || _(s);
121
+ const s = P ? [...C, ...e] : e;
122
+ Y(s), m == null || m(s);
121
123
  }
122
- }, [T, D, q, u, _]), gr = (r) => {
124
+ }, [b, h, P, C, m]), mr = (r) => {
123
125
  if (!r.target.files) return;
124
- const a = Array.from(r.target.files);
125
- W(a), r.target.value = "";
126
- }, z = m((r) => {
127
- if (!D) {
128
- const a = u.filter((s) => s.file.name !== r);
129
- S(a);
130
- }
131
- v == null || v(r);
132
- }, [D, u, v]), X = A(() => new Map(d.map((r) => [r.file.name, () => z(r.file.name)])), [d, z]), {
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]), {
133
133
  onDragOver: E,
134
- onDragLeave: M,
135
- onDrop: $,
136
- ...mr
137
- } = ir, pr = (r) => {
138
- N || (r.preventDefault(), V || L(!0), E == null || E(r));
139
- }, _r = (r) => {
140
- r.preventDefault(), L(!1), M == null || M(r);
141
- }, fr = (r) => {
134
+ onDragLeave: z,
135
+ onDrop: R,
136
+ ...fr
137
+ } = sr, ur = (r) => {
138
+ N || (r.preventDefault(), G || S(!0), E == null || E(r));
139
+ }, Dr = (r) => {
140
+ r.preventDefault(), S(!1), z == null || z(r);
141
+ }, hr = (r) => {
142
142
  if (N) return;
143
143
  r.preventDefault();
144
- const a = Array.from(r.dataTransfer.files);
145
- W(a), r.dataTransfer.clearData(), L(!1), $ == null || $(r);
144
+ const e = Array.from(r.dataTransfer.files);
145
+ W(e), r.dataTransfer.clearData(), S(!1), R == null || R(r);
146
146
  };
147
- return /* @__PURE__ */ g("div", { className: J(n["drag-and-drop-container"], N && n.disabled, U), ...mr, children: [
148
- k && /* @__PURE__ */ g("label", { htmlFor: y, children: [
149
- k,
150
- F && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: n.required, children: "*" })
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: "*" })
151
151
  ] }),
152
- /* @__PURE__ */ g("div", { className: J(n["drag-and-drop-space"], V && n.active), onDragOver: pr, onDragLeave: _r, onDrop: fr, children: [
153
- /* @__PURE__ */ t(R, { type: "secondary", variant: "default", size: "sm", ...nr, disabled: N, onClick: lr, icon: ar, children: or() }),
154
- /* @__PURE__ */ t("input", { id: y, ref: P, type: "file", style: {
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() }),
154
+ /* @__PURE__ */ t("input", { id: j, ref: y, type: "file", style: {
155
155
  display: "none"
156
- }, multiple: i === "multiple", accept: dr, onChange: gr }),
157
- /* @__PURE__ */ g("div", { className: n["drag-and-drop-space-text"], children: [
158
- /* @__PURE__ */ t("span", { className: n["drag-and-drop-space-text-message"], children: sr() }),
159
- /* @__PURE__ */ g("span", { className: n["drag-and-drop-space-text-constraints"], children: [
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: [
160
160
  " ",
161
- tr()
161
+ _r()
162
162
  ] })
163
163
  ] })
164
164
  ] }),
165
- (d == null ? void 0 : d.length) > 0 && /* @__PURE__ */ t("ul", { className: n["drag-and-drop-files-list"], children: d == null ? void 0 : d.map((r, a) => j ? /* @__PURE__ */ t("li", { children: j(r, a, X.get(r.file.name) ?? (() => z(r.file.name))) }, r.file.name) : /* @__PURE__ */ t("li", { className: n["drag-and-drop-files-list-item"], children: /* @__PURE__ */ g("div", { className: n["drag-and-drop-files-list-item-content"], children: [
166
- /* @__PURE__ */ t("span", { className: n["drag-and-drop-files-list-item-icon-container"], children: /* @__PURE__ */ t(K, { icon: x, className: n["drag-and-drop-files-list-item-icon"] }) }),
167
- /* @__PURE__ */ g("div", { className: n["drag-and-drop-files-list-item-content-data"], children: [
168
- /* @__PURE__ */ g("div", { className: n["drag-and-drop-files-list-item-text"], children: [
169
- /* @__PURE__ */ t("span", { className: n["drag-and-drop-files-list-item-name"], children: r.file.name }),
170
- /* @__PURE__ */ t("span", { className: n["drag-and-drop-files-list-item-size"], children: cr(r.file.size) }),
171
- r.error && /* @__PURE__ */ g("span", { className: n["drag-and-drop-files-list-item-error"], children: [
172
- /* @__PURE__ */ t(K, { icon: rr, className: n["drag-and-drop-files-list-item-icon-error"] }),
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"] }),
173
173
  r.error
174
174
  ] })
175
175
  ] }),
176
- /* @__PURE__ */ t(R, { type: "tertiary", variant: "default", size: "sm", onClick: X.get(r.file.name), icon: er, iconClassName: n["drag-and-drop-files-list-item-icon-delete"], "aria-label": `Remove ${r.file.name}` })
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}` })
177
177
  ] })
178
- ] }) }, r.file.name)) })
178
+ ] }) }, e)) })
179
179
  ] });
180
180
  }
181
181
  export {
182
- Or as default
182
+ Rr as default
183
183
  };
@@ -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 h, d as I } from "../../DragAndDrop.utils-D3xTV9EK.js";
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), e(n).toHaveBeenCalledWith("test.pdf"), await f(() => {
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 = n.filter((T) => T.file.name !== m);
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), e(r).toHaveBeenCalledWith("test1.pdf");
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 = h(t, a), s = {
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 = h(t, a), s = {
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 = h(t, a), s = {
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 T = I(x, m);
568
- return T.error ? T : x.name.startsWith("reject") ? {
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 = h(I, t), n = {
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 = h(I, t), n = new File(["test"], "blocked.pdf", {
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,15 +31,16 @@ export type FilePickerContextValue = {
31
31
  inputRef: React.RefObject<HTMLInputElement | null>;
32
32
  triggerInput: () => void;
33
33
  handleKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => void;
34
- handleRemoveFile: (fileName: string) => void;
34
+ handleRemoveFile: (index: number) => void;
35
35
  displayFileSize: (size: number) => string;
36
+ uploadedFileAppendedRow?: (item: UploadFile, index: number) => ReactNode;
36
37
  };
37
38
  declare function useFilePickerContext(): FilePickerContextValue;
38
39
  type FilePickerProps = {
39
40
  type?: 'single' | 'multiple';
40
41
  maxFiles?: number;
41
42
  fileExtensionsAllowed: string[];
42
- maxSize: number;
43
+ maxSize?: number;
43
44
  queueFiles?: boolean;
44
45
  isUploadDisabled?: boolean;
45
46
  disabled?: boolean;
@@ -48,21 +49,24 @@ type FilePickerProps = {
48
49
  required?: boolean;
49
50
  placeholder?: string;
50
51
  errorMessage?: string;
52
+ maxSizeErrorMessage?: string;
53
+ fileExtensionInvalidErrorMessage?: string;
51
54
  helpText?: string;
52
55
  helpLink?: string;
53
56
  helpLinkText?: string;
54
57
  multipleHelpText?: string;
55
58
  multipleButtonHelpText?: string;
56
59
  labelTooltip?: InputLabelTooltipProps;
60
+ uploadedFileAppendedRow?: (item: UploadFile, index: number) => ReactNode;
57
61
  onUpload?: (files: UploadFile[]) => void;
58
- onRemoveFile?: (fileName: string) => void;
62
+ onRemoveFile?: (removedFile: File, remaining: UploadFile[]) => void;
59
63
  children?: ReactNode;
60
64
  } & InteractiveEventHandlers;
61
65
  /**
62
66
  * FilePicker root. Use with no children for default layout, or compose with
63
67
  * FilePicker.Label, FilePicker.BrowseButton, FilePicker.HelpText, FilePicker.UploadedFilesList, etc.
64
68
  */
65
- declare function FilePickerRoot({ type, maxFiles, fileExtensionsAllowed, maxSize, queueFiles, disabled, isUploadDisabled, value, label, required, placeholder, errorMessage, helpText, helpLink, helpLinkText, multipleHelpText, multipleButtonHelpText, labelTooltip, onUpload, onRemoveFile, children, }: FilePickerProps): import("react/jsx-runtime").JSX.Element;
69
+ declare function FilePickerRoot({ type, maxFiles, fileExtensionsAllowed, maxSize, queueFiles, disabled, isUploadDisabled, value, label, required, placeholder, errorMessage, maxSizeErrorMessage, fileExtensionInvalidErrorMessage, helpText, helpLink, helpLinkText, multipleHelpText, multipleButtonHelpText, labelTooltip, uploadedFileAppendedRow, onUpload, onRemoveFile, children, }: FilePickerProps): import("react/jsx-runtime").JSX.Element;
66
70
  type FilePickerLabelProps = {
67
71
  /** Override label text. If not provided, uses FilePicker's label prop. */
68
72
  children?: ReactNode;