@reykjavik/hanna-react 0.10.61 → 0.10.64
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/CHANGELOG.md +19 -0
- package/FileInput/_FileInput.utils.d.ts +36 -0
- package/FileInput/_FileInput.utils.js +69 -0
- package/FileInput/_FileInputFileList.d.ts +11 -0
- package/FileInput/_FileInputFileList.js +24 -0
- package/FileInput.d.ts +38 -7
- package/FileInput.js +43 -78
- package/TagPill.js +3 -2
- package/_abstract/_AbstractCarousel.js +4 -4
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.10.63 – 0.10.64
|
|
8
|
+
|
|
9
|
+
_2022-08-29_
|
|
10
|
+
|
|
11
|
+
- feat: Changes to `FileInput`
|
|
12
|
+
- feat: Add prop `FileList` to suppress (`false`) or customize its rendering
|
|
13
|
+
- feat: Add props `multiple`, `accept`
|
|
14
|
+
- feat: Deprecate prop `dropzoneProps`
|
|
15
|
+
- fix: report deleted when adding files in single-file mode
|
|
16
|
+
- fix: Make `dropZoneProps` optional, as originally indented
|
|
17
|
+
- fix: Hide `Carousel` mouse-cursor scroll controls at start/end positions
|
|
18
|
+
- fix: Pass `id` and other HTML props to static (span) `TagPill`s
|
|
19
|
+
|
|
20
|
+
## 0.10.62
|
|
21
|
+
|
|
22
|
+
_2022-08-23_
|
|
23
|
+
|
|
24
|
+
- feat: Add `diff` object to `FileInput`'s `onFilesUpdated` callback signature
|
|
25
|
+
|
|
7
26
|
## 0.10.61
|
|
8
27
|
|
|
9
28
|
_2022-08-11_
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare type CustomFile = {
|
|
2
|
+
preview?: string;
|
|
3
|
+
} & File;
|
|
4
|
+
/**
|
|
5
|
+
* Attaches a `preview` prop to file objects that don't already have a `preview` key defined
|
|
6
|
+
*
|
|
7
|
+
* The preview's value is either a data URI (for image-type files) or `undefined`
|
|
8
|
+
*/
|
|
9
|
+
export declare const addPreview: (file: CustomFile) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Revokes `preview` data URIs to avoid memory leaks
|
|
12
|
+
*
|
|
13
|
+
* (See: https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL)
|
|
14
|
+
*/
|
|
15
|
+
export declare const releasePreview: (file: CustomFile) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Small+stupid file size pretty-printer.
|
|
18
|
+
*/
|
|
19
|
+
export declare const formatBytes: (bytes: number, decimals?: number) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Figures out how to handle adding files to a FileInput
|
|
22
|
+
* Which files to retaine, which too delete, and
|
|
23
|
+
* what the updated fileList should look like.
|
|
24
|
+
*
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
export declare const getFileListUpdate: (oldFileList: Array<File>, added: Array<File>, replaceMode: boolean) => {
|
|
28
|
+
fileList: File[];
|
|
29
|
+
diff: {
|
|
30
|
+
added: File[];
|
|
31
|
+
deleted: File[];
|
|
32
|
+
} | {
|
|
33
|
+
added: File[];
|
|
34
|
+
deleted?: undefined;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFileListUpdate = exports.formatBytes = exports.releasePreview = exports.addPreview = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Attaches a `preview` prop to file objects that don't already have a `preview` key defined
|
|
6
|
+
*
|
|
7
|
+
* The preview's value is either a data URI (for image-type files) or `undefined`
|
|
8
|
+
*/
|
|
9
|
+
const addPreview = (file) => {
|
|
10
|
+
if (!('preview' in file)) {
|
|
11
|
+
file.preview = file.type.includes('image/') ? URL.createObjectURL(file) : undefined;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
exports.addPreview = addPreview;
|
|
15
|
+
/**
|
|
16
|
+
* Revokes `preview` data URIs to avoid memory leaks
|
|
17
|
+
*
|
|
18
|
+
* (See: https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL)
|
|
19
|
+
*/
|
|
20
|
+
const releasePreview = (file) => {
|
|
21
|
+
file.preview && URL.revokeObjectURL(file.preview);
|
|
22
|
+
delete file.preview;
|
|
23
|
+
};
|
|
24
|
+
exports.releasePreview = releasePreview;
|
|
25
|
+
/**
|
|
26
|
+
* Small+stupid file size pretty-printer.
|
|
27
|
+
*/
|
|
28
|
+
const formatBytes = (bytes, decimals = 2) => {
|
|
29
|
+
if (bytes === 0) {
|
|
30
|
+
return '0 Bytes';
|
|
31
|
+
}
|
|
32
|
+
const k = 1024;
|
|
33
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
34
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
35
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
|
|
36
|
+
};
|
|
37
|
+
exports.formatBytes = formatBytes;
|
|
38
|
+
/**
|
|
39
|
+
* Figures out how to handle adding files to a FileInput
|
|
40
|
+
* Which files to retaine, which too delete, and
|
|
41
|
+
* what the updated fileList should look like.
|
|
42
|
+
*
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
const getFileListUpdate = (oldFileList, added,
|
|
46
|
+
/**
|
|
47
|
+
* `replaceMode: true` is the default "single-file" input behavior.
|
|
48
|
+
*
|
|
49
|
+
* Pass `false` to this argument when the "multiple" prop is true.
|
|
50
|
+
*/
|
|
51
|
+
replaceMode) => {
|
|
52
|
+
const deleted = replaceMode ? oldFileList : [];
|
|
53
|
+
const retained = [];
|
|
54
|
+
if (!replaceMode) {
|
|
55
|
+
oldFileList.forEach((oldFile) => {
|
|
56
|
+
if (added.find(({ name }) => name === oldFile.name)) {
|
|
57
|
+
deleted.push(oldFile);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
retained.push(oldFile);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
fileList: retained.concat(added),
|
|
66
|
+
diff: deleted.length ? { added, deleted } : { added },
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
exports.getFileListUpdate = getFileListUpdate;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { formatBytes } from './_FileInput.utils';
|
|
2
|
+
import { CustomFile } from './_FileInput.utils';
|
|
3
|
+
export declare type FileListProps = {
|
|
4
|
+
files: Array<CustomFile>;
|
|
5
|
+
showFileSize?: boolean;
|
|
6
|
+
showImagePreviews?: boolean;
|
|
7
|
+
removeFileText: string;
|
|
8
|
+
removeFile: (file: File | string) => void;
|
|
9
|
+
formatBytes: typeof formatBytes;
|
|
10
|
+
};
|
|
11
|
+
export declare const DefaultFileList: (props: FileListProps) => JSX.Element | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultFileList = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const DefaultFileList = (props) => {
|
|
7
|
+
const { files, showFileSize, showImagePreviews, removeFileText, removeFile, formatBytes, } = props;
|
|
8
|
+
if (!files.length) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return (react_1.default.createElement("ul", { className: "FileInput__filelist" }, files.map((file) => (react_1.default.createElement("li", { key: file.name, className: "FileInput__file" },
|
|
12
|
+
react_1.default.createElement("button", { className: "FileInput__file-remove", type: "button", onClick: () => removeFile(file), "aria-label": removeFileText }, removeFileText),
|
|
13
|
+
react_1.default.createElement("span", { className: "FileInput__fileinfo" },
|
|
14
|
+
showImagePreviews && file.preview && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
15
|
+
react_1.default.createElement("span", { className: "FileInput__preview" },
|
|
16
|
+
react_1.default.createElement("img", { src: file.preview })),
|
|
17
|
+
' ')),
|
|
18
|
+
react_1.default.createElement("span", { className: "FileInput__filename" }, file.name),
|
|
19
|
+
showFileSize && (react_1.default.createElement("small", { className: "FileInput__filesize" },
|
|
20
|
+
" - (",
|
|
21
|
+
formatBytes(file.size),
|
|
22
|
+
")"))))))));
|
|
23
|
+
};
|
|
24
|
+
exports.DefaultFileList = DefaultFileList;
|
package/FileInput.d.ts
CHANGED
|
@@ -1,17 +1,48 @@
|
|
|
1
|
+
import { FileListProps } from './FileInput/_FileInputFileList';
|
|
1
2
|
import { FormFieldWrappingProps } from './FormField';
|
|
2
|
-
declare type dropzonePropsProps = {
|
|
3
|
-
accept?: string;
|
|
4
|
-
multiple?: boolean;
|
|
5
|
-
};
|
|
6
3
|
export declare type FileInputProps = {
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Flags if the input should accept multiple, or just a single file at a time.
|
|
6
|
+
*
|
|
7
|
+
* Default: `true`
|
|
8
|
+
*/
|
|
9
|
+
multiple?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Accepted file mime type(s).
|
|
12
|
+
*
|
|
13
|
+
* Default: no restrictions.
|
|
14
|
+
*/
|
|
15
|
+
accept?: string | Array<string>;
|
|
8
16
|
dropzoneText: string | JSX.Element;
|
|
17
|
+
removeFileText: string;
|
|
9
18
|
showFileSize?: boolean;
|
|
10
19
|
showImagePreviews?: boolean;
|
|
11
|
-
|
|
12
|
-
onFilesUpdated?: (
|
|
20
|
+
FileList?: false | ((props: FileListProps) => JSX.Element | null);
|
|
21
|
+
onFilesUpdated?: (
|
|
22
|
+
/** Updated, full list of Files. */
|
|
23
|
+
files: Array<File>,
|
|
24
|
+
/** Information about which Files were added or removed during with this update.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: When a diff contains both added and deleted files, this indicates a
|
|
27
|
+
* name-conflict occurred — i.e. one of the added files has a name that
|
|
28
|
+
* existed in the old file list.
|
|
29
|
+
* In such cases the deletion is more implicit than explicit, and depending
|
|
30
|
+
* on the circumstances, you MIGHT wish to either warn the user, rename
|
|
31
|
+
* one of the files, instead of overwriting/deleting the older file, etc.
|
|
32
|
+
*/
|
|
33
|
+
diff: {
|
|
34
|
+
deleted?: Array<File>;
|
|
35
|
+
added?: Array<File>;
|
|
36
|
+
}) => void;
|
|
13
37
|
name?: string;
|
|
14
38
|
value?: ReadonlyArray<File>;
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Use props `multiple`, `accept` instead (Will be removed in v0.11)
|
|
41
|
+
*/
|
|
42
|
+
dropzoneProps?: {
|
|
43
|
+
accept?: string;
|
|
44
|
+
multiple?: boolean;
|
|
45
|
+
};
|
|
15
46
|
} & FormFieldWrappingProps;
|
|
16
47
|
declare const FileInput: (props: FileInputProps) => JSX.Element;
|
|
17
48
|
export default FileInput;
|
package/FileInput.js
CHANGED
|
@@ -5,26 +5,9 @@ const react_1 = tslib_1.__importStar(require("react"));
|
|
|
5
5
|
const react_dropzone_1 = require("react-dropzone"); // https://react-dropzone.js.org/#!/Dropzone
|
|
6
6
|
const hooks_1 = require("@hugsmidjan/react/hooks");
|
|
7
7
|
const getBemClass_1 = tslib_1.__importDefault(require("@hugsmidjan/react/utils/getBemClass"));
|
|
8
|
+
const _FileInput_utils_1 = require("./FileInput/_FileInput.utils");
|
|
9
|
+
const _FileInputFileList_1 = require("./FileInput/_FileInputFileList");
|
|
8
10
|
const FormField_1 = tslib_1.__importDefault(require("./FormField"));
|
|
9
|
-
/**
|
|
10
|
-
* Attaches a `preview` prop to file objects that don't already have a `preview` key defined
|
|
11
|
-
*
|
|
12
|
-
* The preview's value is either a data URI (for image-type files) or `undefined`
|
|
13
|
-
*/
|
|
14
|
-
const addPreview = (file) => {
|
|
15
|
-
if (!('preview' in file)) {
|
|
16
|
-
file.preview = file.type.includes('image/') ? URL.createObjectURL(file) : undefined;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Revokes `preview` data URIs to avoid memory leaks
|
|
21
|
-
*
|
|
22
|
-
* (See: https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL)
|
|
23
|
-
*/
|
|
24
|
-
const releasePreview = (file) => {
|
|
25
|
-
file.preview && URL.revokeObjectURL(file.preview);
|
|
26
|
-
delete file.preview;
|
|
27
|
-
};
|
|
28
11
|
const arrayToFileList = (arr) => {
|
|
29
12
|
const fileList = new DataTransfer();
|
|
30
13
|
arr.forEach((item) => {
|
|
@@ -32,115 +15,97 @@ const arrayToFileList = (arr) => {
|
|
|
32
15
|
});
|
|
33
16
|
return fileList.files;
|
|
34
17
|
};
|
|
35
|
-
const dedupeFilesArray = (files) => {
|
|
36
|
-
const newArray = [];
|
|
37
|
-
const found = {};
|
|
38
|
-
files.forEach((file) => {
|
|
39
|
-
if (!(file.name in found)) {
|
|
40
|
-
newArray.push(file);
|
|
41
|
-
found[file.name] = true;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
releasePreview(file);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
return newArray;
|
|
48
|
-
};
|
|
49
|
-
const formatBytes = (bytes, decimals = 2) => {
|
|
50
|
-
if (bytes === 0) {
|
|
51
|
-
return '0 Bytes';
|
|
52
|
-
}
|
|
53
|
-
const k = 1024;
|
|
54
|
-
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
55
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
56
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + ' ' + sizes[i];
|
|
57
|
-
};
|
|
58
18
|
const FileInput = (props) => {
|
|
59
|
-
const { className, id, label, hideLabel, dropzoneProps = { multiple: true }, dropzoneText, removeFileText, assistText, disabled, invalid, errorMessage, required, reqText, onFilesUpdated = () => undefined, showFileSize, showImagePreviews, value = [] } = props, inputElementProps = tslib_1.__rest(props, ["className", "id", "label", "hideLabel", "dropzoneProps", "dropzoneText", "removeFileText", "assistText", "disabled", "invalid", "errorMessage", "required", "reqText", "onFilesUpdated", "showFileSize", "showImagePreviews", "value"]);
|
|
19
|
+
const { className, id, label, hideLabel, dropzoneProps = { multiple: true }, multiple = dropzoneProps.multiple, accept, dropzoneText, removeFileText, assistText, disabled, invalid, errorMessage, required, reqText, FileList = _FileInputFileList_1.DefaultFileList, onFilesUpdated = () => undefined, showFileSize, showImagePreviews, value = [] } = props, inputElementProps = tslib_1.__rest(props, ["className", "id", "label", "hideLabel", "dropzoneProps", "multiple", "accept", "dropzoneText", "removeFileText", "assistText", "disabled", "invalid", "errorMessage", "required", "reqText", "FileList", "onFilesUpdated", "showFileSize", "showImagePreviews", "value"]);
|
|
60
20
|
const domid = (0, hooks_1.useDomid)(id);
|
|
61
21
|
const fileInputWrapper = (0, react_1.useRef)(null);
|
|
62
22
|
const fileInput = (0, react_1.useRef)(null);
|
|
63
23
|
const files = value;
|
|
64
24
|
const [isHover, setIsHover] = (0, react_1.useState)(false);
|
|
65
|
-
const { getRootProps, getInputProps, isDragReject, inputRef } = (0, react_dropzone_1.useDropzone)(
|
|
25
|
+
const { getRootProps, getInputProps, isDragReject, inputRef } = (0, react_dropzone_1.useDropzone)({
|
|
26
|
+
onDrop: (acceptedFiles) => {
|
|
66
27
|
acceptedFiles = acceptedFiles.map((file) => {
|
|
67
|
-
addPreview(file);
|
|
28
|
+
(0, _FileInput_utils_1.addPreview)(file);
|
|
68
29
|
return file;
|
|
69
30
|
});
|
|
70
31
|
addFiles(acceptedFiles); // eslint-disable-line
|
|
71
32
|
setIsHover(false);
|
|
72
|
-
},
|
|
33
|
+
},
|
|
34
|
+
onDropRejected: (rejectedFiles) => {
|
|
73
35
|
window.alert('Error:\n' +
|
|
74
36
|
rejectedFiles
|
|
75
37
|
.map((elm) => {
|
|
76
38
|
return elm.name;
|
|
77
39
|
})
|
|
78
40
|
.join(', '));
|
|
79
|
-
},
|
|
41
|
+
},
|
|
42
|
+
onDragEnter: () => {
|
|
80
43
|
// 'dragLeave' always fires right after 'dragEnter', use 'dragOver' instead
|
|
81
44
|
// console.log('enter');
|
|
82
45
|
// setIsHover(true);
|
|
83
|
-
},
|
|
46
|
+
},
|
|
47
|
+
onDragLeave: () => {
|
|
84
48
|
// console.log('leave');
|
|
85
49
|
setIsHover(false);
|
|
86
|
-
},
|
|
50
|
+
},
|
|
51
|
+
onDragOver: () => {
|
|
87
52
|
// TODO: add error icon? 'isDragReject' gives unstable results
|
|
88
53
|
// console.log(isDragReject);
|
|
89
54
|
setIsHover(true);
|
|
90
|
-
}
|
|
55
|
+
},
|
|
56
|
+
multiple,
|
|
57
|
+
accept,
|
|
58
|
+
});
|
|
91
59
|
// Add previews on incoming files
|
|
92
60
|
// (NOTE: `addPreview` ignores files that already have preview.)
|
|
93
|
-
files.forEach(addPreview);
|
|
61
|
+
files.forEach(_FileInput_utils_1.addPreview);
|
|
94
62
|
(0, react_1.useEffect)(() => () => {
|
|
95
63
|
// Make sure to revoke the data uris on unmount to avoid memory leaks
|
|
96
|
-
files.forEach(releasePreview);
|
|
64
|
+
files.forEach(_FileInput_utils_1.releasePreview);
|
|
97
65
|
}, [files]);
|
|
98
|
-
const removeFile = (
|
|
66
|
+
const removeFile = (removeTarget) => {
|
|
99
67
|
if (fileInput.current) {
|
|
68
|
+
const deleted = [];
|
|
69
|
+
const targetName = typeof removeTarget !== 'string' ? removeTarget.name : removeTarget;
|
|
100
70
|
const newFileList = files.filter((file) => {
|
|
101
|
-
if (file.name !==
|
|
71
|
+
if (file.name !== targetName) {
|
|
102
72
|
return true;
|
|
103
73
|
}
|
|
104
|
-
|
|
74
|
+
deleted.push(file);
|
|
75
|
+
(0, _FileInput_utils_1.releasePreview)(file);
|
|
76
|
+
return false;
|
|
105
77
|
});
|
|
106
78
|
fileInput.current.files = arrayToFileList(newFileList);
|
|
107
|
-
onFilesUpdated(newFileList);
|
|
79
|
+
onFilesUpdated(newFileList, { deleted });
|
|
108
80
|
}
|
|
109
81
|
};
|
|
110
|
-
const addFiles = (
|
|
82
|
+
const addFiles = (added) => {
|
|
111
83
|
if (fileInput.current) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
fileInput.current.files = arrayToFileList(newFileList);
|
|
116
|
-
onFilesUpdated(newFileList);
|
|
84
|
+
const { fileList, diff } = (0, _FileInput_utils_1.getFileListUpdate)(files, added, !multiple);
|
|
85
|
+
fileInput.current.files = arrayToFileList(fileList);
|
|
86
|
+
onFilesUpdated(fileList, diff);
|
|
117
87
|
}
|
|
118
88
|
if (inputRef.current) {
|
|
119
89
|
// Empty on every add
|
|
120
90
|
inputRef.current.files = arrayToFileList([]);
|
|
121
91
|
}
|
|
122
92
|
};
|
|
123
|
-
|
|
124
|
-
react_1.default.createElement("button", { className: "FileInput__file-remove", type: "button", onClick: () => removeFile(file.name), "aria-label": removeFileText }, removeFileText),
|
|
125
|
-
react_1.default.createElement("span", { className: "FileInput__fileinfo" },
|
|
126
|
-
showImagePreviews && file.preview && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
127
|
-
react_1.default.createElement("span", { className: "FileInput__preview" },
|
|
128
|
-
react_1.default.createElement("img", { src: file.preview })),
|
|
129
|
-
' ')),
|
|
130
|
-
react_1.default.createElement("span", { className: "FileInput__filename" }, file.name),
|
|
131
|
-
showFileSize && (react_1.default.createElement("small", { className: "FileInput__filesize" },
|
|
132
|
-
" - (",
|
|
133
|
-
formatBytes(file.size),
|
|
134
|
-
")"))))));
|
|
135
|
-
return (react_1.default.createElement(FormField_1.default, { className: (0, getBemClass_1.default)('FileInput', [dropzoneProps.multiple && 'multi'], className), label: label, id: domid + '-fake', LabelTag: "h4", assistText: assistText, hideLabel: hideLabel, disabled: disabled, invalid: invalid, errorMessage: errorMessage, required: required, reqText: reqText, renderInput: (className, inputProps /* , addFocusProps */) => {
|
|
93
|
+
return (react_1.default.createElement(FormField_1.default, { className: (0, getBemClass_1.default)('FileInput', [multiple && 'multi'], className), label: label, id: domid + '-fake', LabelTag: "h4", assistText: assistText, hideLabel: hideLabel, disabled: disabled, invalid: invalid, errorMessage: errorMessage, required: required, reqText: reqText, renderInput: (className, inputProps /* , addFocusProps */) => {
|
|
136
94
|
return (react_1.default.createElement("div", { className: className.control, ref: fileInputWrapper },
|
|
137
|
-
react_1.default.createElement("input", { className: "FileInput__input", name: inputElementProps.name, id: domid, ref: fileInput, type: "file", style: { display: 'none' }, multiple:
|
|
95
|
+
react_1.default.createElement("input", { className: "FileInput__input", name: inputElementProps.name, id: domid, ref: fileInput, type: "file", style: { display: 'none' }, multiple: multiple || undefined, required: inputProps.required }),
|
|
138
96
|
' ',
|
|
139
|
-
react_1.default.createElement("input", Object.assign({ className: "FileInput__input--fake" }, getInputProps(), { tabIndex: undefined, style: undefined, multiple:
|
|
97
|
+
react_1.default.createElement("input", Object.assign({ className: "FileInput__input--fake" }, getInputProps(), { tabIndex: undefined, style: undefined, multiple: multiple || undefined }, inputProps, { required: undefined })),
|
|
140
98
|
' ',
|
|
141
99
|
react_1.default.createElement("div", Object.assign({ className: (0, getBemClass_1.default)('FileInput__dropzone', [isHover && 'highlight']) }, getRootProps({ isDragReject }), { tabIndex: undefined }),
|
|
142
100
|
react_1.default.createElement("p", { className: "FileInput__droptext" }, dropzoneText)),
|
|
143
|
-
|
|
101
|
+
FileList && (react_1.default.createElement(FileList, Object.assign({}, {
|
|
102
|
+
files,
|
|
103
|
+
showFileSize,
|
|
104
|
+
showImagePreviews,
|
|
105
|
+
removeFileText,
|
|
106
|
+
removeFile,
|
|
107
|
+
formatBytes: _FileInput_utils_1.formatBytes,
|
|
108
|
+
})))));
|
|
144
109
|
} }));
|
|
145
110
|
};
|
|
146
111
|
exports.default = FileInput;
|
package/TagPill.js
CHANGED
|
@@ -18,10 +18,11 @@ const TagPill = (props) => {
|
|
|
18
18
|
removable &&
|
|
19
19
|
isStatic &&
|
|
20
20
|
!onRemove &&
|
|
21
|
-
console.warn('static (non-button) `TagPill`s
|
|
21
|
+
console.warn('Removable static (non-button) `TagPill`s ' +
|
|
22
|
+
'must have an `onRemove` handler defined');
|
|
22
23
|
const modifiers = [modifier, large && 'large', colors[color]];
|
|
23
24
|
const removeBtn = removable && (react_1.default.createElement("button", { className: "TagPill__remove", onClick: onRemove && (() => onRemove()), "aria-label": removeLabelLong, type: "button" }, removeLabel));
|
|
24
|
-
return isStatic ? (react_1.default.createElement("span", { className: (0, getBemClass_1.default)('TagPill', modifiers) },
|
|
25
|
+
return isStatic ? (react_1.default.createElement("span", Object.assign({ className: (0, getBemClass_1.default)('TagPill', modifiers) }, buttonProps),
|
|
25
26
|
label,
|
|
26
27
|
" ",
|
|
27
28
|
removeBtn)) : onRemove ? (react_1.default.createElement("span", { className: (0, getBemClass_1.default)('TagPill', modifiers) },
|
|
@@ -95,14 +95,14 @@ const AbstractCarousel = (props) => {
|
|
|
95
95
|
title && react_1.default.createElement("h2", { className: bem + '__title' }, title),
|
|
96
96
|
isBrowser ? (react_1.default.createElement("div", { className: bem + '__itemlist-wrapper' },
|
|
97
97
|
itemList,
|
|
98
|
-
react_1.default.createElement("div", { className: bem + '__itemlist-goLeft', onClick: () => {
|
|
98
|
+
activeItem > 0 && (react_1.default.createElement("div", { className: bem + '__itemlist-goLeft', onClick: () => {
|
|
99
99
|
delayedScrollLeft.cancel();
|
|
100
100
|
scrollToItem(activeItem - 1);
|
|
101
|
-
}, onMouseOver: () => delayedScrollLeft(activeItem), onMouseOut: () => delayedScrollLeft.cancel() }),
|
|
102
|
-
react_1.default.createElement("div", { className: bem + '__itemlist-goRight', onClick: () => {
|
|
101
|
+
}, onMouseOver: () => delayedScrollLeft(activeItem), onMouseOut: () => delayedScrollLeft.cancel() })),
|
|
102
|
+
activeItem < itemCount - 1 && (react_1.default.createElement("div", { className: bem + '__itemlist-goRight', onClick: () => {
|
|
103
103
|
delayedScrollRight.cancel();
|
|
104
104
|
scrollToItem(activeItem + 1);
|
|
105
|
-
}, onMouseOver: () => delayedScrollRight(activeItem), onMouseOut: () => delayedScrollRight.cancel() }))) : (itemList),
|
|
105
|
+
}, onMouseOver: () => delayedScrollRight(activeItem), onMouseOut: () => delayedScrollRight.cancel() })))) : (itemList),
|
|
106
106
|
isBrowser && (react_1.default.createElement(CarouselStepper_1.default, { itemCount: itemCount, setCurrent: scrollToItem, current: activeItem }))));
|
|
107
107
|
};
|
|
108
108
|
exports.default = AbstractCarousel;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reykjavik/hanna-react",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.64",
|
|
4
4
|
"author": "Reykjavík (http://www.reykjavik.is)",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Hugsmiðjan ehf (http://www.hugsmidjan.is)",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@hugsmidjan/qj": "^4.10.2",
|
|
17
17
|
"@hugsmidjan/react": "^0.4.17",
|
|
18
|
-
"@reykjavik/hanna-css": "^0.3.
|
|
19
|
-
"@reykjavik/hanna-utils": "^0.1.
|
|
18
|
+
"@reykjavik/hanna-css": "^0.3.7",
|
|
19
|
+
"@reykjavik/hanna-utils": "^0.1.11",
|
|
20
20
|
"@types/react": "^17.0.24",
|
|
21
21
|
"@types/react-autosuggest": "^10.1.0",
|
|
22
22
|
"@types/react-datepicker": "^3.0.2",
|