@alixpartners/ui-components 2.3.0 → 2.3.2

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,153 +1,242 @@
1
- import { jsxs as n, jsx as t } from "react/jsx-runtime";
2
- import { useId as J, useRef as Y, useState as M, useEffect as G } from "react";
3
- import Q from "../Tooltip/Tooltip.js";
4
- import g from "../Icon/Icon.js";
5
- import I from "../Button/Button.js";
6
- import { c as W } from "../../clsx-OuTLNxxd.js";
7
- import '../../assets/FilePicker.css';const Z = "FilePicker-module__container___knCCi", ee = "FilePicker-module__label___al7Xe", ie = "FilePicker-module__required___41Vjd", le = "FilePicker-module__labelTooltipIcon___Cc1QF", te = "FilePicker-module__helpers___79-g5", ne = "FilePicker-module__helperText___ja9Rr", se = "FilePicker-module__errorMessage___TvHrL", oe = "FilePicker-module__singleFileHelpLinkContainer___mpjUf", ce = "FilePicker-module__singleFileHelpLinkReservedSpace___r8j2b", re = "FilePicker-module__helpLink___uu45D", me = "FilePicker-module__input___cL1Hs", ae = "FilePicker-module__singleFileContainer___OFSDt", ue = "FilePicker-module__singleFileInputContainer___MOkES", pe = "FilePicker-module__inputFileName___sMs7R", _e = "FilePicker-module__inputFileNamePlaceholder___-mkDD", Fe = "FilePicker-module__inputButton___ghLlD", de = "FilePicker-module__multipleHelpText___5tnnn", Ie = "FilePicker-module__multipleInputButton___WCJp9", he = "FilePicker-module__multipleFilesList___Kim0I", Le = "FilePicker-module__multipleFilesListItem___01PDS", ke = "FilePicker-module__multipleFilesListItemContent___pKbho", fe = "FilePicker-module__multipleFilesListItemContentData___5GC-C", Ne = "FilePicker-module__multipleFilesListItemIconContainer___7sUL5", ge = "FilePicker-module__multipleFilesListItemIcon___nfMX9", Ce = "FilePicker-module__multipleFilesListItemText___nPqrL", Pe = "FilePicker-module__multipleFilesListItemName___NjHhX", xe = "FilePicker-module__multipleFilesListItemSize___wc8LJ", ve = "FilePicker-module__multipleFilesListItemError___x9qkT", De = "FilePicker-module__multipleFilesListItemIconError___0RO46", Ee = "FilePicker-module__multipleFilesListItemIconDelete___9Z9Dl", Te = "FilePicker-module__disabled___szMiq", e = {
8
- container: Z,
9
- label: ee,
10
- required: ie,
11
- labelTooltipIcon: le,
12
- helpers: te,
13
- helperText: ne,
14
- errorMessage: se,
15
- singleFileHelpLinkContainer: oe,
16
- singleFileHelpLinkReservedSpace: ce,
17
- helpLink: re,
18
- input: me,
19
- singleFileContainer: ae,
20
- singleFileInputContainer: ue,
21
- inputFileName: pe,
22
- inputFileNamePlaceholder: _e,
23
- inputButton: Fe,
24
- multipleHelpText: de,
25
- multipleInputButton: Ie,
26
- multipleFilesList: he,
27
- multipleFilesListItem: Le,
28
- multipleFilesListItemContent: ke,
29
- multipleFilesListItemContentData: fe,
30
- multipleFilesListItemIconContainer: Ne,
31
- multipleFilesListItemIcon: ge,
32
- multipleFilesListItemText: Ce,
33
- multipleFilesListItemName: Pe,
34
- multipleFilesListItemSize: xe,
35
- multipleFilesListItemError: ve,
36
- multipleFilesListItemIconError: De,
37
- multipleFilesListItemIconDelete: Ee,
38
- disabled: Te
39
- };
40
- function Me({
41
- type: c = "single",
42
- maxFiles: _ = 1,
43
- fileExtensionsAllowed: h,
44
- maxSize: u,
45
- queueFiles: j = !1,
46
- disabled: s = !1,
47
- value: F,
48
- label: C,
49
- required: b = !1,
50
- placeholder: q,
51
- errorMessage: m,
52
- helpText: L,
53
- helpLink: P,
54
- helpLinkText: x,
55
- labelTooltip: r
1
+ import { jsxs as a, jsx as i, Fragment as ne } from "react/jsx-runtime";
2
+ import { createContext as se, useId as re, useRef as oe, useState as v, useCallback as _, useEffect as ce, useContext as ae } from "react";
3
+ import pe from "../Tooltip/Tooltip.js";
4
+ import D from "../Icon/Icon.js";
5
+ import x from "../Button/Button.js";
6
+ import { c as C } from "../../clsx-OuTLNxxd.js";
7
+ import '../../assets/FilePicker.css';const ue = "FilePicker-module__container___knCCi", me = "FilePicker-module__label___al7Xe", de = "FilePicker-module__required___41Vjd", Fe = "FilePicker-module__labelTooltipIcon___Cc1QF", _e = "FilePicker-module__helpers___79-g5", Ie = "FilePicker-module__helperText___ja9Rr", he = "FilePicker-module__errorMessage___TvHrL", Le = "FilePicker-module__singleFileHelpLinkContainer___mpjUf", ge = "FilePicker-module__singleFileHelpLinkReservedSpace___r8j2b", ke = "FilePicker-module__helpLink___uu45D", fe = "FilePicker-module__input___cL1Hs", Pe = "FilePicker-module__singleFileContainer___OFSDt", Ne = "FilePicker-module__singleFileInputContainer___MOkES", xe = "FilePicker-module__inputFileName___sMs7R", Ce = "FilePicker-module__inputFileNamePlaceholder___-mkDD", Te = "FilePicker-module__inputButton___ghLlD", be = "FilePicker-module__multipleHelpText___5tnnn", ye = "FilePicker-module__multipleInputButton___WCJp9", De = "FilePicker-module__multipleFilesList___Kim0I", Be = "FilePicker-module__multipleFilesListItem___01PDS", Se = "FilePicker-module__multipleFilesListItemContent___pKbho", He = "FilePicker-module__multipleFilesListItemContentData___5GC-C", ve = "FilePicker-module__multipleFilesListItemIconContainer___7sUL5", we = "FilePicker-module__multipleFilesListItemIcon___nfMX9", Me = "FilePicker-module__multipleFilesListItemText___nPqrL", Ee = "FilePicker-module__multipleFilesListItemName___NjHhX", ze = "FilePicker-module__multipleFilesListItemSize___wc8LJ", Re = "FilePicker-module__multipleFilesListItemError___x9qkT", je = "FilePicker-module__multipleFilesListItemIconError___0RO46", Ke = "FilePicker-module__multipleFilesListItemIconDelete___9Z9Dl", Ve = "FilePicker-module__disabled___szMiq", t = {
8
+ container: ue,
9
+ label: me,
10
+ required: de,
11
+ labelTooltipIcon: Fe,
12
+ helpers: _e,
13
+ helperText: Ie,
14
+ errorMessage: he,
15
+ singleFileHelpLinkContainer: Le,
16
+ singleFileHelpLinkReservedSpace: ge,
17
+ helpLink: ke,
18
+ input: fe,
19
+ singleFileContainer: Pe,
20
+ singleFileInputContainer: Ne,
21
+ inputFileName: xe,
22
+ inputFileNamePlaceholder: Ce,
23
+ inputButton: Te,
24
+ multipleHelpText: be,
25
+ multipleInputButton: ye,
26
+ multipleFilesList: De,
27
+ multipleFilesListItem: Be,
28
+ multipleFilesListItemContent: Se,
29
+ multipleFilesListItemContentData: He,
30
+ multipleFilesListItemIconContainer: ve,
31
+ multipleFilesListItemIcon: we,
32
+ multipleFilesListItemText: Me,
33
+ multipleFilesListItemName: Ee,
34
+ multipleFilesListItemSize: ze,
35
+ multipleFilesListItemError: Re,
36
+ multipleFilesListItemIconError: je,
37
+ multipleFilesListItemIconDelete: Ke,
38
+ disabled: Ve
39
+ }, w = se(null);
40
+ function p() {
41
+ const e = ae(w);
42
+ if (!e)
43
+ throw new Error("FilePicker compound components must be used within a FilePicker.");
44
+ return e;
45
+ }
46
+ function qe(e) {
47
+ const l = e.name.toLowerCase();
48
+ return l.includes(".") ? l.split(".").pop() ?? "" : "";
49
+ }
50
+ function $e({
51
+ type: e = "single",
52
+ maxFiles: l = 1,
53
+ fileExtensionsAllowed: s,
54
+ maxSize: r,
55
+ queueFiles: h = !1,
56
+ disabled: c = !1,
57
+ isUploadDisabled: E = !1,
58
+ value: L,
59
+ label: z,
60
+ required: R = !1,
61
+ placeholder: j,
62
+ errorMessage: K,
63
+ helpText: V,
64
+ helpLink: q,
65
+ helpLinkText: $,
66
+ multipleHelpText: O,
67
+ multipleButtonHelpText: A,
68
+ labelTooltip: X,
69
+ onUpload: F,
70
+ onRemoveFile: g,
71
+ children: k
56
72
  }) {
57
- var R, w;
58
- const v = J(), k = Y(null), [l, d] = M(F ? F.map((i) => ({
59
- file: i
60
- })) : []), [D, E] = M(!1);
61
- G(() => {
62
- const i = B(F ?? []);
63
- d(i);
64
- }, [F]);
65
- const K = h.map((i) => `.${i.replace(/^\./, "")}`).join(","), T = h.join(", "), V = (i) => {
66
- const o = i.name.toLowerCase();
67
- return o.includes(".") ? o.split(".").pop() ?? "" : "";
68
- }, B = (i) => {
69
- const a = l.length + i.length > _;
70
- E(a);
71
- const f = u ? u * 1024 * 1024 : Number.POSITIVE_INFINITY, y = new Set(h.map((p) => p.toLowerCase().replace(/^\./, "")));
72
- return i.map((p) => {
73
- const U = p.size <= f, X = y.size === 0 || y.has(V(p));
74
- let N;
75
- const A = u ? `up to ${u}MB` : "";
76
- return U || (N = `File size is too large. Must be ${A}.`), X || (N = `The file format is incorrect. Please make sure it is one of the extensions: ${T}.`), {
77
- file: p,
78
- error: N
73
+ const B = re(), f = oe(null), [u, P] = v(L ? L.map((n) => ({
74
+ file: n
75
+ })) : []), [J, T] = v(!1), b = s.join(", "), S = s.map((n) => `.${n.replace(/^\./, "")}`).join(","), N = _((n) => {
76
+ const o = r ? r * 1024 * 1024 : Number.POSITIVE_INFINITY, m = new Set(s.map((d) => d.toLowerCase().replace(/^\./, "")));
77
+ return n.map((d) => {
78
+ const le = d.size <= o, ie = m.size === 0 || m.has(qe(d));
79
+ let y;
80
+ const te = r ? `up to ${r}MB` : "";
81
+ return le || (y = `File size is too large. Must be ${te}.`), ie || (y = `The file format is incorrect. Please make sure it is one of the extensions: ${b}.`), {
82
+ file: d,
83
+ error: y
79
84
  };
80
85
  });
81
- }, O = (i) => (i / 1024).toFixed(2) + " KB", H = () => {
82
- var i;
83
- s || (i = k.current) == null || i.click();
84
- }, S = (i) => {
86
+ }, [s, b, r]), H = _((n) => {
87
+ const o = u.length;
88
+ return T(o + n.length > l), N(n);
89
+ }, [l, u.length, N]);
90
+ ce(() => {
91
+ const n = N(L ?? []);
92
+ P(n), T(n.length > l);
93
+ }, [L, l, N]);
94
+ const Y = _((n) => (n / 1024).toFixed(2) + " KB", []), G = _(() => {
95
+ var n;
96
+ c || (n = f.current) == null || n.click();
97
+ }, [c]), Q = _((n) => {
85
98
  var o;
86
- s || i.key === "Enter" && ((o = k.current) == null || o.click());
87
- }, $ = (i) => {
88
- if (s) return;
89
- const o = i.target.files, a = B(Array.from(o ?? []));
90
- d(c === "multiple" && j ? [...l, ...a] : a);
91
- }, z = (i) => {
92
- if (s || !l) return;
93
- const a = l.length - 1 > _;
94
- E(a), d(l == null ? void 0 : l.filter((f) => f.file.name !== i));
95
- };
96
- return /* @__PURE__ */ n("div", { className: W(e.container, s && e.disabled), children: [
97
- /* @__PURE__ */ n("label", { htmlFor: v, onClick: (i) => i.preventDefault(), className: e.label, children: [
98
- /* @__PURE__ */ t("span", { title: C, className: e.labelText, children: C }),
99
- b && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: e.required, children: "*" }),
100
- r && /* @__PURE__ */ t(Q, { content: r.content, size: r.size, theme: r.theme, tipSide: r.tipSide, tipAlignment: r.tipAlignment, startVisible: r.startVisible, children: /* @__PURE__ */ t(g, { icon: "ap-icon-info", className: e.labelTooltipIcon }) }),
101
- c === "multiple" && /* @__PURE__ */ n("span", { className: e.multipleHelpText, children: [
102
- "Only ",
103
- T,
104
- " files with max size of ",
105
- u,
106
- "MB"
107
- ] })
108
- ] }),
109
- /* @__PURE__ */ t("input", { accept: K, multiple: c === "multiple", ref: k, type: "file", id: v, className: e.input, onChange: $ }),
110
- c === "single" && /* @__PURE__ */ n("div", { className: e.singleFileContainer, children: [
111
- /* @__PURE__ */ n("div", { tabIndex: s ? -1 : 0, onClick: H, onKeyDown: S, className: e.singleFileInputContainer, children: [
112
- /* @__PURE__ */ n("span", { className: e.inputFileName, children: [
113
- l && l.length > 0 && /* @__PURE__ */ t("span", { className: e.inputFileNameText, children: l[0].file.name }),
114
- l && l.length === 0 && /* @__PURE__ */ t("span", { className: e.inputFileNamePlaceholder, children: q })
115
- ] }),
116
- /* @__PURE__ */ t(I, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-upload", className: e.inputButton, tabIndex: -1, disabled: s, children: /* @__PURE__ */ t("span", { children: "Browse file" }) })
117
- ] }),
118
- /* @__PURE__ */ t("span", { className: e.singleFileHelpLinkReservedSpace, children: l && l.length > 0 && /* @__PURE__ */ t(I, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-delete", className: e.singleFileDeleteButton, onClick: () => z(l[0].file.name), disabled: s }) })
119
- ] }),
120
- c === "multiple" && /* @__PURE__ */ t(I, { type: "secondary", variant: "default", size: "md", icon: "ap-icon-upload", className: e.multipleInputButton, onClick: H, onKeyDown: S, disabled: s, children: /* @__PURE__ */ n("span", { children: [
121
- "Browse files (max ",
122
- _,
123
- " files)"
124
- ] }) }),
125
- /* @__PURE__ */ n("div", { className: e.helpers, children: [
126
- m || D || (R = l[0]) != null && R.error ? /* @__PURE__ */ n("span", { title: m, className: e.errorMessage, children: [
127
- c === "single" && (m || ((w = l[0]) == null ? void 0 : w.error)),
128
- c === "multiple" && (m || (D ? `You can only upload up to ${_} files.` : ""))
129
- ] }) : L && c === "single" && /* @__PURE__ */ t("span", { title: L, className: e.helperText, children: L }),
130
- c === "single" && P && x && /* @__PURE__ */ n("span", { className: e.singleFileHelpLinkContainer, children: [
131
- /* @__PURE__ */ t("a", { href: P, className: e.helpLink, target: "_blank", rel: "noopener noreferrer", tabIndex: s ? -1 : 0, children: x }),
132
- /* @__PURE__ */ t("span", { className: e.singleFileHelpLinkReservedSpace })
133
- ] })
134
- ] }),
135
- c === "multiple" && l && (l == null ? void 0 : l.length) > 0 && /* @__PURE__ */ t("ul", { className: e.multipleFilesList, children: l == null ? void 0 : l.map((i, o) => /* @__PURE__ */ t("li", { className: e.multipleFilesListItem, children: /* @__PURE__ */ n("div", { className: e.multipleFilesListItemContent, children: [
136
- /* @__PURE__ */ t("span", { className: e.multipleFilesListItemIconContainer, children: /* @__PURE__ */ t(g, { icon: "ap-icon-document", className: e.multipleFilesListItemIcon }) }),
137
- /* @__PURE__ */ n("div", { className: e.multipleFilesListItemContentData, children: [
138
- /* @__PURE__ */ n("div", { className: e.multipleFilesListItemText, children: [
139
- /* @__PURE__ */ t("span", { className: e.multipleFilesListItemName, children: i.file.name }),
140
- /* @__PURE__ */ t("span", { className: e.multipleFilesListItemSize, children: O(i.file.size) }),
141
- i.error && /* @__PURE__ */ n("span", { className: e.multipleFilesListItemError, children: [
142
- /* @__PURE__ */ t(g, { icon: "ap-icon-alert", className: e.multipleFilesListItemIconError }),
143
- i.error
144
- ] })
145
- ] }),
146
- /* @__PURE__ */ t(I, { type: "tertiary", variant: "default", size: "sm", onClick: () => z(i.file.name), icon: "ap-icon-delete", iconClassName: e.multipleFilesListItemIconDelete, disabled: s })
147
- ] })
148
- ] }) }, o)) })
99
+ c || n.key === "Enter" && ((o = f.current) == null || o.click());
100
+ }, [c]), W = _((n) => {
101
+ if (c) return;
102
+ const o = n.target.files, m = H(Array.from(o ?? []));
103
+ if (e === "multiple" && h) {
104
+ const d = [...u, ...m];
105
+ P(d), F == null || F(d);
106
+ } else
107
+ P(m), F == null || F(m);
108
+ n.target.value = "";
109
+ }, [c, e, h, u, H, F]), Z = _((n) => {
110
+ if (c || !u) return;
111
+ const o = u.filter((m) => m.file.name !== n);
112
+ T(o.length > l), P(o), g == null || g(n);
113
+ }, [c, u, l, g]), U = {
114
+ id: B,
115
+ type: e,
116
+ maxFiles: l,
117
+ fileExtensionsAllowed: s,
118
+ fileExtensionsAllowedText: b,
119
+ maxSize: r,
120
+ queueFiles: h,
121
+ disabled: c,
122
+ isUploadDisabled: E,
123
+ uploadedFiles: u,
124
+ isMaxFilesExceeded: J,
125
+ label: z,
126
+ required: R,
127
+ placeholder: j,
128
+ errorMessage: K,
129
+ helpText: V,
130
+ helpLink: q,
131
+ helpLinkText: $,
132
+ multipleHelpText: O,
133
+ multipleButtonHelpText: A,
134
+ labelTooltip: X,
135
+ accept: S,
136
+ inputRef: f,
137
+ triggerInput: G,
138
+ handleKeyDown: Q,
139
+ handleRemoveFile: Z,
140
+ displayFileSize: Y
141
+ }, ee = k != null && (Array.isArray(k) ? k.length > 0 : !0);
142
+ return /* @__PURE__ */ a(w.Provider, { value: U, children: [
143
+ /* @__PURE__ */ i("input", { accept: S, multiple: e === "multiple", ref: f, type: "file", id: B, className: t.input, onChange: W }),
144
+ /* @__PURE__ */ i("div", { className: C(t.container, c && t.disabled), children: ee ? k : /* @__PURE__ */ i(Oe, {}) })
145
+ ] });
146
+ }
147
+ function Oe() {
148
+ const e = p();
149
+ return /* @__PURE__ */ a(ne, { children: [
150
+ /* @__PURE__ */ i(I.Label, {}),
151
+ e.type === "single" && /* @__PURE__ */ i(I.SingleFileRow, { children: /* @__PURE__ */ i(I.BrowseButton, {}) }),
152
+ e.type === "single" && e.uploadedFiles.length > 0 && /* @__PURE__ */ i("span", { className: t.singleFileHelpLinkReservedSpace, children: /* @__PURE__ */ i(I.SingleFileDeleteButton, {}) }),
153
+ e.type === "multiple" && /* @__PURE__ */ i(I.BrowseButton, {}),
154
+ /* @__PURE__ */ i(I.HelpText, {}),
155
+ /* @__PURE__ */ i(I.UploadedFilesList, {})
156
+ ] });
157
+ }
158
+ function Ae({
159
+ children: e
160
+ }) {
161
+ const l = p(), s = e ?? l.label;
162
+ return /* @__PURE__ */ a("label", { htmlFor: l.id, onClick: (r) => r.preventDefault(), className: C(t.label, l.type === "multiple" && t.labelMultiple), children: [
163
+ /* @__PURE__ */ i("span", { title: l.label, className: t.labelText, children: s }),
164
+ l.required && /* @__PURE__ */ i("span", { "aria-hidden": "true", className: t.required, children: "*" }),
165
+ l.labelTooltip && /* @__PURE__ */ i(pe, { 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__ */ i(D, { icon: "ap-icon-info", className: t.labelTooltipIcon }) }),
166
+ l.type === "multiple" && l.multipleHelpText && /* @__PURE__ */ i("span", { className: t.multipleHelpText, children: l.multipleHelpText })
167
+ ] });
168
+ }
169
+ function Xe({
170
+ children: e,
171
+ className: l
172
+ }) {
173
+ const s = p();
174
+ return s.type === "multiple" ? /* @__PURE__ */ i(x, { type: "secondary", variant: "default", size: "md", icon: "ap-icon-upload", className: C(t.multipleInputButton, l), onClick: s.triggerInput, onKeyDown: s.handleKeyDown, disabled: s.disabled || s.isUploadDisabled, children: /* @__PURE__ */ i("span", { children: e ?? `Browse files ${s.multipleButtonHelpText ?? ""}` }) }) : /* @__PURE__ */ i(x, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-upload", className: C(t.inputButton, l), tabIndex: -1, disabled: s.disabled || s.isUploadDisabled, onClick: (r) => {
175
+ r.preventDefault(), r.stopPropagation(), s.triggerInput();
176
+ }, children: /* @__PURE__ */ i("span", { children: e ?? "Browse file" }) });
177
+ }
178
+ function Je({
179
+ children: e
180
+ }) {
181
+ return p().type !== "single" ? null : /* @__PURE__ */ i("div", { className: t.singleFileContainer, children: e });
182
+ }
183
+ function Ye({
184
+ children: e
185
+ }) {
186
+ const l = p();
187
+ return l.type !== "single" ? null : /* @__PURE__ */ a("div", { tabIndex: l.disabled ? -1 : 0, onClick: l.triggerInput, onKeyDown: l.handleKeyDown, className: t.singleFileInputContainer, children: [
188
+ /* @__PURE__ */ i("span", { className: t.inputFileName, children: l.uploadedFiles.length > 0 ? /* @__PURE__ */ i("span", { className: t.inputFileNameText, children: l.uploadedFiles[0].file.name }) : /* @__PURE__ */ i("span", { className: t.inputFileNamePlaceholder, children: l.placeholder }) }),
189
+ e
149
190
  ] });
150
191
  }
192
+ function Ge() {
193
+ return p().type !== "single" ? null : /* @__PURE__ */ i("span", { className: t.singleFileHelpLinkReservedSpace, children: /* @__PURE__ */ i(M, {}) });
194
+ }
195
+ function M() {
196
+ const e = p();
197
+ if (e.type !== "single" || e.uploadedFiles.length === 0) return null;
198
+ const l = e.uploadedFiles[0].file.name;
199
+ return /* @__PURE__ */ i(x, { type: "tertiary", variant: "default", size: "md", icon: "ap-icon-delete", className: t.singleFileDeleteButton, onClick: () => e.handleRemoveFile(l), disabled: e.disabled });
200
+ }
201
+ function Qe() {
202
+ var r, h;
203
+ const e = p(), l = e.errorMessage || e.isMaxFilesExceeded || e.type === "single" && ((r = e.uploadedFiles[0]) == null ? void 0 : r.error), s = e.type === "single" ? e.errorMessage || ((h = e.uploadedFiles[0]) == null ? void 0 : h.error) : e.errorMessage || (e.isMaxFilesExceeded ? `You can only upload up to ${e.maxFiles} files.` : "");
204
+ return /* @__PURE__ */ a("div", { className: t.helpers, children: [
205
+ l ? /* @__PURE__ */ i("span", { title: e.errorMessage, className: t.errorMessage, children: s }) : e.helpText && e.type === "single" && /* @__PURE__ */ i("span", { title: e.helpText, className: t.helperText, children: e.helpText }),
206
+ e.type === "single" && e.helpLink && e.helpLinkText && /* @__PURE__ */ a("span", { className: t.singleFileHelpLinkContainer, children: [
207
+ /* @__PURE__ */ i("a", { href: e.helpLink, className: t.helpLink, target: "_blank", rel: "noopener noreferrer", tabIndex: e.disabled ? -1 : 0, children: e.helpLinkText }),
208
+ /* @__PURE__ */ i("span", { className: t.singleFileHelpLinkReservedSpace })
209
+ ] })
210
+ ] });
211
+ }
212
+ function We() {
213
+ const e = p();
214
+ return e.type !== "multiple" || !e.uploadedFiles.length ? null : /* @__PURE__ */ i("ul", { className: t.multipleFilesList, children: e.uploadedFiles.map((l, s) => /* @__PURE__ */ i("li", { className: t.multipleFilesListItem, children: /* @__PURE__ */ a("div", { className: t.multipleFilesListItemContent, children: [
215
+ /* @__PURE__ */ i("span", { className: t.multipleFilesListItemIconContainer, children: /* @__PURE__ */ i(D, { icon: "ap-icon-document", className: t.multipleFilesListItemIcon }) }),
216
+ /* @__PURE__ */ a("div", { className: t.multipleFilesListItemContentData, children: [
217
+ /* @__PURE__ */ a("div", { className: t.multipleFilesListItemText, children: [
218
+ /* @__PURE__ */ i("span", { className: t.multipleFilesListItemName, children: l.file.name }),
219
+ /* @__PURE__ */ i("span", { className: t.multipleFilesListItemSize, children: e.displayFileSize(l.file.size) }),
220
+ l.error && /* @__PURE__ */ a("span", { className: t.multipleFilesListItemError, children: [
221
+ /* @__PURE__ */ i(D, { icon: "ap-icon-alert", className: t.multipleFilesListItemIconError }),
222
+ l.error
223
+ ] })
224
+ ] }),
225
+ /* @__PURE__ */ i(x, { type: "tertiary", variant: "default", size: "sm", onClick: () => e.handleRemoveFile(l.file.name), icon: "ap-icon-delete", iconClassName: t.multipleFilesListItemIconDelete, disabled: e.disabled })
226
+ ] })
227
+ ] }) }, s)) });
228
+ }
229
+ const I = Object.assign($e, {
230
+ Label: Ae,
231
+ BrowseButton: Xe,
232
+ HelpText: Qe,
233
+ UploadedFilesList: We,
234
+ SingleFileContainer: Je,
235
+ SingleFileRow: Ye,
236
+ SingleFileActions: Ge,
237
+ SingleFileDeleteButton: M
238
+ });
151
239
  export {
152
- Me as default
240
+ I as default,
241
+ p as useFilePickerContext
153
242
  };
@@ -1,8 +1,155 @@
1
- import { jsx as e } from "react/jsx-runtime";
2
- import l from "./FilePicker.js";
3
- import { d as i, i as r, r as t, g as o } from "../../vi.bdSIJ99Y-017e_Pkz.js";
4
- i("FilePicker", () => {
5
- r("should render", () => {
6
- t(/* @__PURE__ */ e(l, { type: "single", fileExtensionsAllowed: ["xlsx"], maxSize: 1, maxFiles: 10, label: "Label", required: !0, placeholder: "Select a file", helpText: "Help text", helpLink: "https://example.com", helpLinkText: "Help link" })), o(!0).toBe(!0);
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import { d as h, i as o, r as n, g as e, s as l, w as x, v as f, f as B } from "../../vi.bdSIJ99Y-017e_Pkz.js";
3
+ import { u as r } from "../../index-DkTDHhag.js";
4
+ import s from "./FilePicker.js";
5
+ const a = {
6
+ fileExtensionsAllowed: ["xlsx", "csv"],
7
+ maxSize: 5,
8
+ maxFiles: 10,
9
+ label: "Upload files",
10
+ required: !0,
11
+ placeholder: "Select a file",
12
+ helpText: "Help text",
13
+ helpLink: "https://example.com",
14
+ helpLinkText: "Help link"
15
+ };
16
+ function d(t, c = 100, u = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
17
+ return new File(["x".repeat(c)], t, {
18
+ type: u
19
+ });
20
+ }
21
+ h("FilePicker", () => {
22
+ h("Rendering", () => {
23
+ o("should render with required props", () => {
24
+ n(/* @__PURE__ */ i(s, { type: "single", ...a })), e(l.getByText("Upload files")).toBeInTheDocument(), e(l.getByText("Select a file")).toBeInTheDocument(), e(l.getByText("Browse file")).toBeInTheDocument();
25
+ }), o("should render required asterisk when required is true", () => {
26
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, required: !0 }));
27
+ const t = document.querySelector('[aria-hidden="true"]');
28
+ e(t).toBeInTheDocument(), e(t).toHaveTextContent("*");
29
+ }), o("should render single mode with Browse file button", () => {
30
+ n(/* @__PURE__ */ i(s, { type: "single", ...a })), e(l.getByText("Browse file")).toBeInTheDocument(), e(l.queryByText(/Browse files \(max/)).not.toBeInTheDocument();
31
+ }), o("should render multiple mode with Browse files button and max count", () => {
32
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, 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
+ }), o("should display custom multipleHelpText when provided in multiple mode", () => {
34
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, multipleHelpText: "Custom extensions and size info" })), e(l.getByText("Custom extensions and size info")).toBeInTheDocument();
35
+ }), o("should not render multipleHelpText in single mode", () => {
36
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, multipleHelpText: "This should not appear" })), e(l.queryByText("This should not appear")).not.toBeInTheDocument();
37
+ }), o("should display custom multipleButtonHelpText in button when provided in multiple mode", () => {
38
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, multipleButtonHelpText: "(max 3 files, 2MB each)" })), e(l.getByText("Browse files (max 3 files, 2MB each)")).toBeInTheDocument();
39
+ }), o("should render file input with correct accept and multiple attributes", () => {
40
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a }));
41
+ const t = l.getByTestId("file-picker-input");
42
+ e(t).toHaveAttribute("accept", ".xlsx,.csv"), e(t).toHaveAttribute("multiple");
43
+ }), o("should render single file input without multiple attribute", () => {
44
+ n(/* @__PURE__ */ i(s, { type: "single", ...a }));
45
+ const t = l.getByTestId("file-picker-input");
46
+ e(t).not.toHaveAttribute("multiple");
47
+ }), o("should display selected file name in single mode", async () => {
48
+ const t = d("report.xlsx");
49
+ n(/* @__PURE__ */ i(s, { type: "single", ...a }));
50
+ const c = l.getByTestId("file-picker-input");
51
+ await r.upload(c, t), await x(() => {
52
+ e(l.getByText("report.xlsx")).toBeInTheDocument();
53
+ });
54
+ }), o("should display error message when provided", () => {
55
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, errorMessage: "Please select a file" })), e(l.getByText("Please select a file")).toBeInTheDocument();
56
+ });
57
+ }), h("onUpload", () => {
58
+ o("should call onUpload with uploaded file when single file is selected", async () => {
59
+ const t = f.fn(), c = d("document.xlsx");
60
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, onUpload: t }));
61
+ const u = l.getByTestId("file-picker-input");
62
+ await r.upload(u, c), await x(() => {
63
+ e(t).toHaveBeenCalledTimes(1), e(t).toHaveBeenCalledWith([e.objectContaining({
64
+ file: e.any(File),
65
+ error: void 0
66
+ })]), e(t.mock.calls[0][0][0].file.name).toBe("document.xlsx");
67
+ });
68
+ }), o("should call onUpload with all selected files when multiple files selected (non-queue)", async () => {
69
+ const t = f.fn(), c = d("a.xlsx"), u = d("b.xlsx");
70
+ n(/* @__PURE__ */ i(s, { type: "multiple", queueFiles: !1, ...a, onUpload: t }));
71
+ const m = l.getByTestId("file-picker-input");
72
+ await r.upload(m, [c, u]), await x(() => {
73
+ e(t).toHaveBeenCalledTimes(1);
74
+ const p = t.mock.calls[0][0];
75
+ e(p).toHaveLength(2), e(p[0].file.name).toBe("a.xlsx"), e(p[1].file.name).toBe("b.xlsx");
76
+ });
77
+ }), o("should call onUpload with accumulated files when queueFiles is true", async () => {
78
+ const t = f.fn(), c = d("first.xlsx"), u = d("second.xlsx");
79
+ n(/* @__PURE__ */ i(s, { type: "multiple", queueFiles: !0, ...a, maxFiles: 10, onUpload: t }));
80
+ const m = l.getByTestId("file-picker-input");
81
+ await r.upload(m, c), await x(() => {
82
+ e(t).toHaveBeenCalledTimes(1);
83
+ const p = t.mock.calls[0][0];
84
+ e(p).toHaveLength(1), e(p[0].file.name).toBe("first.xlsx");
85
+ }), await r.upload(m, u), await x(() => {
86
+ e(t).toHaveBeenCalledTimes(2);
87
+ const p = t.mock.calls[1][0];
88
+ e(p).toHaveLength(2), e(p[0].file.name).toBe("first.xlsx"), e(p[1].file.name).toBe("second.xlsx");
89
+ });
90
+ }), o("should include validation error in onUpload when file extension is invalid", async () => {
91
+ const t = f.fn(), c = d("document.pdf", 100, "application/pdf");
92
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, fileExtensionsAllowed: ["xlsx"], onUpload: t }));
93
+ const u = l.getByTestId("file-picker-input");
94
+ B.change(u, {
95
+ target: {
96
+ files: [c]
97
+ }
98
+ }), await x(() => {
99
+ e(t).toHaveBeenCalledWith([e.objectContaining({
100
+ file: e.any(File),
101
+ error: e.stringContaining("file format is incorrect")
102
+ })]);
103
+ });
104
+ });
105
+ }), h("onRemoveFile", () => {
106
+ o("should call onRemoveFile when remove button is clicked in single mode", async () => {
107
+ const t = f.fn(), c = d("to-remove.xlsx");
108
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, onRemoveFile: t }));
109
+ const u = l.getByTestId("file-picker-input");
110
+ await r.upload(u, c), await x(() => {
111
+ e(l.getByText("to-remove.xlsx")).toBeInTheDocument();
112
+ });
113
+ const m = l.getByTestId("file-picker-remove-single");
114
+ await r.click(m), e(t).toHaveBeenCalledWith("to-remove.xlsx");
115
+ }), o("should call onRemoveFile when remove button is clicked in multiple mode", async () => {
116
+ const t = f.fn(), c = d("one.xlsx"), u = d("two.xlsx");
117
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, onRemoveFile: t }));
118
+ const m = l.getByTestId("file-picker-input");
119
+ await r.upload(m, [c, u]), await x(() => {
120
+ e(l.getByText("one.xlsx")).toBeInTheDocument(), e(l.getByText("two.xlsx")).toBeInTheDocument();
121
+ });
122
+ const p = l.getByTestId("file-picker-remove-two.xlsx");
123
+ await r.click(p), e(t).toHaveBeenCalledWith("two.xlsx");
124
+ });
125
+ }), h("Disabled state", () => {
126
+ o("should not call onUpload when disabled and file is selected", async () => {
127
+ const t = f.fn(), c = d("doc.xlsx");
128
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, disabled: !0, onUpload: t }));
129
+ const u = l.getByTestId("file-picker-input");
130
+ await r.upload(u, c), e(t).not.toHaveBeenCalled();
131
+ }), o("should not call onRemoveFile when disabled and remove is clicked", async () => {
132
+ const t = f.fn(), c = d("doc.xlsx");
133
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, disabled: !0, value: [c], onRemoveFile: t })), e(l.getByText("doc.xlsx")).toBeInTheDocument();
134
+ const u = l.getByTestId("file-picker-remove-single");
135
+ e(u).toBeDisabled(), await r.click(u), e(t).not.toHaveBeenCalled();
136
+ });
137
+ }), h("Controlled value", () => {
138
+ o("should display files from value prop", () => {
139
+ const t = d("controlled.xlsx");
140
+ n(/* @__PURE__ */ i(s, { type: "single", ...a, value: [t] })), e(l.getByText("controlled.xlsx")).toBeInTheDocument();
141
+ }), o("should display multiple files from value prop", () => {
142
+ const t = [d("a.xlsx"), d("b.xlsx")];
143
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, value: t })), e(l.getByText("a.xlsx")).toBeInTheDocument(), e(l.getByText("b.xlsx")).toBeInTheDocument();
144
+ });
145
+ }), h("Max files exceeded", () => {
146
+ o("should show max files exceeded message when over limit in multiple mode", async () => {
147
+ const t = [d("1.xlsx"), d("2.xlsx"), d("3.xlsx")];
148
+ n(/* @__PURE__ */ i(s, { type: "multiple", ...a, maxFiles: 2 }));
149
+ const c = l.getByTestId("file-picker-input");
150
+ await r.upload(c, t), await x(() => {
151
+ e(l.getByText(/You can only upload up to 2 files/)).toBeInTheDocument();
152
+ });
153
+ });
7
154
  });
