@jobber/components 4.71.8 → 4.72.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.
@@ -6,7 +6,7 @@ var tslib_es6 = require('../tslib.es6-5b8768b7.js');
6
6
  var React = require('react');
7
7
  var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
8
8
  var Avatar = require('../Avatar-76a799fa.js');
9
- var InputFile = require('../InputFile-271f6d31.js');
9
+ var InputFile = require('../InputFile-8767b7fd.js');
10
10
  var ProgressBar = require('../ProgressBar-b68edc8f.js');
11
11
  var Button = require('../Button-b73a5e01.js');
12
12
  require('classnames');
@@ -16,8 +16,11 @@ require('@jobber/design');
16
16
  require('react-dropzone');
17
17
  require('axios');
18
18
  require('uuid');
19
- require('../Content-2ca1ffe1.js');
19
+ require('../InputValidation-a7a737f9.js');
20
+ require('framer-motion');
21
+ require('../Text-259af966.js');
20
22
  require('../Typography-c45bf216.js');
23
+ require('../Content-2ca1ffe1.js');
21
24
  require('react-router-dom');
22
25
 
23
26
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -1,4 +1,5 @@
1
1
  /// <reference types="react" />
2
+ import { FileError } from "react-dropzone";
2
3
  export interface FileUpload {
3
4
  /**
4
5
  * File Identifier
@@ -113,8 +114,16 @@ interface InputFileProps {
113
114
  * Upload event handler. Triggered on upload completion.
114
115
  */
115
116
  onUploadComplete?(file: FileUpload): void;
117
+ /**
118
+ * Upload event handler. Triggered on upload error.
119
+ */
120
+ onUploadError?(error: Error): void;
121
+ /**
122
+ * Pass a custom validator function that will be called when a file is dropped.
123
+ */
124
+ readonly validator?: <T extends File>(file: T) => FileError | FileError[] | null;
116
125
  }
