@deviceinsight/ng-ui-components 6.24.0 → 6.25.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.
@@ -74,7 +74,7 @@
74
74
  .di.upload,
75
75
  .di.upload * {transition:all .1s ease;}
76
76
  .di.upload {margin:0; padding:0; width:100%; height:100%; min-height:80px; font-size:16px; border:1px dashed #888; border-radius:4px; overflow:hidden; user-select:none;}
77
- .di.upload {display:flex; align-items:center;}
77
+ .di.upload {display:flex; flex-direction:column; align-items:center;}
78
78
  .di.upload:hover {border-color:#666; background:#f9f9f9;}
79
79
  .di.upload:active {background:#eee;}
80
80
  .di.upload > div {width:100%; height:100%;}
@@ -17,14 +17,14 @@ const testing_library_1 = require("@storybook/testing-library");
17
17
  (0, vitest_1.expect)(timeElement).toHaveDisplayValue('03:24');
18
18
  });
19
19
  (0, vitest_1.it)('should display the time and date as timezone date', async () => {
20
- const { rerender } = (0, react_2.render)(react_1.default.createElement(DateTimeInput_1.default, { timestamp: new Date('2019-02-01T11:11:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
20
+ const { rerender } = (0, react_2.render)(react_1.default.createElement(DateTimeInput_1.default, { timestamp: new Date('2019-02-01T11:11:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
21
21
  const timeElementUtm = react_2.screen.queryByDisplayValue('11:11');
22
22
  (0, vitest_1.expect)(timeElementUtm).not.toBeInTheDocument();
23
23
  const timeElement = react_2.screen.queryByDisplayValue('03:11');
24
24
  (0, vitest_1.expect)(timeElement).toBeInTheDocument();
25
25
  const dateElement = react_2.screen.queryByDisplayValue('01.02.2019');
26
26
  (0, vitest_1.expect)(dateElement).toBeInTheDocument();
27
- rerender(react_1.default.createElement(DateTimeInput_1.default, { timestamp: new Date('2019-02-02T03:24:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
27
+ rerender(react_1.default.createElement(DateTimeInput_1.default, { timestamp: new Date('2019-02-02T03:24:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
28
28
  (0, vitest_1.expect)(timeElement).toHaveDisplayValue('19:24');
29
29
  (0, vitest_1.expect)(dateElement).toHaveDisplayValue('01.02.2019');
30
30
  await (0, react_2.act)(async () => {
@@ -10,12 +10,8 @@ export declare type PreviewComponentProps = {
10
10
  export declare type Props = {
11
11
  /** (Optional) string for accepting files */
12
12
  accept?: string;
13
- /** Function, executed when a file gets removed */
14
- onRemoveFile: () => void;
15
13
  /** Optional Function, executed to download the file */
16
- onDownloadFile?: () => void;
17
- /** Function, executed when a file gets selected */
18
- onSelectFile: (file: DropzoneFile) => void;
14
+ onDownloadFile?: (file: DropzoneFile) => void;
19
15
  /** (Optional) function, executed when a file gets dragged into the upload field and accepted */
20
16
  onDropAccepted?: () => void;
21
17
  /** (Optional) function, executed when a file gets dragged into the upload field and rejected */
@@ -32,9 +28,27 @@ export declare type Props = {
32
28
  previewComponent?: React.ComponentType<PreviewComponentProps>;
33
29
  /** (Optional) Maximum upload size */
34
30
  maxSize?: number;
35
- };
31
+ } & ({
32
+ /** (Optional) accept multiple files */
33
+ multiple?: false;
34
+ /** Function, executed when files get added or removed */
35
+ onChange?: (files: DropzoneFile[]) => void;
36
+ /** Function, executed when a file gets removed */
37
+ onRemoveFile: (file: DropzoneFile) => void;
38
+ /** Function, executed when a file gets selected */
39
+ onSelectFile: (file: DropzoneFile) => void;
40
+ } | {
41
+ /** (Optional) accept multiple files */
42
+ multiple: true;
43
+ /** Function, executed when files get added or removed */
44
+ onChange: (files: DropzoneFile[]) => void;
45
+ /** Function, executed when a file gets removed */
46
+ onRemoveFile?: (file: DropzoneFile) => void;
47
+ /** Function, executed when a file gets selected */
48
+ onSelectFile?: (file: DropzoneFile) => void;
49
+ });
36
50
  export declare type State = {
37
- file: DropzoneFile | null | undefined;
51
+ files: DropzoneFile[];
38
52
  };
39
53
  /**
40
54
  * FileUpload enables the possibility to upload files conveniently
@@ -60,8 +74,8 @@ export default class FileUpload extends React.Component<Props, State> {
60
74
  };
61
75
  state: State;
62
76
  handleDrop: (accepted: Array<DropzoneFile>, rejected: Array<DropzoneFile>) => void;
63
- selectFile: (arg0: DropzoneFile) => void;
64
- handleRemoveFile: () => void;
77
+ selectFile: (files: DropzoneFile[]) => void;
78
+ handleRemoveFile: (file: DropzoneFile) => void;
65
79
  render(): React.JSX.Element;
66
80
  }
67
81
  //# sourceMappingURL=FileUpload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,oBAAY,YAAY,GAAG,IAAI,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IACnC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,mDAAmD;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE3C,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEjD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAEjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAElC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAE9D,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IACpE,MAAM,CAAC,YAAY,EAAE;QACpB,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,QAAQ,EAAE;YACT,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,SAAS,EAAE;YACV,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;KACF,CAiBC;IAEF,KAAK,EAAE,KAAK,CAEV;IAEF,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,CAgBhF;IAEF,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAMtC;IAEF,gBAAgB,EAAE,MAAM,IAAI,CAW1B;IAEF,MAAM;CAqEN"}
1
+ {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"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"}
@@ -38,58 +38,66 @@ class FileUpload extends React.Component {
38
38
  constructor() {
39
39
  super(...arguments);
40
40
  this.state = {
41
- file: null
41
+ files: []
42
42
  };
43
43
  this.handleDrop = (accepted, rejected) => {
44
- if (accepted.length > 1) {
44
+ if (!this.props.multiple && accepted.length > 1) {
45
45
  return;
46
46
  }
47
47
  if (rejected.length > 0) {
48
48
  return;
49
49
  }
50
- const file = accepted[0];
51
50
  /** Prevent console error on <Dropzone /> component */
52
- setTimeout(() => this.selectFile(file), 100);
51
+ setTimeout(() => this.selectFile(accepted), 100);
53
52
  };
54
- this.selectFile = (file) => {
55
- file.preview = URL.createObjectURL(file);
56
- this.setState({
57
- file
53
+ this.selectFile = (files) => {
54
+ const { onSelectFile, onChange } = this.props;
55
+ files.forEach((file) => {
56
+ file.preview = URL.createObjectURL(file);
58
57
  });
59
- this.props.onSelectFile(file);
58
+ const newFiles = [...this.state.files, ...files];
59
+ this.setState({ files: newFiles });
60
+ onChange?.(newFiles);
61
+ if (onSelectFile) {
62
+ files.forEach((file) => {
63
+ onSelectFile(file);
64
+ });
65
+ }
60
66
  };
61
- this.handleRemoveFile = () => {
62
- const { file } = this.state;
63
- const { onRemoveFile } = this.props;
67
+ this.handleRemoveFile = (file) => {
68
+ const { files } = this.state;
64
69
  if (file) {
65
70
  if (file.preview)
66
71
  window.URL.revokeObjectURL(file.preview);
67
- onRemoveFile();
68
- this.setState({
69
- file: null
70
- });
72
+ const newFiles = files.filter((f) => f !== file);
73
+ this.setState({ files: newFiles });
74
+ this.props.onChange?.(newFiles);
75
+ this.props.onRemoveFile?.(file);
71
76
  }
72
77
  };
73
78
  }
74
79
  render() {
75
- const { file } = this.state;
80
+ const { files } = this.state;
76
81
  const { accept, previewComponent: Preview, dropHint, hoverHint, acceptHint, rejectHint,
77
82
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
83
+ onChange,
84
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
78
85
  onRemoveFile, onDownloadFile,
79
86
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
80
- onSelectFile, onDropRejected, onDropAccepted, maxSize, ...otherProps } = this.props;
87
+ onSelectFile, onDropRejected, onDropAccepted, maxSize, multiple, ...otherProps } = this.props;
81
88
  const dropHintOrDefault = dropHint || FileUpload.defaultProps.dropHint;
82
89
  const hoverHintOrDefault = hoverHint || FileUpload.defaultProps.hoverHint;
83
90
  const acceptHintOrDefault = acceptHint || FileUpload.defaultProps.acceptHint;
84
91
  const rejectHintOrDefault = rejectHint || FileUpload.defaultProps.rejectHint;
85
92
  return (React.createElement("div", { ...otherProps, className: (0, classnames_1.default)('di upload', {
86
- clickable: !file,
87
- hasContent: !!file
93
+ clickable: !files.length,
94
+ hasContent: !!files.length
88
95
  }) },
89
- !!file && !!Preview && (
90
- // @ts-ignore
91
- React.createElement(Preview, { file: file, onRemoveFile: this.handleRemoveFile, onDownloadFile: onDownloadFile })),
92
- !file && (React.createElement(react_dropzone_1.default, { accept: accept, multiple: false, style: {
96
+ !!Preview &&
97
+ files.map((file, i) => (React.createElement(Preview, { key: i, file: file, onRemoveFile: () => this.handleRemoveFile(file),
98
+ // @ts-ignore
99
+ onDownloadFile: onDownloadFile && (() => onDownloadFile(file)) }))),
100
+ (multiple || !files.length) && (React.createElement(react_dropzone_1.default, { accept: accept, multiple: multiple ?? false, style: {
93
101
  border: 'none'
94
102
  }, onDrop: this.handleDrop, onDropRejected: onDropRejected, onDropAccepted: onDropAccepted, activeClassName: "active", acceptClassName: "accept", rejectClassName: "reject", maxSize: maxSize || Infinity },
95
103
  React.createElement("div", { className: "drag-drop-text-container" },
@@ -1,12 +1,13 @@
1
1
  import * as React from 'react';
2
- import { Props as FileUploadProps } from './FileUpload';
3
- export declare type Props = FileUploadProps & {
2
+ import { DropzoneFile, Props as FileUploadProps } from './FileUpload';
3
+ export declare type Props = Omit<FileUploadProps, 'multiple'> & {
4
4
  /** (Optional) Url for the image preview */
5
5
  imageUrl: string | null | undefined;
6
6
  imageSize?: 'contain' | 'cover';
7
7
  };
8
8
  declare type ImageUploadState = {
9
9
  dragOverPreview: boolean;
10
+ file: DropzoneFile | null;
10
11
  };
11
12
  /**
12
13
  * ImageUpload enables the possibility to upload images conveniently
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BlE,oBAAY,KAAK,GAAG,eAAe,GAAG;IACrC,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAErB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CAkBN"}
1
+ {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,YAAY,EAAE,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BhF,oBAAY,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACvD,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAGrB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CA+BN"}
@@ -45,7 +45,8 @@ class ImageUpload extends React.Component {
45
45
  constructor() {
46
46
  super(...arguments);
47
47
  this.state = {
48
- dragOverPreview: false
48
+ dragOverPreview: false,
49
+ file: null
49
50
  };
50
51
  this.handleDragOver = () => {
51
52
  this.setState({
@@ -61,13 +62,19 @@ class ImageUpload extends React.Component {
61
62
  }
62
63
  }
63
64
  render() {
64
- const { accept, imageUrl, imageSize, ...otherProps } = this.props;
65
- const { dragOverPreview } = this.state;
66
- if (imageUrl && !dragOverPreview) {
67
- return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: otherProps.onRemoveFile, onDownloadFile: otherProps.onDownloadFile, onDragOver: this.handleDragOver }));
65
+ const { accept, imageUrl, imageSize, onSelectFile, onRemoveFile, ...otherProps } = this.props;
66
+ const { dragOverPreview, file } = this.state;
67
+ if (imageUrl && !dragOverPreview && file) {
68
+ return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: () => onRemoveFile?.(file), onDownloadFile: () => otherProps.onDownloadFile?.(file), onDragOver: this.handleDragOver }));
68
69
  }
69
70
  else {
70
- return React.createElement(FileUpload_1.default, { ...otherProps, accept: accept || 'image/jpeg, image/png' });
71
+ return (React.createElement(FileUpload_1.default, { ...otherProps, onRemoveFile: (file) => {
72
+ this.setState({ file: null });
73
+ onRemoveFile?.(file);
74
+ }, onSelectFile: (file) => {
75
+ this.setState({ file });
76
+ onSelectFile?.(file);
77
+ }, accept: accept || 'image/jpeg, image/png' }));
71
78
  }
72
79
  }
73
80
  }
@@ -74,7 +74,7 @@
74
74
  .di.upload,
75
75
  .di.upload * {transition:all .1s ease;}
76
76
  .di.upload {margin:0; padding:0; width:100%; height:100%; min-height:80px; font-size:16px; border:1px dashed #888; border-radius:4px; overflow:hidden; user-select:none;}
77
- .di.upload {display:flex; align-items:center;}
77
+ .di.upload {display:flex; flex-direction:column; align-items:center;}
78
78
  .di.upload:hover {border-color:#666; background:#f9f9f9;}
79
79
  .di.upload:active {background:#eee;}
80
80
  .di.upload > div {width:100%; height:100%;}
@@ -12,14 +12,14 @@ describe('DateTimeInput.js', () => {
12
12
  expect(timeElement).toHaveDisplayValue('03:24');
13
13
  });
14
14
  it('should display the time and date as timezone date', async () => {
15
- const { rerender } = render(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-01T11:11:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
15
+ const { rerender } = render(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-01T11:11:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
16
16
  const timeElementUtm = screen.queryByDisplayValue('11:11');
17
17
  expect(timeElementUtm).not.toBeInTheDocument();
18
18
  const timeElement = screen.queryByDisplayValue('03:11');
19
19
  expect(timeElement).toBeInTheDocument();
20
20
  const dateElement = screen.queryByDisplayValue('01.02.2019');
21
21
  expect(dateElement).toBeInTheDocument();
22
- rerender(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-02T03:24:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
22
+ rerender(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-02T03:24:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
23
23
  expect(timeElement).toHaveDisplayValue('19:24');
24
24
  expect(dateElement).toHaveDisplayValue('01.02.2019');
25
25
  await act(async () => {
@@ -10,12 +10,8 @@ export declare type PreviewComponentProps = {
10
10
  export declare type Props = {
11
11
  /** (Optional) string for accepting files */
12
12
  accept?: string;
13
- /** Function, executed when a file gets removed */
14
- onRemoveFile: () => void;
15
13
  /** Optional Function, executed to download the file */
16
- onDownloadFile?: () => void;
17
- /** Function, executed when a file gets selected */
18
- onSelectFile: (file: DropzoneFile) => void;
14
+ onDownloadFile?: (file: DropzoneFile) => void;
19
15
  /** (Optional) function, executed when a file gets dragged into the upload field and accepted */
20
16
  onDropAccepted?: () => void;
21
17
  /** (Optional) function, executed when a file gets dragged into the upload field and rejected */
@@ -32,9 +28,27 @@ export declare type Props = {
32
28
  previewComponent?: React.ComponentType<PreviewComponentProps>;
33
29
  /** (Optional) Maximum upload size */
34
30
  maxSize?: number;
35
- };
31
+ } & ({
32
+ /** (Optional) accept multiple files */
33
+ multiple?: false;
34
+ /** Function, executed when files get added or removed */
35
+ onChange?: (files: DropzoneFile[]) => void;
36
+ /** Function, executed when a file gets removed */
37
+ onRemoveFile: (file: DropzoneFile) => void;
38
+ /** Function, executed when a file gets selected */
39
+ onSelectFile: (file: DropzoneFile) => void;
40
+ } | {
41
+ /** (Optional) accept multiple files */
42
+ multiple: true;
43
+ /** Function, executed when files get added or removed */
44
+ onChange: (files: DropzoneFile[]) => void;
45
+ /** Function, executed when a file gets removed */
46
+ onRemoveFile?: (file: DropzoneFile) => void;
47
+ /** Function, executed when a file gets selected */
48
+ onSelectFile?: (file: DropzoneFile) => void;
49
+ });
36
50
  export declare type State = {
37
- file: DropzoneFile | null | undefined;
51
+ files: DropzoneFile[];
38
52
  };
39
53
  /**
40
54
  * FileUpload enables the possibility to upload files conveniently
@@ -60,8 +74,8 @@ export default class FileUpload extends React.Component<Props, State> {
60
74
  };
61
75
  state: State;
62
76
  handleDrop: (accepted: Array<DropzoneFile>, rejected: Array<DropzoneFile>) => void;
63
- selectFile: (arg0: DropzoneFile) => void;
64
- handleRemoveFile: () => void;
77
+ selectFile: (files: DropzoneFile[]) => void;
78
+ handleRemoveFile: (file: DropzoneFile) => void;
65
79
  render(): React.JSX.Element;
66
80
  }
67
81
  //# sourceMappingURL=FileUpload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,oBAAY,YAAY,GAAG,IAAI,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IACnC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,mDAAmD;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE3C,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEjD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAEjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAElC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAE9D,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IACpE,MAAM,CAAC,YAAY,EAAE;QACpB,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,QAAQ,EAAE;YACT,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,SAAS,EAAE;YACV,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;KACF,CAiBC;IAEF,KAAK,EAAE,KAAK,CAEV;IAEF,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,CAgBhF;IAEF,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAMtC;IAEF,gBAAgB,EAAE,MAAM,IAAI,CAW1B;IAEF,MAAM;CAqEN"}
1
+ {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,oBAAY,YAAY,GAAG,IAAI,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IACnC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uDAAuD;IACvD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE9C,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEjD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAEjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAElC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAE9D,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,CACD;IACA,uCAAuC;IACvC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAEjB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAE3C,kDAAkD;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE3C,mDAAmD;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC1C,GACD;IACA,uCAAuC;IACvC,QAAQ,EAAE,IAAI,CAAC;IAEf,yDAAyD;IACzD,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAE1C,kDAAkD;IAClD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE5C,mDAAmD;IACnD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC3C,CACH,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,KAAK,EAAE,YAAY,EAAE,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IACpE,MAAM,CAAC,YAAY,EAAE;QACpB,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,QAAQ,EAAE;YACT,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,SAAS,EAAE;YACV,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;KACF,CAiBC;IAEF,KAAK,EAAE,KAAK,CAEV;IAEF,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,CAchF;IAEF,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAazC;IAEF,gBAAgB,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAU5C;IAEF,MAAM;CA8EN"}
@@ -10,58 +10,66 @@ export default class FileUpload extends React.Component {
10
10
  constructor() {
11
11
  super(...arguments);
12
12
  this.state = {
13
- file: null
13
+ files: []
14
14
  };
15
15
  this.handleDrop = (accepted, rejected) => {
16
- if (accepted.length > 1) {
16
+ if (!this.props.multiple && accepted.length > 1) {
17
17
  return;
18
18
  }
19
19
  if (rejected.length > 0) {
20
20
  return;
21
21
  }
22
- const file = accepted[0];
23
22
  /** Prevent console error on <Dropzone /> component */
24
- setTimeout(() => this.selectFile(file), 100);
23
+ setTimeout(() => this.selectFile(accepted), 100);
25
24
  };
26
- this.selectFile = (file) => {
27
- file.preview = URL.createObjectURL(file);
28
- this.setState({
29
- file
25
+ this.selectFile = (files) => {
26
+ const { onSelectFile, onChange } = this.props;
27
+ files.forEach((file) => {
28
+ file.preview = URL.createObjectURL(file);
30
29
  });
31
- this.props.onSelectFile(file);
30
+ const newFiles = [...this.state.files, ...files];
31
+ this.setState({ files: newFiles });
32
+ onChange?.(newFiles);
33
+ if (onSelectFile) {
34
+ files.forEach((file) => {
35
+ onSelectFile(file);
36
+ });
37
+ }
32
38
  };
33
- this.handleRemoveFile = () => {
34
- const { file } = this.state;
35
- const { onRemoveFile } = this.props;
39
+ this.handleRemoveFile = (file) => {
40
+ const { files } = this.state;
36
41
  if (file) {
37
42
  if (file.preview)
38
43
  window.URL.revokeObjectURL(file.preview);
39
- onRemoveFile();
40
- this.setState({
41
- file: null
42
- });
44
+ const newFiles = files.filter((f) => f !== file);
45
+ this.setState({ files: newFiles });
46
+ this.props.onChange?.(newFiles);
47
+ this.props.onRemoveFile?.(file);
43
48
  }
44
49
  };
45
50
  }
46
51
  render() {
47
- const { file } = this.state;
52
+ const { files } = this.state;
48
53
  const { accept, previewComponent: Preview, dropHint, hoverHint, acceptHint, rejectHint,
49
54
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
55
+ onChange,
56
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
50
57
  onRemoveFile, onDownloadFile,
51
58
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
52
- onSelectFile, onDropRejected, onDropAccepted, maxSize, ...otherProps } = this.props;
59
+ onSelectFile, onDropRejected, onDropAccepted, maxSize, multiple, ...otherProps } = this.props;
53
60
  const dropHintOrDefault = dropHint || FileUpload.defaultProps.dropHint;
54
61
  const hoverHintOrDefault = hoverHint || FileUpload.defaultProps.hoverHint;
55
62
  const acceptHintOrDefault = acceptHint || FileUpload.defaultProps.acceptHint;
56
63
  const rejectHintOrDefault = rejectHint || FileUpload.defaultProps.rejectHint;
57
64
  return (React.createElement("div", { ...otherProps, className: classNames('di upload', {
58
- clickable: !file,
59
- hasContent: !!file
65
+ clickable: !files.length,
66
+ hasContent: !!files.length
60
67
  }) },
61
- !!file && !!Preview && (
62
- // @ts-ignore
63
- React.createElement(Preview, { file: file, onRemoveFile: this.handleRemoveFile, onDownloadFile: onDownloadFile })),
64
- !file && (React.createElement(Dropzone, { accept: accept, multiple: false, style: {
68
+ !!Preview &&
69
+ files.map((file, i) => (React.createElement(Preview, { key: i, file: file, onRemoveFile: () => this.handleRemoveFile(file),
70
+ // @ts-ignore
71
+ onDownloadFile: onDownloadFile && (() => onDownloadFile(file)) }))),
72
+ (multiple || !files.length) && (React.createElement(Dropzone, { accept: accept, multiple: multiple ?? false, style: {
65
73
  border: 'none'
66
74
  }, onDrop: this.handleDrop, onDropRejected: onDropRejected, onDropAccepted: onDropAccepted, activeClassName: "active", acceptClassName: "accept", rejectClassName: "reject", maxSize: maxSize || Infinity },
67
75
  React.createElement("div", { className: "drag-drop-text-container" },
@@ -1,12 +1,13 @@
1
1
  import * as React from 'react';
2
- import { Props as FileUploadProps } from './FileUpload';
3
- export declare type Props = FileUploadProps & {
2
+ import { DropzoneFile, Props as FileUploadProps } from './FileUpload';
3
+ export declare type Props = Omit<FileUploadProps, 'multiple'> & {
4
4
  /** (Optional) Url for the image preview */
5
5
  imageUrl: string | null | undefined;
6
6
  imageSize?: 'contain' | 'cover';
7
7
  };
8
8
  declare type ImageUploadState = {
9
9
  dragOverPreview: boolean;
10
+ file: DropzoneFile | null;
10
11
  };
11
12
  /**
12
13
  * ImageUpload enables the possibility to upload images conveniently
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BlE,oBAAY,KAAK,GAAG,eAAe,GAAG;IACrC,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAErB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CAkBN"}
1
+ {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,YAAY,EAAE,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BhF,oBAAY,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACvD,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAGrB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CA+BN"}
@@ -17,7 +17,8 @@ export default class ImageUpload extends React.Component {
17
17
  constructor() {
18
18
  super(...arguments);
19
19
  this.state = {
20
- dragOverPreview: false
20
+ dragOverPreview: false,
21
+ file: null
21
22
  };
22
23
  this.handleDragOver = () => {
23
24
  this.setState({
@@ -33,13 +34,19 @@ export default class ImageUpload extends React.Component {
33
34
  }
34
35
  }
35
36
  render() {
36
- const { accept, imageUrl, imageSize, ...otherProps } = this.props;
37
- const { dragOverPreview } = this.state;
38
- if (imageUrl && !dragOverPreview) {
39
- return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: otherProps.onRemoveFile, onDownloadFile: otherProps.onDownloadFile, onDragOver: this.handleDragOver }));
37
+ const { accept, imageUrl, imageSize, onSelectFile, onRemoveFile, ...otherProps } = this.props;
38
+ const { dragOverPreview, file } = this.state;
39
+ if (imageUrl && !dragOverPreview && file) {
40
+ return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: () => onRemoveFile?.(file), onDownloadFile: () => otherProps.onDownloadFile?.(file), onDragOver: this.handleDragOver }));
40
41
  }
41
42
  else {
42
- return React.createElement(FileUpload, { ...otherProps, accept: accept || 'image/jpeg, image/png' });
43
+ return (React.createElement(FileUpload, { ...otherProps, onRemoveFile: (file) => {
44
+ this.setState({ file: null });
45
+ onRemoveFile?.(file);
46
+ }, onSelectFile: (file) => {
47
+ this.setState({ file });
48
+ onSelectFile?.(file);
49
+ }, accept: accept || 'image/jpeg, image/png' }));
43
50
  }
44
51
  }
45
52
  }
@@ -12,14 +12,14 @@ describe('DateTimeInput.js', () => {
12
12
  expect(timeElement).toHaveDisplayValue('03:24');
13
13
  });
14
14
  it('should display the time and date as timezone date', async () => {
15
- const { rerender } = render(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-01T11:11:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
15
+ const { rerender } = render(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-01T11:11:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
16
16
  const timeElementUtm = screen.queryByDisplayValue('11:11');
17
17
  expect(timeElementUtm).not.toBeInTheDocument();
18
18
  const timeElement = screen.queryByDisplayValue('03:11');
19
19
  expect(timeElement).toBeInTheDocument();
20
20
  const dateElement = screen.queryByDisplayValue('01.02.2019');
21
21
  expect(dateElement).toBeInTheDocument();
22
- rerender(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-02T03:24:00').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
22
+ rerender(React.createElement(DateTimeInput, { timestamp: new Date('2019-02-02T03:24:00Z').getTime(), onChange: () => { }, timezone: "America/Vancouver" }));
23
23
  expect(timeElement).toHaveDisplayValue('19:24');
24
24
  expect(dateElement).toHaveDisplayValue('01.02.2019');
25
25
  await act(async () => {
@@ -10,12 +10,8 @@ export declare type PreviewComponentProps = {
10
10
  export declare type Props = {
11
11
  /** (Optional) string for accepting files */
12
12
  accept?: string;
13
- /** Function, executed when a file gets removed */
14
- onRemoveFile: () => void;
15
13
  /** Optional Function, executed to download the file */
16
- onDownloadFile?: () => void;
17
- /** Function, executed when a file gets selected */
18
- onSelectFile: (file: DropzoneFile) => void;
14
+ onDownloadFile?: (file: DropzoneFile) => void;
19
15
  /** (Optional) function, executed when a file gets dragged into the upload field and accepted */
20
16
  onDropAccepted?: () => void;
21
17
  /** (Optional) function, executed when a file gets dragged into the upload field and rejected */
@@ -32,9 +28,27 @@ export declare type Props = {
32
28
  previewComponent?: React.ComponentType<PreviewComponentProps>;
33
29
  /** (Optional) Maximum upload size */
34
30
  maxSize?: number;
35
- };
31
+ } & ({
32
+ /** (Optional) accept multiple files */
33
+ multiple?: false;
34
+ /** Function, executed when files get added or removed */
35
+ onChange?: (files: DropzoneFile[]) => void;
36
+ /** Function, executed when a file gets removed */
37
+ onRemoveFile: (file: DropzoneFile) => void;
38
+ /** Function, executed when a file gets selected */
39
+ onSelectFile: (file: DropzoneFile) => void;
40
+ } | {
41
+ /** (Optional) accept multiple files */
42
+ multiple: true;
43
+ /** Function, executed when files get added or removed */
44
+ onChange: (files: DropzoneFile[]) => void;
45
+ /** Function, executed when a file gets removed */
46
+ onRemoveFile?: (file: DropzoneFile) => void;
47
+ /** Function, executed when a file gets selected */
48
+ onSelectFile?: (file: DropzoneFile) => void;
49
+ });
36
50
  export declare type State = {
37
- file: DropzoneFile | null | undefined;
51
+ files: DropzoneFile[];
38
52
  };
39
53
  /**
40
54
  * FileUpload enables the possibility to upload files conveniently
@@ -60,8 +74,8 @@ export default class FileUpload extends React.Component<Props, State> {
60
74
  };
61
75
  state: State;
62
76
  handleDrop: (accepted: Array<DropzoneFile>, rejected: Array<DropzoneFile>) => void;
63
- selectFile: (arg0: DropzoneFile) => void;
64
- handleRemoveFile: () => void;
77
+ selectFile: (files: DropzoneFile[]) => void;
78
+ handleRemoveFile: (file: DropzoneFile) => void;
65
79
  render(): React.JSX.Element;
66
80
  }
67
81
  //# sourceMappingURL=FileUpload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,oBAAY,YAAY,GAAG,IAAI,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,qBAAqB,GAAG;IACnC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,mDAAmD;IACnD,YAAY,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAE3C,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAEjD,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAEjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAElC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAE9D,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,KAAK,GAAG;IACnB,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC;IACpE,MAAM,CAAC,YAAY,EAAE;QACpB,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,QAAQ,EAAE;YACT,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,SAAS,EAAE;YACV,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;QACF,UAAU,EAAE;YACX,YAAY,EAAE,MAAM,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACX,CAAC;KACF,CAiBC;IAEF,KAAK,EAAE,KAAK,CAEV;IAEF,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,CAgBhF;IAEF,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAMtC;IAEF,gBAAgB,EAAE,MAAM,IAAI,CAW1B;IAEF,MAAM;CAqEN"}
1
+ {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../../../src/components/upload/FileUpload.tsx"],"names":[],"mappings":"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"}
@@ -10,58 +10,66 @@ export default class FileUpload extends React.Component {
10
10
  constructor() {
11
11
  super(...arguments);
12
12
  this.state = {
13
- file: null
13
+ files: []
14
14
  };
15
15
  this.handleDrop = (accepted, rejected) => {
16
- if (accepted.length > 1) {
16
+ if (!this.props.multiple && accepted.length > 1) {
17
17
  return;
18
18
  }
19
19
  if (rejected.length > 0) {
20
20
  return;
21
21
  }
22
- const file = accepted[0];
23
22
  /** Prevent console error on <Dropzone /> component */
24
- setTimeout(() => this.selectFile(file), 100);
23
+ setTimeout(() => this.selectFile(accepted), 100);
25
24
  };
26
- this.selectFile = (file) => {
27
- file.preview = URL.createObjectURL(file);
28
- this.setState({
29
- file
25
+ this.selectFile = (files) => {
26
+ const { onSelectFile, onChange } = this.props;
27
+ files.forEach((file) => {
28
+ file.preview = URL.createObjectURL(file);
30
29
  });
31
- this.props.onSelectFile(file);
30
+ const newFiles = [...this.state.files, ...files];
31
+ this.setState({ files: newFiles });
32
+ onChange?.(newFiles);
33
+ if (onSelectFile) {
34
+ files.forEach((file) => {
35
+ onSelectFile(file);
36
+ });
37
+ }
32
38
  };
33
- this.handleRemoveFile = () => {
34
- const { file } = this.state;
35
- const { onRemoveFile } = this.props;
39
+ this.handleRemoveFile = (file) => {
40
+ const { files } = this.state;
36
41
  if (file) {
37
42
  if (file.preview)
38
43
  window.URL.revokeObjectURL(file.preview);
39
- onRemoveFile();
40
- this.setState({
41
- file: null
42
- });
44
+ const newFiles = files.filter((f) => f !== file);
45
+ this.setState({ files: newFiles });
46
+ this.props.onChange?.(newFiles);
47
+ this.props.onRemoveFile?.(file);
43
48
  }
44
49
  };
45
50
  }
46
51
  render() {
47
- const { file } = this.state;
52
+ const { files } = this.state;
48
53
  const { accept, previewComponent: Preview, dropHint, hoverHint, acceptHint, rejectHint,
49
54
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
55
+ onChange,
56
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
50
57
  onRemoveFile, onDownloadFile,
51
58
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
52
- onSelectFile, onDropRejected, onDropAccepted, maxSize, ...otherProps } = this.props;
59
+ onSelectFile, onDropRejected, onDropAccepted, maxSize, multiple, ...otherProps } = this.props;
53
60
  const dropHintOrDefault = dropHint || FileUpload.defaultProps.dropHint;
54
61
  const hoverHintOrDefault = hoverHint || FileUpload.defaultProps.hoverHint;
55
62
  const acceptHintOrDefault = acceptHint || FileUpload.defaultProps.acceptHint;
56
63
  const rejectHintOrDefault = rejectHint || FileUpload.defaultProps.rejectHint;
57
64
  return (React.createElement("div", { ...otherProps, className: classNames('di upload', {
58
- clickable: !file,
59
- hasContent: !!file
65
+ clickable: !files.length,
66
+ hasContent: !!files.length
60
67
  }) },
61
- !!file && !!Preview && (
62
- // @ts-ignore
63
- React.createElement(Preview, { file: file, onRemoveFile: this.handleRemoveFile, onDownloadFile: onDownloadFile })),
64
- !file && (React.createElement(Dropzone, { accept: accept, multiple: false, style: {
68
+ !!Preview &&
69
+ files.map((file, i) => (React.createElement(Preview, { key: i, file: file, onRemoveFile: () => this.handleRemoveFile(file),
70
+ // @ts-ignore
71
+ onDownloadFile: onDownloadFile && (() => onDownloadFile(file)) }))),
72
+ (multiple || !files.length) && (React.createElement(Dropzone, { accept: accept, multiple: multiple ?? false, style: {
65
73
  border: 'none'
66
74
  }, onDrop: this.handleDrop, onDropRejected: onDropRejected, onDropAccepted: onDropAccepted, activeClassName: "active", acceptClassName: "accept", rejectClassName: "reject", maxSize: maxSize || Infinity },
67
75
  React.createElement("div", { className: "drag-drop-text-container" },
@@ -1,12 +1,13 @@
1
1
  import * as React from 'react';
2
- import { Props as FileUploadProps } from './FileUpload';
3
- export declare type Props = FileUploadProps & {
2
+ import { DropzoneFile, Props as FileUploadProps } from './FileUpload';
3
+ export declare type Props = Omit<FileUploadProps, 'multiple'> & {
4
4
  /** (Optional) Url for the image preview */
5
5
  imageUrl: string | null | undefined;
6
6
  imageSize?: 'contain' | 'cover';
7
7
  };
8
8
  declare type ImageUploadState = {
9
9
  dragOverPreview: boolean;
10
+ file: DropzoneFile | null;
10
11
  };
11
12
  /**
12
13
  * ImageUpload enables the possibility to upload images conveniently
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BlE,oBAAY,KAAK,GAAG,eAAe,GAAG;IACrC,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAErB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CAkBN"}
1
+ {"version":3,"file":"ImageUpload.d.ts","sourceRoot":"","sources":["../../../../../src/components/upload/ImageUpload.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAmB,EAAC,YAAY,EAAE,KAAK,IAAI,eAAe,EAAC,MAAM,cAAc,CAAC;AA+BhF,oBAAY,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACvD,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,aAAK,gBAAgB,GAAG;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAChF,KAAK,EAAE,gBAAgB,CAGrB;IAEF,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IAQ1C,cAAc,EAAE,MAAM,IAAI,CAIxB;IAEF,MAAM;CA+BN"}
@@ -17,7 +17,8 @@ export default class ImageUpload extends React.Component {
17
17
  constructor() {
18
18
  super(...arguments);
19
19
  this.state = {
20
- dragOverPreview: false
20
+ dragOverPreview: false,
21
+ file: null
21
22
  };
22
23
  this.handleDragOver = () => {
23
24
  this.setState({
@@ -33,13 +34,19 @@ export default class ImageUpload extends React.Component {
33
34
  }
34
35
  }
35
36
  render() {
36
- const { accept, imageUrl, imageSize, ...otherProps } = this.props;
37
- const { dragOverPreview } = this.state;
38
- if (imageUrl && !dragOverPreview) {
39
- return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: otherProps.onRemoveFile, onDownloadFile: otherProps.onDownloadFile, onDragOver: this.handleDragOver }));
37
+ const { accept, imageUrl, imageSize, onSelectFile, onRemoveFile, ...otherProps } = this.props;
38
+ const { dragOverPreview, file } = this.state;
39
+ if (imageUrl && !dragOverPreview && file) {
40
+ return (React.createElement(PreviewImage, { url: imageUrl, imageSize: imageSize, onRemoveFile: () => onRemoveFile?.(file), onDownloadFile: () => otherProps.onDownloadFile?.(file), onDragOver: this.handleDragOver }));
40
41
  }
41
42
  else {
42
- return React.createElement(FileUpload, { ...otherProps, accept: accept || 'image/jpeg, image/png' });
43
+ return (React.createElement(FileUpload, { ...otherProps, onRemoveFile: (file) => {
44
+ this.setState({ file: null });
45
+ onRemoveFile?.(file);
46
+ }, onSelectFile: (file) => {
47
+ this.setState({ file });
48
+ onSelectFile?.(file);
49
+ }, accept: accept || 'image/jpeg, image/png' }));
43
50
  }
44
51
  }
45
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deviceinsight/ng-ui-components",
3
- "version": "6.24.0",
3
+ "version": "6.25.0",
4
4
  "private": false,
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {
@@ -36,29 +36,29 @@
36
36
  "storybook": "start-storybook -p 6006"
37
37
  },
38
38
  "dependencies": {
39
- "@deviceinsight/ng-ui-api-client": "10.39.0",
40
- "@deviceinsight/ng-ui-basic-components": "3.16.0",
41
- "@dnd-kit/core": "6.0.5",
42
- "@dnd-kit/modifiers": "6.0.0",
43
- "@dnd-kit/sortable": "7.0.1",
44
- "@svgdotjs/svg.js": "3.0.16",
45
- "classnames": "2.3.1",
46
- "dayjs": "1.11.0",
47
- "highcharts": "10.2.1",
48
- "highcharts-react-official": "3.1.0",
49
- "lodash": "4.17.21",
50
- "nanoid": "3.3.8",
51
- "pure-color": "1.3.0",
52
- "rc-slider": "9.7.5",
53
- "react-colorful": "5.5.1",
54
- "react-datepicker": "4.10.0",
55
- "react-draggable": "4.4.3",
56
- "react-dropzone": "7.0.1",
57
- "react-onclickoutside": "6.12.2",
58
- "react-popper": "2.3.0",
59
- "react-select": "5.7.0",
60
- "react-select-async-paginate": "0.7.2",
61
- "react-toastify": "7.0.3"
39
+ "@deviceinsight/ng-ui-api-client": "^10.39.0",
40
+ "@deviceinsight/ng-ui-basic-components": "^3.16.0",
41
+ "@dnd-kit/core": "^6.0.5",
42
+ "@dnd-kit/modifiers": "^6.0.0",
43
+ "@dnd-kit/sortable": "^7.0.1",
44
+ "@svgdotjs/svg.js": "^3.0.16",
45
+ "classnames": "^2.3.1",
46
+ "dayjs": "^1.11.0",
47
+ "highcharts": "^10.2.1",
48
+ "highcharts-react-official": "^3.1.0",
49
+ "lodash": "^4.17.21",
50
+ "nanoid": "^3.3.8",
51
+ "pure-color": "^1.3.0",
52
+ "rc-slider": "^9.7.5",
53
+ "react-colorful": "^5.5.1",
54
+ "react-datepicker": "^4.10.0",
55
+ "react-draggable": "^4.4.3",
56
+ "react-dropzone": "^7.0.1",
57
+ "react-onclickoutside": "^6.12.2",
58
+ "react-popper": "^2.3.0",
59
+ "react-select": "^5.7.0",
60
+ "react-select-async-paginate": "^0.7.2",
61
+ "react-toastify": "^7.0.3"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "react": "^18.x",