@douglasneuroinformatics/libui 3.4.2 → 3.5.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/dist/components.d.ts +17 -7
- package/dist/components.js +418 -385
- package/dist/components.js.map +1 -1
- package/dist/douglasneuroinformatics-libui-3.5.0.tgz +0 -0
- package/package.json +2 -1
- package/src/components/FileDropzone/FileDropzone.spec.tsx +69 -0
- package/src/components/FileDropzone/FileDropzone.stories.tsx +33 -0
- package/src/components/FileDropzone/FileDropzone.tsx +52 -0
- package/src/components/FileDropzone/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/dist/douglasneuroinformatics-libui-3.4.2.tgz +0 -0
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douglasneuroinformatics/libui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.5.0",
|
|
5
5
|
"packageManager": "pnpm@9.11.0",
|
|
6
6
|
"description": "Generic UI components for DNP projects, built using React and Tailwind CSS",
|
|
7
7
|
"author": "Joshua Unrau",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"framer-motion": "^11.5.2",
|
|
103
103
|
"lodash-es": "^4.17.21",
|
|
104
104
|
"lucide-react": "^0.438.0",
|
|
105
|
+
"react-dropzone": "^14.2.3",
|
|
105
106
|
"react-error-boundary": "^4.0.13",
|
|
106
107
|
"react-resizable-panels": "^2.1.2",
|
|
107
108
|
"recharts": "^2.12.7",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { FileDropzone } from './FileDropzone';
|
|
5
|
+
|
|
6
|
+
describe('FileDropzone', () => {
|
|
7
|
+
const testfile = new File([new Blob()], 'testfile.csv');
|
|
8
|
+
it('should render', () => {
|
|
9
|
+
render(
|
|
10
|
+
<FileDropzone
|
|
11
|
+
acceptedFileTypes={{
|
|
12
|
+
'text/csv': ['.csv'],
|
|
13
|
+
'text/plain': ['.csv', '.tsv']
|
|
14
|
+
}}
|
|
15
|
+
file={null}
|
|
16
|
+
setFile={function (file: File): void {
|
|
17
|
+
throw new Error('Function not implemented. File name is ' + file.name);
|
|
18
|
+
}}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
expect(screen.getByTestId('dropzoneText')).contains(String, "Drag'n'drop files or click on box to upload");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should have file', () => {
|
|
25
|
+
render(
|
|
26
|
+
<FileDropzone
|
|
27
|
+
acceptedFileTypes={{
|
|
28
|
+
'text/csv': ['.csv'],
|
|
29
|
+
'text/plain': ['.csv', '.tsv']
|
|
30
|
+
}}
|
|
31
|
+
file={testfile}
|
|
32
|
+
setFile={function (file: File): void {
|
|
33
|
+
throw new Error('Function not implemented. File name is ' + file.name);
|
|
34
|
+
}}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
expect(screen.getByText('testfile.csv')).toBeInTheDocument();
|
|
38
|
+
});
|
|
39
|
+
it('drag active should work', () => {
|
|
40
|
+
render(
|
|
41
|
+
<FileDropzone
|
|
42
|
+
acceptedFileTypes={{
|
|
43
|
+
'text/csv': ['.csv'],
|
|
44
|
+
'text/plain': ['.csv', '.tsv']
|
|
45
|
+
}}
|
|
46
|
+
file={null}
|
|
47
|
+
setFile={function (file: File): void {
|
|
48
|
+
throw new Error('Function not implemented. File name is ' + file.name);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const fileDropzoneElement = screen.getByTestId('dropzone');
|
|
54
|
+
|
|
55
|
+
fireEvent.dragOver(fileDropzoneElement, {
|
|
56
|
+
dataTransfer: {
|
|
57
|
+
files: [testfile]
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
fireEvent.drop(fileDropzoneElement, {
|
|
62
|
+
dataTransfer: {
|
|
63
|
+
files: [testfile]
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(screen.getByTestId('dropzoneText')).contain(String, 'testfile.csv');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
import { FileDropzone } from './FileDropzone.js';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof FileDropzone> = {
|
|
8
|
+
component: FileDropzone
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof FileDropzone>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {
|
|
16
|
+
decorators: [
|
|
17
|
+
(Story) => {
|
|
18
|
+
const [file, setFile] = useState<File | undefined>();
|
|
19
|
+
return (
|
|
20
|
+
<Story
|
|
21
|
+
args={{
|
|
22
|
+
acceptedFileTypes: {
|
|
23
|
+
'text/csv': ['.csv'],
|
|
24
|
+
'text/plain': ['.csv', '.tsv']
|
|
25
|
+
},
|
|
26
|
+
file,
|
|
27
|
+
setFile
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { type FileRejection, useDropzone } from 'react-dropzone';
|
|
4
|
+
|
|
5
|
+
import { useTranslation } from '@/hooks/useTranslation';
|
|
6
|
+
|
|
7
|
+
export type FileDropzoneProps = {
|
|
8
|
+
acceptedFileTypes: {
|
|
9
|
+
[key: string]: string[];
|
|
10
|
+
};
|
|
11
|
+
file: File | null;
|
|
12
|
+
setFile: (file: File) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const FileDropzone = ({ acceptedFileTypes, file, setFile }: FileDropzoneProps) => {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
|
|
18
|
+
const handleDrop = useCallback(
|
|
19
|
+
(acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
|
|
20
|
+
for (const { errors, file } of rejectedFiles) {
|
|
21
|
+
console.error(errors, file);
|
|
22
|
+
}
|
|
23
|
+
setFile(acceptedFiles[0]!);
|
|
24
|
+
},
|
|
25
|
+
[setFile]
|
|
26
|
+
);
|
|
27
|
+
const { getInputProps, getRootProps, isDragActive } = useDropzone({
|
|
28
|
+
accept: acceptedFileTypes,
|
|
29
|
+
maxFiles: 1,
|
|
30
|
+
onDrop: handleDrop
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div data-testid="dropzone" {...getRootProps()}>
|
|
35
|
+
<p className="mt-1 border border-dashed p-4 text-center text-sm" data-testid="dropzoneText">
|
|
36
|
+
{file
|
|
37
|
+
? file.name
|
|
38
|
+
: isDragActive
|
|
39
|
+
? t({
|
|
40
|
+
en: 'File to upload',
|
|
41
|
+
fr: 'fichier à télécharger'
|
|
42
|
+
})
|
|
43
|
+
: t({
|
|
44
|
+
en: "Drag'n'drop files or click on box to upload",
|
|
45
|
+
fr: 'Glissez-déposez les fichiers ou cliquez sur la case pour les télécharger'
|
|
46
|
+
})}
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
<input {...getInputProps()} />
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './FileDropzone';
|
package/src/components/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export * from './DropdownButton';
|
|
|
20
20
|
export * from './DropdownMenu';
|
|
21
21
|
export * from './ErrorBoundary';
|
|
22
22
|
export * from './ErrorFallback';
|
|
23
|
+
export * from './FileDropzone';
|
|
23
24
|
export * from './Form';
|
|
24
25
|
export * from './Heading';
|
|
25
26
|
export * from './HoverCard';
|
|
Binary file
|