117
- export declare function InputFile({ variation, size, buttonLabel: providedButtonLabel, allowMultiple, allowedTypes, getUploadParams, onUploadStart, onUploadProgress, onUploadComplete, }: InputFileProps): JSX.Element;
126
+ export declare function InputFile({ variation, size, buttonLabel: providedButtonLabel, allowMultiple, allowedTypes, getUploadParams, onUploadStart, onUploadProgress, onUploadComplete, onUploadError, validator, }: InputFileProps): JSX.Element;
118
127
  /**
119
128
  * Upsert a given `FileUpload` into an array of `FileUpload`s.
120
129
  * `key` is used to uniquely identify files.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var InputFile = require('../InputFile-271f6d31.js');
5
+ var InputFile = require('../InputFile-8767b7fd.js');
6
6
  require('../tslib.es6-5b8768b7.js');
7
7
  require('react');
8
8
  require('classnames');
@@ -10,11 +10,14 @@ require('react-dropzone');
10
10
  require('axios');
11
11
  require('uuid');
12
12
  require('../style-inject.es-9d2f5f4e.js');
13
- require('../Button-b73a5e01.js');
14
- require('react-router-dom');
13
+ require('../InputValidation-a7a737f9.js');
14
+ require('framer-motion');
15
+ require('../Text-259af966.js');
16
+ require('../Typography-c45bf216.js');
15
17
  require('../Icon-405a216c.js');
16
18
  require('@jobber/design');
17
- require('../Typography-c45bf216.js');
19
+ require('../Button-b73a5e01.js');
20
+ require('react-router-dom');
18
21
  require('../Content-2ca1ffe1.js');
19
22
 
20
23
 
@@ -7,6 +7,7 @@ var reactDropzone = require('react-dropzone');
7
7
  var axios = require('axios');
8
8
  var uuid = require('uuid');
9
9
  var styleInject_es = require('./style-inject.es-9d2f5f4e.js');
10
+ var InputValidation = require('./InputValidation-a7a737f9.js');
10
11
  var Button = require('./Button-b73a5e01.js');
11
12
  var Content = require('./Content-2ca1ffe1.js');
12
13
  var Typography = require('./Typography-c45bf216.js');
@@ -17,14 +18,15 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
17
18
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
18
19
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
19
20
 
20
- var css_248z = ".grljXfTWj84- {\n font-size: 0;\n line-height: 0;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n cursor: pointer;\n}\n\n.grljXfTWj84-:focus,\n.grljXfTWj84-:focus-within {\n border-color: rgb(147, 161, 169);\n border-color: var(--color-focus);\n outline: none;\n}\n\n.WHhHWgaoXk4- {\n padding: calc(16px * 1);\n padding: var(--space-base);\n border: rgb(217, 223, 225) dashed calc(16px / 8);\n border: var(--color-border) dashed var(--border-thick);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n text-align: center;\n}\n\n.WHhHWgaoXk4-.n1h-T2metRA- {\n border-color: rgb(147, 161, 169);\n border-color: var(--color-focus);\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n}\n";
21
- var styles = {"dropZoneBase":"grljXfTWj84-","dropZone":"WHhHWgaoXk4-","active":"n1h-T2metRA-"};
21
+ var css_248z = ".grljXfTWj84- {\n font-size: 0;\n line-height: 0;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n cursor: pointer;\n}\n\n.grljXfTWj84-:focus,\n.grljXfTWj84-:focus-within {\n border-color: rgb(147, 161, 169);\n border-color: var(--color-focus);\n outline: none;\n}\n\n.WHhHWgaoXk4- {\n padding: calc(16px * 1);\n padding: var(--space-base);\n border: rgb(217, 223, 225) dashed calc(16px / 8);\n border: var(--color-border) dashed var(--border-thick);\n border-radius: calc(16px / 2);\n border-radius: var(--radius-larger);\n text-align: center;\n}\n\n.WHhHWgaoXk4-.n1h-T2metRA- {\n border-color: rgb(147, 161, 169);\n border-color: var(--color-focus);\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n}\n\n.WHhHWgaoXk4-.MRRclAp51-w- {\n border-color: rgb(201, 66, 33);\n border-color: var(--color-critical);\n}\n\n.TIbSRNvDK10- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-direction: column;\n flex-direction: column;\n}\n";
22
+ var styles = {"dropZoneBase":"grljXfTWj84-","dropZone":"WHhHWgaoXk4-","active":"n1h-T2metRA-","error":"MRRclAp51-w-","validationErrors":"TIbSRNvDK10-"};
22
23
  styleInject_es.styleInject(css_248z);
23
24
 
24
- function InputFile({ variation = "dropzone", size = "base", buttonLabel: providedButtonLabel, allowMultiple = false, allowedTypes = "all", getUploadParams, onUploadStart, onUploadProgress, onUploadComplete, }) {
25
+ function InputFile({ variation = "dropzone", size = "base", buttonLabel: providedButtonLabel, allowMultiple = false, allowedTypes = "all", getUploadParams, onUploadStart, onUploadProgress, onUploadComplete, onUploadError, validator, }) {
25
26
  const options = {
26
27
  multiple: allowMultiple,
27
28
  onDrop: React.useCallback(handleDrop, [uploadFile]),
29
+ validator: validator && React.useCallback(validator, []),
28
30
  };
29
31
  if (allowedTypes === "images") {
30
32
  options.accept = "image/*";
@@ -35,18 +37,26 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
35
37
  else if (Array.isArray(allowedTypes)) {
36
38
  options.accept = allowedTypes.join(",");
37
39
  }
38
- const { getRootProps, getInputProps, isDragActive } = reactDropzone.useDropzone(options);
40
+ const { getRootProps, getInputProps, isDragActive, fileRejections } = reactDropzone.useDropzone(options);
41
+ const validationErrors = fileRejections === null || fileRejections === void 0 ? void 0 : fileRejections.map(({ file, errors }) => {
42
+ return errors.map(error => {
43
+ return (React__default["default"].createElement(InputValidation.InputValidation, { message: `${file.name} ${error.message}`, key: `${file.name}${error.code}` }));
44
+ });
45
+ });
39
46
  const { buttonLabel, hintText } = getLabels(providedButtonLabel, allowMultiple, allowedTypes);
40
47
  const dropZone = classnames__default["default"](styles.dropZoneBase, {
41
48
  [styles.dropZone]: variation === "dropzone",
42
49
  [styles.active]: isDragActive,
50
+ [styles.error]: (fileRejections === null || fileRejections === void 0 ? void 0 : fileRejections.length) > 0,
43
51
  });
44
- return (React__default["default"].createElement("div", Object.assign({}, getRootProps({ className: dropZone }), { tabIndex: variation === "button" ? -1 : 0 }),
45
- React__default["default"].createElement("input", Object.assign({}, getInputProps())),
46
- variation === "dropzone" && (React__default["default"].createElement(Content.Content, { spacing: "small" },
47
- React__default["default"].createElement(Button.Button, { label: buttonLabel, size: "small", type: "secondary" }),
48
- size === "base" && (React__default["default"].createElement(Typography.Typography, { size: "small", textColor: "textSecondary" }, hintText)))),
49
- variation === "button" && (React__default["default"].createElement(Button.Button, { label: buttonLabel, size: size, type: "secondary", fullWidth: true }))));
52
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
53
+ React__default["default"].createElement("div", Object.assign({}, getRootProps({ className: dropZone }), { tabIndex: variation === "button" ? -1 : 0 }),
54
+ React__default["default"].createElement("input", Object.assign({}, getInputProps())),
55
+ variation === "dropzone" && (React__default["default"].createElement(Content.Content, { spacing: "small" },
56
+ React__default["default"].createElement(Button.Button, { label: buttonLabel, size: "small", type: "secondary" }),
57
+ size === "base" && (React__default["default"].createElement(Typography.Typography, { size: "small", textColor: "textSecondary" }, hintText)))),
58
+ variation === "button" && (React__default["default"].createElement(Button.Button, { label: buttonLabel, size: size, type: "secondary", fullWidth: true }))),
59
+ (fileRejections === null || fileRejections === void 0 ? void 0 : fileRejections.length) > 0 && (React__default["default"].createElement("div", { className: styles.validationErrors }, validationErrors))));
50
60
  function handleDrop(acceptedFiles) {
51
61
  acceptedFiles.forEach(file => {
52
62
  uploadFile(file);
@@ -54,7 +64,15 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
54
64
  }
55
65
  function uploadFile(file) {
56
66
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
57
- const { url, key = uuid.v1(), fields = {}, httpMethod = "POST", } = yield getUploadParams(file);
67
+ let params;
68
+ try {
69
+ params = yield getUploadParams(file);
70
+ }
71
+ catch (_a) {
72
+ onUploadError && onUploadError(new Error("Failed to get upload params"));
73
+ return;
74
+ }
75
+ const { url, key = uuid.v1(), fields = {}, httpMethod = "POST" } = params;
58
76
  const fileUpload = getFileUpload(file, key, url);
59
77
  onUploadStart && onUploadStart(Object.assign({}, fileUpload));
60
78
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -72,7 +90,12 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
72
90
  file,
73
91
  handleUploadProgress,
74
92
  });
75
- axios__default["default"].request(axiosConfig).then(handleUploadComplete);
93
+ axios__default["default"]
94
+ .request(axiosConfig)
95
+ .then(handleUploadComplete)
96
+ .catch(() => {
97
+ onUploadError && onUploadError(new Error("Failed to upload file"));
98
+ });
76
99
  });
77
100
  }
78
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "4.71.8",
3
+ "version": "4.72.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -83,5 +83,5 @@
83
83
  "> 1%",
84
84
  "IE 10"
85
85
  ],
86
- "gitHead": "0c486c394963e801f8fac71487ae9e3f7d788370"
86
+ "gitHead": "58a975b16f769405c26ebad6b5b8d8e699edbd04"
87
87
  }