@alixpartners/ui-components 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -99
- package/dist/DragAndDrop.utils-D3xTV9EK.js +30 -0
- package/dist/components/DragAndDrop/DragAndDrop.d.ts +56 -1
- package/dist/components/DragAndDrop/DragAndDrop.js +144 -83
- package/dist/components/DragAndDrop/DragAndDrop.test.d.ts +1 -0
- package/dist/components/DragAndDrop/DragAndDrop.test.js +606 -0
- package/dist/components/DragAndDrop/DragAndDrop.utils.d.ts +30 -0
- package/dist/main.d.ts +2 -1
- package/dist/main.js +37 -34
- package/dist/web.config +8 -8
- package/package.json +86 -86
package/README.md
CHANGED
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
# AlixPartners UI Component Library
|
|
2
|
-
|
|
3
|
-
A modern, reusable component library built with **[ReactJS](https://react.dev/)**.
|
|
4
|
-
|
|
5
|
-
Version **2.0** has been **rebuilt from the ground up** to align with the latest **AlixPartners Design System** and deliver improved developer experience, accessibility, and performance.
|
|
6
|
-
|
|
7
|
-
‼️ **BETA Notice**: This release is **not yet production-ready**. While stable for development and testing, expect ongoing refinements, new components, and breaking changes before the full release.
|
|
8
|
-
|
|
9
|
-
## ✨ What’s New in 2.0
|
|
10
|
-
|
|
11
|
-
- Completely redesigned architecture with modern build tooling ([Vite](https://vitejs.dev/))
|
|
12
|
-
- Updated design tokens and styles aligned with AlixPartners Design System
|
|
13
|
-
- Improved accessibility (a11y) and semantic HTML usage
|
|
14
|
-
- Streamlined props API for cleaner integration
|
|
15
|
-
- Enhanced Storybook documentation
|
|
16
|
-
- Faster build & development workflows
|
|
17
|
-
|
|
18
|
-
### Version Support
|
|
19
|
-
|
|
20
|
-
- v2.x — Active development (BETA)
|
|
21
|
-
- v1.x — Maintained for legacy projects (no new features, critical fixes only)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 🚀 Installation
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
npm install @alixpartners/ui-components
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 🔧 Usage
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
import { YourComponent } from '@alixpartners/ui-components'
|
|
35
|
-
|
|
36
|
-
function App() {
|
|
37
|
-
return <YourComponent />
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## 🧱 Components
|
|
42
|
-
|
|
43
|
-
Explore all available components and documentation in Storybook.
|
|
44
|
-
|
|
45
|
-
To run it locally:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm run storybook
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 📦 Build
|
|
54
|
-
|
|
55
|
-
To bundle the library for publishing:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
npm run build
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
The output will be in the `dist/` directory.
|
|
62
|
-
|
|
63
|
-
### Usage in projects while developing
|
|
64
|
-
|
|
65
|
-
When working on the library and testing it in another project:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
# In the component library root:
|
|
69
|
-
npm link
|
|
70
|
-
|
|
71
|
-
# In the consuming project's root:
|
|
72
|
-
npm link alix-partners-react-components-test
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Then import components using the `alix-partners-react-components-test` import.
|
|
76
|
-
|
|
77
|
-
## 🧪 Testing
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
npm run test
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
#### 🧪 Test Coverage
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
npm run coverage
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## 📚 Publish
|
|
90
|
-
|
|
91
|
-
To publish to npm:
|
|
92
|
-
|
|
93
|
-
1. Bump the version in `package.json`
|
|
94
|
-
2. Create a pull request in Azure DevOps to the `main` branch
|
|
95
|
-
3. This will automatically publish the library to `npm` once approved
|
|
96
|
-
|
|
97
|
-
## 🤝 Contributing
|
|
98
|
-
|
|
99
|
-
The **AlixPartners UI Component Library** is a collaborative, community-driven project where contributions from all team members are encouraged and valued. If you’d like to add new components or improve existing ones, please see the CONTRIBUTING.md file.
|
|
1
|
+
# AlixPartners UI Component Library
|
|
2
|
+
|
|
3
|
+
A modern, reusable component library built with **[ReactJS](https://react.dev/)**.
|
|
4
|
+
|
|
5
|
+
Version **2.0** has been **rebuilt from the ground up** to align with the latest **AlixPartners Design System** and deliver improved developer experience, accessibility, and performance.
|
|
6
|
+
|
|
7
|
+
‼️ **BETA Notice**: This release is **not yet production-ready**. While stable for development and testing, expect ongoing refinements, new components, and breaking changes before the full release.
|
|
8
|
+
|
|
9
|
+
## ✨ What’s New in 2.0
|
|
10
|
+
|
|
11
|
+
- Completely redesigned architecture with modern build tooling ([Vite](https://vitejs.dev/))
|
|
12
|
+
- Updated design tokens and styles aligned with AlixPartners Design System
|
|
13
|
+
- Improved accessibility (a11y) and semantic HTML usage
|
|
14
|
+
- Streamlined props API for cleaner integration
|
|
15
|
+
- Enhanced Storybook documentation
|
|
16
|
+
- Faster build & development workflows
|
|
17
|
+
|
|
18
|
+
### Version Support
|
|
19
|
+
|
|
20
|
+
- v2.x — Active development (BETA)
|
|
21
|
+
- v1.x — Maintained for legacy projects (no new features, critical fixes only)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🚀 Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @alixpartners/ui-components
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 🔧 Usage
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { YourComponent } from '@alixpartners/ui-components'
|
|
35
|
+
|
|
36
|
+
function App() {
|
|
37
|
+
return <YourComponent />
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 🧱 Components
|
|
42
|
+
|
|
43
|
+
Explore all available components and documentation in Storybook.
|
|
44
|
+
|
|
45
|
+
To run it locally:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run storybook
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 📦 Build
|
|
54
|
+
|
|
55
|
+
To bundle the library for publishing:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run build
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The output will be in the `dist/` directory.
|
|
62
|
+
|
|
63
|
+
### Usage in projects while developing
|
|
64
|
+
|
|
65
|
+
When working on the library and testing it in another project:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# In the component library root:
|
|
69
|
+
npm link
|
|
70
|
+
|
|
71
|
+
# In the consuming project's root:
|
|
72
|
+
npm link alix-partners-react-components-test
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then import components using the `alix-partners-react-components-test` import.
|
|
76
|
+
|
|
77
|
+
## 🧪 Testing
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm run test
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### 🧪 Test Coverage
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm run coverage
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 📚 Publish
|
|
90
|
+
|
|
91
|
+
To publish to npm:
|
|
92
|
+
|
|
93
|
+
1. Bump the version in `package.json`
|
|
94
|
+
2. Create a pull request in Azure DevOps to the `main` branch
|
|
95
|
+
3. This will automatically publish the library to `npm` once approved
|
|
96
|
+
|
|
97
|
+
## 🤝 Contributing
|
|
98
|
+
|
|
99
|
+
The **AlixPartners UI Component Library** is a collaborative, community-driven project where contributions from all team members are encouraged and valued. If you’d like to add new components or improve existing ones, please see the CONTRIBUTING.md file.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function u(r, e) {
|
|
2
|
+
const t = e.maxSize ? e.maxSize * 1024 * 1024 : Number.POSITIVE_INFINITY, o = new Set(e.fileExtensionsAllowed.map((l) => l.toLowerCase().replace(/^\./, ""))), s = r.size <= t, n = r.name.toLowerCase(), a = n.includes(".") ? n.split(".").pop() ?? "" : "", i = o.size === 0 || o.has(a);
|
|
3
|
+
return s ? i ? {
|
|
4
|
+
file: r
|
|
5
|
+
} : {
|
|
6
|
+
file: r,
|
|
7
|
+
error: `The file format is incorrect. Please make sure it is one of the extensions: ${e.fileExtensionsAllowed.join(", ")}.`,
|
|
8
|
+
errorCode: "INVALID_EXTENSION"
|
|
9
|
+
} : {
|
|
10
|
+
file: r,
|
|
11
|
+
error: `File size is too large. Must be up to ${e.maxSize}MB.`,
|
|
12
|
+
errorCode: "SIZE_TOO_LARGE"
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function c(...r) {
|
|
16
|
+
return (e, t) => {
|
|
17
|
+
for (const o of r) {
|
|
18
|
+
const s = o(e, t);
|
|
19
|
+
if (s.error)
|
|
20
|
+
return s;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
file: e
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
c,
|
|
29
|
+
u as d
|
|
30
|
+
};
|
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
import { DataAttributes } from '../../types/data-attributes';
|
|
2
2
|
import { DraggableEventHandlers } from '../../types/native-events';
|
|
3
|
+
import { ButtonProps } from '../Button/Button';
|
|
4
|
+
import { ApIcon } from '../../assets/ap-icons-types';
|
|
3
5
|
export type UploadFile = {
|
|
4
6
|
file: File;
|
|
5
7
|
error?: string;
|
|
6
8
|
};
|
|
9
|
+
export type ValidationErrorCode = 'SIZE_TOO_LARGE' | 'INVALID_EXTENSION' | 'MAX_FILES' | 'SINGLE_FILE_ONLY';
|
|
10
|
+
export type ValidationResult = {
|
|
11
|
+
file: File;
|
|
12
|
+
error?: string;
|
|
13
|
+
errorCode?: ValidationErrorCode;
|
|
14
|
+
};
|
|
15
|
+
export type ValidationContext = {
|
|
16
|
+
maxSize: number;
|
|
17
|
+
fileExtensionsAllowed: string[];
|
|
18
|
+
type: 'single' | 'multiple';
|
|
19
|
+
maxFiles: number;
|
|
20
|
+
};
|
|
21
|
+
export type Validator = (file: File, context: ValidationContext) => ValidationResult;
|
|
22
|
+
export type DragAndDropTexts = {
|
|
23
|
+
browse?: string | ((type: 'single' | 'multiple') => string);
|
|
24
|
+
drag?: string | ((type: 'single' | 'multiple') => string);
|
|
25
|
+
constraints?: (params: {
|
|
26
|
+
extensions: string[];
|
|
27
|
+
maxSize: number;
|
|
28
|
+
type: 'single' | 'multiple';
|
|
29
|
+
}) => string;
|
|
30
|
+
errors?: {
|
|
31
|
+
sizeTooLarge?: string | ((maxSize: number) => string);
|
|
32
|
+
invalidExtension?: string | ((extensions: string[]) => string);
|
|
33
|
+
};
|
|
34
|
+
};
|
|
7
35
|
type DragAndDropProps = {
|
|
8
36
|
className?: string;
|
|
9
37
|
type?: 'single' | 'multiple';
|
|
@@ -15,8 +43,35 @@ type DragAndDropProps = {
|
|
|
15
43
|
maxFiles?: number;
|
|
16
44
|
value?: File | File[];
|
|
17
45
|
onUpload?: (files: UploadFile[]) => void;
|
|
46
|
+
/**
|
|
47
|
+
* Callback fired when a file is removed.
|
|
48
|
+
* @param fileName - Name of the file to remove
|
|
49
|
+
*/
|
|
18
50
|
onRemoveFile?: (fileName: string) => void;
|
|
19
51
|
queueFiles?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Customizable text content for the component.
|
|
54
|
+
* @note Should be memoized (e.g., using `useMemo`) to prevent unnecessary re-renders.
|
|
55
|
+
* If an inline object is passed, all memoized callbacks will recreate on every render.
|
|
56
|
+
*/
|
|
57
|
+
texts?: DragAndDropTexts;
|
|
58
|
+
fileIcon?: ApIcon;
|
|
59
|
+
errorIcon?: ApIcon;
|
|
60
|
+
deleteIcon?: ApIcon;
|
|
61
|
+
browseButtonIcon?: ApIcon;
|
|
62
|
+
renderFileItem?: (file: UploadFile, index: number, onRemove: () => void) => React.ReactNode;
|
|
63
|
+
fileSizeFormatter?: (size: number) => string;
|
|
64
|
+
browseButtonProps?: Omit<Partial<ButtonProps>, 'onClick' | 'disabled'>;
|
|
65
|
+
validator?: Validator;
|
|
66
|
+
/**
|
|
67
|
+
* External errors to attach to files by filename.
|
|
68
|
+
* Useful for async/API validation results.
|
|
69
|
+
*
|
|
70
|
+
* NOTE: Error identity is filename-based. Duplicate filenames will collide.
|
|
71
|
+
* NOTE: The component does not clear external errors automatically;
|
|
72
|
+
* the parent owns that state.
|
|
73
|
+
*/
|
|
74
|
+
errors?: Record<string, string>;
|
|
20
75
|
} & DataAttributes & DraggableEventHandlers;
|
|
21
76
|
/**
|
|
22
77
|
* DragAndDrop provides a file upload surface that supports browsing files
|
|
@@ -35,5 +90,5 @@ type DragAndDropProps = {
|
|
|
35
90
|
* @param {boolean} [props.queueFiles] - When true, newly selected files are appended to the existing list
|
|
36
91
|
* @returns {JSX.Element} The rendered DragAndDrop component
|
|
37
92
|
*/
|
|
38
|
-
export default function DragAndDrop({ label, type, disabled, required, fileExtensionsAllowed, maxSize, maxFiles, value, onUpload, onRemoveFile, queueFiles, className, ...props }: DragAndDropProps): import("react/jsx-runtime").JSX.Element;
|
|
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;
|
|
39
94
|
export {};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useId as
|
|
3
|
-
import
|
|
4
|
-
import { c as
|
|
5
|
-
import
|
|
6
|
-
import '../../assets/DragAndDrop.css';const
|
|
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 = {
|
|
7
7
|
"drag-and-drop-container": "DragAndDrop-module__drag-and-drop-container___WHqGh",
|
|
8
|
-
disabled:
|
|
9
|
-
required:
|
|
8
|
+
disabled: Ar,
|
|
9
|
+
required: vr,
|
|
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:
|
|
13
|
+
active: Ir,
|
|
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",
|
|
@@ -25,98 +25,159 @@ import '../../assets/DragAndDrop.css';const X = "DragAndDrop-module__disabled___
|
|
|
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
27
|
};
|
|
28
|
-
function
|
|
28
|
+
function Or({
|
|
29
29
|
label: k,
|
|
30
|
-
type:
|
|
31
|
-
disabled:
|
|
32
|
-
required:
|
|
33
|
-
fileExtensionsAllowed:
|
|
34
|
-
maxSize:
|
|
35
|
-
maxFiles:
|
|
30
|
+
type: i = "single",
|
|
31
|
+
disabled: w,
|
|
32
|
+
required: F,
|
|
33
|
+
fileExtensionsAllowed: c,
|
|
34
|
+
maxSize: p,
|
|
35
|
+
maxFiles: l = Number.POSITIVE_INFINITY,
|
|
36
36
|
value: f,
|
|
37
|
-
onUpload:
|
|
38
|
-
onRemoveFile:
|
|
39
|
-
queueFiles:
|
|
40
|
-
className:
|
|
41
|
-
|
|
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
|
|
42
52
|
}) {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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) => {
|
|
54
|
+
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;
|
|
60
|
+
}
|
|
61
|
+
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({
|
|
63
|
+
extensions: c,
|
|
64
|
+
maxSize: p,
|
|
65
|
+
type: i
|
|
66
|
+
}) : `${Y} ${i === "single" ? "file" : "files"} ${Z}`, [e, c, Y, p, Z, i]), lr = () => {
|
|
67
|
+
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 ? {
|
|
72
|
+
file: r
|
|
73
|
+
} : {
|
|
74
|
+
file: r,
|
|
75
|
+
error: `The file format is incorrect. Please make sure it is one of the extensions: ${a.fileExtensionsAllowed.join(", ")}.`,
|
|
76
|
+
errorCode: "INVALID_EXTENSION"
|
|
77
|
+
} : {
|
|
78
|
+
file: r,
|
|
79
|
+
error: `File size is too large. Must be up to ${a.maxSize}MB.`,
|
|
80
|
+
errorCode: "SIZE_TOO_LARGE"
|
|
81
|
+
};
|
|
82
|
+
}, [B]), O = A(() => ({
|
|
83
|
+
maxSize: p,
|
|
84
|
+
fileExtensionsAllowed: c,
|
|
85
|
+
type: i,
|
|
86
|
+
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;
|
|
92
|
+
return {
|
|
93
|
+
file: o.file,
|
|
94
|
+
// Don't merge external errors here - that happens in files useMemo
|
|
95
|
+
error: h
|
|
53
96
|
};
|
|
54
97
|
});
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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 : {
|
|
99
|
+
...o,
|
|
100
|
+
error: o.error ?? `Maximum ${l} file${l === 1 ? "" : "s"} allowed.`
|
|
101
|
+
})), s);
|
|
102
|
+
}, [i, l, b, O, G, H]), d = A(() => {
|
|
103
|
+
let r;
|
|
104
|
+
if (D) {
|
|
105
|
+
const a = Array.isArray(f) ? f : f ? [f] : [];
|
|
106
|
+
r = T(a);
|
|
107
|
+
} else
|
|
108
|
+
r = u;
|
|
109
|
+
return r.map((a) => ({
|
|
110
|
+
...a,
|
|
111
|
+
// Validator errors take precedence over external errors
|
|
112
|
+
error: a.error ?? (I == null ? void 0 : I[a.file.name])
|
|
113
|
+
}));
|
|
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);
|
|
118
|
+
else {
|
|
119
|
+
const s = q ? [...u, ...a] : a;
|
|
120
|
+
S(s), _ == null || _(s);
|
|
121
|
+
}
|
|
122
|
+
}, [T, D, q, u, _]), gr = (r) => {
|
|
123
|
+
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);
|
|
67
130
|
}
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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]), {
|
|
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) => {
|
|
142
|
+
if (N) return;
|
|
143
|
+
r.preventDefault();
|
|
144
|
+
const a = Array.from(r.dataTransfer.files);
|
|
145
|
+
W(a), r.dataTransfer.clearData(), L(!1), $ == null || $(r);
|
|
81
146
|
};
|
|
82
|
-
return /* @__PURE__ */
|
|
83
|
-
k && /* @__PURE__ */
|
|
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: [
|
|
84
149
|
k,
|
|
85
|
-
|
|
150
|
+
F && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: n.required, children: "*" })
|
|
86
151
|
] }),
|
|
87
|
-
/* @__PURE__ */
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
/* @__PURE__ */
|
|
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: {
|
|
90
155
|
display: "none"
|
|
91
|
-
}, multiple:
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
-
" ",
|
|
96
|
-
C,
|
|
97
|
-
" ",
|
|
98
|
-
c === "single" ? "file" : "files",
|
|
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: [
|
|
99
160
|
" ",
|
|
100
|
-
|
|
161
|
+
tr()
|
|
101
162
|
] })
|
|
102
163
|
] })
|
|
103
164
|
] }),
|
|
104
|
-
(d == null ? void 0 : d.length) > 0 && /* @__PURE__ */
|
|
105
|
-
/* @__PURE__ */
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
-
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
-
|
|
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"] }),
|
|
173
|
+
r.error
|
|
113
174
|
] })
|
|
114
175
|
] }),
|
|
115
|
-
/* @__PURE__ */
|
|
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}` })
|
|
116
177
|
] })
|
|
117
|
-
] }) },
|
|
178
|
+
] }) }, r.file.name)) })
|
|
118
179
|
] });
|
|
119
180
|
}
|
|
120
181
|
export {
|
|
121
|
-
|
|
182
|
+
Or as default
|
|
122
183
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|