8
155
  });
package/dist/main.d.ts CHANGED
@@ -9,7 +9,7 @@ export { default as Toggle } from './components/Toggle/Toggle.tsx';
9
9
  export { default as Banner } from './components/Banner/Banner.tsx';
10
10
  export { default as Ghost } from './components/Ghost/Ghost.tsx';
11
11
  export { default as Dropdown, type DropdownOption } from './components/Dropdown/Dropdown.tsx';
12
- export { default as FilePicker } from './components/FilePicker/FilePicker.tsx';
12
+ export { default as FilePicker, useFilePickerContext, type FilePickerContextValue, } from './components/FilePicker/FilePicker.tsx';
13
13
  export { default as Search } from './components/Search/Search.tsx';
14
14
  export { default as Toast } from './components/Toast/Toast.tsx';
15
15
  export { default as ToastProvider } from './components/ToastProvider/ToastProvider.tsx';
@@ -18,7 +18,7 @@ export type { ToastProviderProps, ToastOptions, ToastVariant, UseToastReturn, An
18
18
  export { default as Creatable } from './components/Creatable/Creatable.tsx';
19
19
  export { default as SplitButton, type ActionDropdownOption, } from './components/SplitButton/SplitButton.tsx';
20
20
  export { default as DragAndDrop, type UploadFile, type ValidationResult, type ValidationContext, type ValidationErrorCode, type Validator, type DragAndDropTexts, } from './components/DragAndDrop/DragAndDrop.tsx';
21
- export { defaultValidator, composeValidators, } from './components/DragAndDrop/DragAndDrop.utils';
21
+ export { defaultValidator, composeValidators } from './components/DragAndDrop/DragAndDrop.utils';
22
22
  export { default as Tab } from './components/Tab/Tab.tsx';
23
23
  export { default as TabNavigation } from './components/TabNavigation/TabNavigation.tsx';
24
24
  export { default as Dialog } from './components/Dialog/Dialog.tsx';