@jobber/components 4.69.2 → 4.69.3-JOB-84091.16

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.
Files changed (41) hide show
  1. package/dist/Autocomplete/index.js +2 -2
  2. package/dist/Banner/index.js +11 -11
  3. package/dist/Button/Button.d.ts +3 -2
  4. package/dist/Card/index.js +2 -2
  5. package/dist/{Card-644dd256.js → Card-426a68a8.js} +2 -2
  6. package/dist/DataDump/index.js +2 -2
  7. package/dist/DataList/DataList.types.d.ts +8 -1
  8. package/dist/DataList/components/DataListHeaderTile/DataListHeaderTile.d.ts +2 -1
  9. package/dist/DataList/components/DataListHeaderTile/components/DataListSortingOptions.d.ts +12 -0
  10. package/dist/DataList/components/DataListHeaderTile/components/index.d.ts +1 -0
  11. package/dist/DataList/index.js +145 -83
  12. package/dist/DataTable/index.js +6 -5
  13. package/dist/FormField/FormFieldTypes.d.ts +1 -0
  14. package/dist/FormField/index.js +1 -1
  15. package/dist/{FormField-a332b2a6.js → FormField-b0e74d32.js} +2 -2
  16. package/dist/FormatFile/index.js +1 -1
  17. package/dist/{FormatFile-aae6c6e2.js → FormatFile-cc949eaf.js} +43 -2
  18. package/dist/Gallery/index.js +1 -1
  19. package/dist/InputAvatar/index.js +5 -2
  20. package/dist/InputDate/index.js +1 -1
  21. package/dist/InputEmail/index.js +1 -1
  22. package/dist/InputFile/InputFile.d.ts +12 -2
  23. package/dist/InputFile/index.js +7 -4
  24. package/dist/{InputFile-65bfbd78.js → InputFile-8767b7fd.js} +39 -13
  25. package/dist/InputNumber/index.js +2 -2
  26. package/dist/{InputNumber-3f5d3f8d.js → InputNumber-79da1cdc.js} +1 -1
  27. package/dist/InputPassword/index.js +1 -1
  28. package/dist/InputPhoneNumber/index.js +1 -1
  29. package/dist/InputText/index.js +2 -2
  30. package/dist/{InputText-e2d4ac19.js → InputText-9e61365c.js} +1 -1
  31. package/dist/InputTime/hooks/useTimePredict.d.ts +8 -0
  32. package/dist/InputTime/index.js +160 -5
  33. package/dist/Menu/index.js +1 -1
  34. package/dist/{Menu-da5d8217.js → Menu-81b12936.js} +1 -1
  35. package/dist/{Option-e5274cd8.js → Option-b715f6b4.js} +1 -1
  36. package/dist/Page/index.js +1 -1
  37. package/dist/RecurringSelect/index.js +3 -3
  38. package/dist/Select/index.js +2 -2
  39. package/dist/Toast/index.js +1 -1
  40. package/dist/utils/getClientBrowser.d.ts +7 -0
  41. package/package.json +3 -3
@@ -53,11 +53,52 @@ function InternalThumbnailImage({ file }) {
53
53
  }
54
54
  }
55
55
 
56
+ // This function comes from MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator
57
+ function getClientBrowser(userAgent) {
58
+ // The order matters here, and this may report false positives for unlisted browsers.
59
+ if (userAgent.includes("Firefox")) {
60
+ // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
61
+ return "Mozilla Firefox";
62
+ }
63
+ else if (userAgent.includes("SamsungBrowser")) {
64
+ // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
65
+ return "Samsung Internet";
66
+ }
67
+ else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
68
+ // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
69
+ return "Opera";
70
+ }
71
+ else if (userAgent.includes("Edge")) {
72
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
73
+ return "Microsoft Edge (Legacy)";
74
+ }
75
+ else if (userAgent.includes("Edg")) {
76
+ // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
77
+ return "Microsoft Edge (Chromium)";
78
+ }
79
+ else if (userAgent.includes("Chrome")) {
80
+ // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
81
+ return "Google Chrome or Chromium";
82
+ }
83
+ else if (userAgent.includes("Safari")) {
84
+ // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
85
+ return "Apple Safari";
86
+ }
87
+ else {
88
+ return "unknown";
89
+ }
90
+ }
91
+ function isSafari(userAgent) {
92
+ return getClientBrowser(userAgent) === "Apple Safari";
93
+ }
94
+
56
95
  function InternalThumbnail({ compact = false, size, file, }) {
57
96
  const { name, type } = file;
58
97
  const iconName = getIconNameFromType(type);
59
98
  const hasName = Boolean(name) && compact;
60
- if (type.startsWith("image/")) {
99
+ const nonHeicImage = !type.startsWith("image/heic");
100
+ const userAgent = typeof document === "undefined" ? "" : window.navigator.userAgent;
101
+ if (type.startsWith("image/") && (nonHeicImage || isSafari(userAgent))) {
61
102
  return React__default["default"].createElement(InternalThumbnailImage, { file: file });
62
103
  }
63
104
  return (React__default["default"].createElement("div", { className: classnames__default["default"](styles$1.content, styles$1[size], {
@@ -69,7 +110,7 @@ function InternalThumbnail({ compact = false, size, file, }) {
69
110
  }
70
111
  function getIconNameFromType(mimeType) {
71
112
  if (mimeType.startsWith("image/"))
72
- return "camera";
113
+ return "image";
73
114
  if (mimeType.startsWith("video/"))
74
115
  return "video";
75
116
  switch (mimeType) {
@@ -6,7 +6,7 @@ var React = require('react');
6
6
  var classnames = require('classnames');
7
7
  var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
8
8
  var LightBox = require('../LightBox-a89d8863.js');
9
- var FormatFile = require('../FormatFile-aae6c6e2.js');
9
+ var FormatFile = require('../FormatFile-cc949eaf.js');
10
10
  var Button = require('../Button-b73a5e01.js');
11
11
  require('framer-motion');
12
12
  require('react-dom');
@@ -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-65bfbd78.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 }; }
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var omit = require('lodash/omit');
6
6
  var React = require('react');
7
- var FormField = require('../FormField-a332b2a6.js');
7
+ var FormField = require('../FormField-b0e74d32.js');
8
8
  var DatePicker = require('../DatePicker-64c5ab1a.js');
9
9
  require('../tslib.es6-5b8768b7.js');
10
10
  require('uuid');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
- var FormField = require('../FormField-a332b2a6.js');
6
+ var FormField = require('../FormField-b0e74d32.js');
7
7
  require('../tslib.es6-5b8768b7.js');
8
8
  require('uuid');
9
9
  require('react-hook-form');
@@ -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
@@ -82,10 +83,11 @@ interface InputFileProps {
82
83
  *
83
84
  * @param "images" - only accepts all types of image
84
85
  * @param "basicImages" - only accepts png, jpg and jpeg
86
+ * @param "string[]" - accept a specific list of MIME types
85
87
  *
86
88
  * @default "all"
87
89
  */
88
- readonly allowedTypes?: "all" | "images" | "basicImages";
90
+ readonly allowedTypes?: "all" | "images" | "basicImages" | string[];
89
91
  /**
90
92
  * Allow for multiple files to be selected for upload.
91
93
  *
@@ -112,8 +114,16 @@ interface InputFileProps {
112
114
  * Upload event handler. Triggered on upload completion.
113
115
  */
114
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;
115
125
  }
116
- 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;
117
127
  /**
118
128
  * Upsert a given `FileUpload` into an array of `FileUpload`s.
119
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-65bfbd78.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
- onDrop: React.useCallback(handleDrop, []),
28
+ onDrop: React.useCallback(handleDrop, [uploadFile]),
29
+ validator: validator && React.useCallback(validator, []),
28
30
  };
29
31
  if (allowedTypes === "images") {
30
32
  options.accept = "image/*";
@@ -32,18 +34,29 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
32
34
  else if (allowedTypes === "basicImages") {
33
35
  options.accept = "image/png, image/jpg, image/jpeg";
34
36
  }
35
- const { getRootProps, getInputProps, isDragActive } = reactDropzone.useDropzone(options);
37
+ else if (Array.isArray(allowedTypes)) {
38
+ options.accept = allowedTypes.join(",");
39
+ }
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
+ });
36
46
  const { buttonLabel, hintText } = getLabels(providedButtonLabel, allowMultiple, allowedTypes);
37
47
  const dropZone = classnames__default["default"](styles.dropZoneBase, {
38
48
  [styles.dropZone]: variation === "dropzone",
39
49
  [styles.active]: isDragActive,
50
+ [styles.error]: (fileRejections === null || fileRejections === void 0 ? void 0 : fileRejections.length) > 0,
40
51
  });
41
- return (React__default["default"].createElement("div", Object.assign({}, getRootProps({ className: dropZone }), { tabIndex: variation === "button" ? -1 : 0 }),
42
- React__default["default"].createElement("input", Object.assign({}, getInputProps())),
43
- variation === "dropzone" && (React__default["default"].createElement(Content.Content, { spacing: "small" },
44
- React__default["default"].createElement(Button.Button, { label: buttonLabel, size: "small", type: "secondary" }),
45
- size === "base" && (React__default["default"].createElement(Typography.Typography, { size: "small", textColor: "textSecondary" }, hintText)))),
46
- 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))));
47
60
  function handleDrop(acceptedFiles) {
48
61
  acceptedFiles.forEach(file => {
49
62
  uploadFile(file);
@@ -51,7 +64,15 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
51
64
  }
52
65
  function uploadFile(file) {
53
66
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
54
- 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;
55
76
  const fileUpload = getFileUpload(file, key, url);
56
77
  onUploadStart && onUploadStart(Object.assign({}, fileUpload));
57
78
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -69,7 +90,12 @@ function InputFile({ variation = "dropzone", size = "base", buttonLabel: provide
69
90
  file,
70
91
  handleUploadProgress,
71
92
  });
72
- 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
+ });
73
99
  });
74
100
  }
75
101
  }
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var InputNumber = require('../InputNumber-3f5d3f8d.js');
5
+ var InputNumber = require('../InputNumber-79da1cdc.js');
6
6
  require('react');
7
- require('../FormField-a332b2a6.js');
7
+ require('../FormField-b0e74d32.js');
8
8
  require('../tslib.es6-5b8768b7.js');
9
9
  require('uuid');
10
10
  require('react-hook-form');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
- var FormField = require('./FormField-a332b2a6.js');
4
+ var FormField = require('./FormField-b0e74d32.js');
5
5
 
6
6
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
7
 
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var React = require('react');
6
- var FormField = require('../FormField-a332b2a6.js');
6
+ var FormField = require('../FormField-b0e74d32.js');
7
7
  require('../tslib.es6-5b8768b7.js');
8
8
  require('uuid');
9
9
  require('react-hook-form');
@@ -6,7 +6,7 @@ var tslib_es6 = require('../tslib.es6-5b8768b7.js');
6
6
  var React = require('react');
7
7
  var reactHookForm = require('react-hook-form');
8
8
  var styleInject_es = require('../style-inject.es-9d2f5f4e.js');
9
- var FormField = require('../FormField-a332b2a6.js');
9
+ var FormField = require('../FormField-b0e74d32.js');
10
10
  require('uuid');
11
11
  require('classnames');
12
12
  require('@jobber/hooks/useShowClear');
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var InputText = require('../InputText-e2d4ac19.js');
5
+ var InputText = require('../InputText-9e61365c.js');
6
6
  require('react');
7
- require('../FormField-a332b2a6.js');
7
+ require('../FormField-b0e74d32.js');
8
8
  require('../tslib.es6-5b8768b7.js');
9
9
  require('uuid');
10
10
  require('react-hook-form');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
- var FormField = require('./FormField-a332b2a6.js');
4
+ var FormField = require('./FormField-b0e74d32.js');
5
5
 
6
6
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
7
 
@@ -0,0 +1,8 @@
1
+ import { InputTimeProps } from "../InputTimeProps";
2
+ interface UseTimePredictProps extends Pick<InputTimeProps, "value"> {
3
+ readonly handleChange: (value: string) => void;
4
+ }
5
+ export declare function useTimePredict({ value, handleChange }: UseTimePredictProps): {
6
+ setTypedTime: import("react").Dispatch<import("react").SetStateAction<string>>;
7
+ };
8
+ export {};
@@ -6,7 +6,7 @@ var tslib_es6 = require('../tslib.es6-5b8768b7.js');
6
6
  var React = require('react');
7
7
  var debounce = require('lodash/debounce');
8
8
  var temporal = require('@std-proposal/temporal');
9
- var FormField = require('../FormField-a332b2a6.js');
9
+ var FormField = require('../FormField-b0e74d32.js');
10
10
  require('uuid');
11
11
  require('react-hook-form');
12
12
  require('../style-inject.es-9d2f5f4e.js');
@@ -786,18 +786,173 @@ function InputTimeSafari(_a) {
786
786
  }
787
787
  }
788
788
 
789
+ const DEBOUNCE_TIME = 300;
790
+ function useTimePredict({ value, handleChange }) {
791
+ const IS_12_HOUR_FORMAT = React.useRef(Intl.DateTimeFormat(navigator.language, {
792
+ hour: "numeric",
793
+ }).resolvedOptions().hour12);
794
+ const [typedTime, setTypedTime] = React.useState("");
795
+ const predictTime = React.useCallback(debounce__default["default"](() => {
796
+ if (value)
797
+ return;
798
+ handleChange(predictHours(typedTime, IS_12_HOUR_FORMAT.current));
799
+ }, DEBOUNCE_TIME), [typedTime, value, handleChange]);
800
+ /**
801
+ * Predict the hour when user types a number
802
+ */
803
+ React.useEffect(() => {
804
+ /**
805
+ * Don't try to predict if the user types 0 as the user would almost always
806
+ * type another number after 0.
807
+ */
808
+ if (typedTime && typedTime !== "0") {
809
+ predictTime();
810
+ if ((IS_12_HOUR_FORMAT && typedTime !== "1") || typedTime.length === 2) {
811
+ // Immediately predict the hour
812
+ predictTime.flush();
813
+ }
814
+ }
815
+ return predictTime.cancel;
816
+ }, [typedTime]);
817
+ /**
818
+ * Reset typed time when the value changed
819
+ */
820
+ React.useEffect(() => {
821
+ setTypedTime("");
822
+ }, [value]);
823
+ return {
824
+ setTypedTime,
825
+ };
826
+ }
827
+ function predictHours(time, is12HourFormat = false) {
828
+ const today = new Date();
829
+ const currentHour = today.getHours();
830
+ const parsedTime = parseInt(time, 10);
831
+ let predictedTime;
832
+ if (is12HourFormat) {
833
+ predictedTime = predict12Hours(parsedTime, currentHour);
834
+ }
835
+ else {
836
+ predictedTime = predict24Hours(time, parsedTime, currentHour);
837
+ }
838
+ return formatHour(predictedTime);
839
+ }
840
+ function predict12Hours(parsedTime, currentHour) {
841
+ /**
842
+ * We need to predict what the user wants when they type 1 since it could be
843
+ * 10, 11, 12, or 1.
844
+ *
845
+ * If the current hour is over 12PM, we can skip this and go to the next logic.
846
+ */
847
+ if (parsedTime === 1 && currentHour < 12) {
848
+ if (currentHour < 10) {
849
+ return 10;
850
+ }
851
+ else {
852
+ return currentHour + 1;
853
+ }
854
+ }
855
+ /**
856
+ * Typing 1-5 predicts that the user want that exact hour on the afternoon.
857
+ */
858
+ if (parsedTime <= 5) {
859
+ return parsedTime + 12;
860
+ }
861
+ /**
862
+ * Typing 13-15 predicts that the user want the 2nd number as the minute interval.
863
+ */
864
+ if (parsedTime > 12 && parsedTime <= 15) {
865
+ const timeArray = parsedTime.toString().split("").map(Number); // 13 -> [1, 3]
866
+ const convertToHoursAndMinutes = timeArray.map((time, i) => {
867
+ if (i === 0)
868
+ return time + 12; // 1 -> 13 as 1PM
869
+ if (i === 1)
870
+ return time * 10; // 3 -> 30 as 30 minutes
871
+ });
872
+ return Number(convertToHoursAndMinutes.join("")); // [13, 30] -> 1330
873
+ }
874
+ /**
875
+ * Anything after 5 will be predicted to be set as AM.
876
+ */
877
+ return parsedTime;
878
+ }
879
+ function predict24Hours(time, parsedTime, currentHour) {
880
+ /**
881
+ * Typing 1 could be predicted from 10 to 19.
882
+ * Typing 01 skips this logic and sets the time to 01:00.
883
+ */
884
+ if (parsedTime === 1 && time !== "01") {
885
+ if (currentHour < 10 || currentHour > 19) {
886
+ return 10;
887
+ }
888
+ else {
889
+ return currentHour + 1;
890
+ }
891
+ }
892
+ /**
893
+ * Typing 2 could be predicted from 20 to 24.
894
+ * Typing 02 skips this logic and sets the time to 02:00.
895
+ */
896
+ if (parsedTime === 2 && time !== "02") {
897
+ if (currentHour < 20) {
898
+ return 20;
899
+ }
900
+ else {
901
+ return currentHour + 1;
902
+ }
903
+ }
904
+ /**
905
+ * Typing 24 or 00 is set to midnight. This ensures the time doesn't get set
906
+ * to 24 as that would be invalid.
907
+ */
908
+ if (parsedTime === 24 || time === "00") {
909
+ return 0;
910
+ }
911
+ return parsedTime;
912
+ }
913
+ function formatHour(time) {
914
+ if (time > 99) {
915
+ const splitTime = time.toString().split("");
916
+ if (splitTime.length === 3)
917
+ splitTime.unshift("0"); // 130 -> 0130
918
+ splitTime.splice(2, 0, ":"); // 0130 -> 01:30
919
+ return splitTime.join("");
920
+ }
921
+ if (time < 10) {
922
+ return `0${time}:00`;
923
+ }
924
+ return `${time}:00`;
925
+ }
926
+
789
927
  function InputTime(_a) {
790
928
  var { defaultValue, value, onChange } = _a, params = tslib_es6.__rest(_a, ["defaultValue", "value", "onChange"]);
791
- const handleChange = (newValue) => {
792
- onChange && onChange(htmlTimeToCivilTime(newValue));
793
- };
929
+ const ref = React.useRef(null);
930
+ const { setTypedTime } = useTimePredict({ value, handleChange });
794
931
  if (supportsTime) {
795
932
  const fieldProps = Object.assign(Object.assign(Object.assign({ onChange: handleChange }, (defaultValue && { defaultValue: civilTimeToHTMLTime(defaultValue) })), (!defaultValue && { value: civilTimeToHTMLTime(value) })), params);
796
- return React__default["default"].createElement(FormField.FormField, Object.assign({ type: "time" }, fieldProps));
933
+ return (React__default["default"].createElement(FormField.FormField, Object.assign({ inputRef: ref, type: "time" }, fieldProps, { onBlur: handleBlur, onKeyUp: e => {
934
+ var _a;
935
+ (_a = fieldProps.onKeyUp) === null || _a === void 0 ? void 0 : _a.call(fieldProps, e);
936
+ !isNaN(parseInt(e.key, 10)) && setTypedTime(prev => prev + e.key);
937
+ } })));
797
938
  }
798
939
  else {
799
940
  return (React__default["default"].createElement(InputTimeSafari, Object.assign({ defaultValue: defaultValue, value: value, onChange: onChange }, params)));
800
941
  }
942
+ function handleChange(newValue) {
943
+ onChange === null || onChange === void 0 ? void 0 : onChange(htmlTimeToCivilTime(newValue));
944
+ }
945
+ function handleBlur() {
946
+ var _a;
947
+ (_a = params.onBlur) === null || _a === void 0 ? void 0 : _a.call(params);
948
+ // Time inputs doesn't clear the typed value when it's invalid. This should
949
+ // force it to reset the input value when the typed value is invalid.
950
+ if (ref.current) {
951
+ if (!ref.current.checkValidity()) {
952
+ ref.current.value = "";
953
+ }
954
+ }
955
+ }
801
956
  }
802
957
 
803
958
  exports.InputTime = InputTime;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var Menu = require('../Menu-da5d8217.js');
5
+ var Menu = require('../Menu-81b12936.js');
6
6
  require('react');
7
7
  require('uuid');
8
8
  require('classnames');
@@ -16,7 +16,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
16
16
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
17
17
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
18
18
 
19
- var css_248z = ".dT6M9tp1sZc- * {\n box-sizing: border-box;\n}\n\n.dT6M9tp1sZc- {\n --menu-space: var(--space-small);\n --menu-offset: var(--space-smallest);\n display: inline-block;\n position: relative;\n}\n\n.Qmxlsj0D3qM- {\n position: fixed;\n bottom: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n width: 100%;\n max-height: 72vh;\n padding: var(--menu-space);\n padding-bottom: calc(env(safe-area-inset-bottom) + var(--menu-space));\n border-radius: calc(16px / 8) calc(16px / 8) 0 0;\n border-radius: var(--radius-base) var(--radius-base) 0 0;\n -webkit-overflow-scrolling: touch;\n overflow-y: scroll;\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n@media (min-width: 490px) {\n\n.Qmxlsj0D3qM- {\n position: absolute;\n left: auto;\n width: calc(16px * 12.5);\n width: calc(var(--base-unit) * 12.5);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n padding: var(--menu-space);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n overflow: auto;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.Qmxlsj0D3qM- {\n position: absolute;\n left: auto;\n width: calc(16px * 12.5);\n width: calc(var(--base-unit) * 12.5);\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n padding: var(--menu-space);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n overflow: auto;\n}\n }\n\n@media (min-width: 490px) {\n\n.QTisUfiHwL4- {\n bottom: 100%;\n margin-bottom: var(--menu-offset);\n}\n }\n\n@media (--small-screens-and-up) {\n\n.QTisUfiHwL4- {\n bottom: 100%;\n margin-bottom: var(--menu-offset);\n}\n }\n\n@media (min-width: 490px) {\n\n.qsch1dlpOHc- {\n top: 100%;\n bottom: auto;\n margin-top: var(--menu-offset);\n}\n }\n\n@media (--small-screens-and-up) {\n\n.qsch1dlpOHc- {\n top: 100%;\n bottom: auto;\n margin-top: var(--menu-offset);\n}\n }\n\n@media (min-width: 490px) {\n\n._0xR9-oxWMOU- {\n right: 0;\n left: auto;\n}\n }\n\n@media (--small-screens-and-up) {\n\n._0xR9-oxWMOU- {\n right: 0;\n left: auto;\n}\n }\n\n@media (min-width: 490px) {\n\n.gaZwsdyoG0k- {\n right: auto;\n left: 0;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.gaZwsdyoG0k- {\n right: auto;\n left: 0;\n}\n }\n\n.LaKFjYCLHZc- {\n padding: var(--menu-space) 0;\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\n}\n\n.LaKFjYCLHZc-:first-of-type {\n padding-top: 0;\n}\n\n.LaKFjYCLHZc-:last-of-type {\n padding-bottom: 0;\n border-bottom: none;\n}\n\n._7HB7dWnqCi0- {\n padding: var(--menu-space);\n}\n\n.jobber-retheme ._7HB7dWnqCi0- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: calc(var(--menu-space) * 1.5) var(--menu-space);\n}\n\n.jobber-retheme ._7HB7dWnqCi0- h6 {\n /* can move into the Typography component post re-theme */\n font-size: calc((16px * 1) * 0.875);\n font-size: calc(calc(16px * 1) * 0.875);\n font-size: var(--typography--fontSize-base);\n font-weight: 400;\n text-transform: none;\n}\n\n.ZuceCiefKqw- {\n display: -ms-flexbox;\n display: flex;\n gap: calc(16px * 1);\n gap: var(--space-base);\n width: 100%;\n padding: var(--menu-space);\n border: none;\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n background-color: transparent;\n cursor: pointer;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.jobber-retheme .ZuceCiefKqw- {\n gap: var(--menu-space);\n}\n\n.ZuceCiefKqw-:hover,\n.ZuceCiefKqw-:focus-visible {\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n outline-color: rgb(147, 161, 169);\n outline-color: var(--color-focus);\n}\n\n.jobber-retheme .ZuceCiefKqw- span {\n /* can move into the Typography component post re-theme */\n color: rgb(77, 105, 116);\n color: var(--color-text--secondary);\n font-weight: 600;\n}\n\n.jobber-retheme .Bz8TONF8kws- path {\n /* can move into the Icon component post re-theme */\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n}\n\n.eKnUAucwwWU- {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n background-color: rgba(0, 0, 0, 0.32);\n background-color: var(--color-overlay);\n}\n\n@media (min-width: 490px) {\n\n.eKnUAucwwWU- {\n background-color: transparent;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.eKnUAucwwWU- {\n background-color: transparent;\n}\n }\n\n.oaxefr58z-E- {\n width: 100%;\n}\n\n.vz9opIdwHFg- {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n";
19
+ var css_248z = ".dT6M9tp1sZc- * {\n box-sizing: border-box;\n}\n\n.dT6M9tp1sZc- {\n --menu-space: var(--space-small);\n --menu-offset: var(--space-smallest);\n display: inline-block;\n position: relative;\n}\n\n.Qmxlsj0D3qM- {\n position: fixed;\n bottom: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n width: 100%;\n max-height: 72vh;\n box-shadow: 0px calc(16px / 16) calc(16px / 4) 0px\n rgba(0, 0, 0, 0.1),\n 0px calc(16px / 4) 12px 0px rgba(0, 0, 0, 0.05);\n box-shadow: var(--shadow-base);\n padding: var(--menu-space);\n padding-bottom: calc(env(safe-area-inset-bottom) + var(--menu-space));\n border-radius: calc(16px / 8) calc(16px / 8) 0 0;\n border-radius: var(--radius-base) var(--radius-base) 0 0;\n -webkit-overflow-scrolling: touch;\n overflow-y: scroll;\n background-color: rgba(255, 255, 255, 1);\n background-color: var(--color-surface);\n}\n\n@media (min-width: 490px) {\n\n.Qmxlsj0D3qM- {\n position: absolute;\n left: auto;\n width: calc(16px * 12.5);\n width: calc(var(--base-unit) * 12.5);\n padding: var(--menu-space);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n overflow: auto;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.Qmxlsj0D3qM- {\n position: absolute;\n left: auto;\n width: calc(16px * 12.5);\n width: calc(var(--base-unit) * 12.5);\n padding: var(--menu-space);\n border: calc(16px / 16) solid rgb(217, 223, 225);\n border: var(--border-base) solid var(--color-border);\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n overflow: auto;\n}\n }\n\n@media (min-width: 490px) {\n\n.QTisUfiHwL4- {\n bottom: 100%;\n margin-bottom: var(--menu-offset);\n}\n }\n\n@media (--small-screens-and-up) {\n\n.QTisUfiHwL4- {\n bottom: 100%;\n margin-bottom: var(--menu-offset);\n}\n }\n\n@media (min-width: 490px) {\n\n.qsch1dlpOHc- {\n top: 100%;\n bottom: auto;\n margin-top: var(--menu-offset);\n}\n }\n\n@media (--small-screens-and-up) {\n\n.qsch1dlpOHc- {\n top: 100%;\n bottom: auto;\n margin-top: var(--menu-offset);\n}\n }\n\n@media (min-width: 490px) {\n\n._0xR9-oxWMOU- {\n right: 0;\n left: auto;\n}\n }\n\n@media (--small-screens-and-up) {\n\n._0xR9-oxWMOU- {\n right: 0;\n left: auto;\n}\n }\n\n@media (min-width: 490px) {\n\n.gaZwsdyoG0k- {\n right: auto;\n left: 0;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.gaZwsdyoG0k- {\n right: auto;\n left: 0;\n}\n }\n\n.LaKFjYCLHZc- {\n padding: var(--menu-space) 0;\n border-bottom: calc(16px / 16) solid rgb(217, 223, 225);\n border-bottom: var(--border-base) solid var(--color-border);\n}\n\n.LaKFjYCLHZc-:first-of-type {\n padding-top: 0;\n}\n\n.LaKFjYCLHZc-:last-of-type {\n padding-bottom: 0;\n border-bottom: none;\n}\n\n._7HB7dWnqCi0- {\n padding: var(--menu-space);\n}\n\n.jobber-retheme ._7HB7dWnqCi0- {\n display: -ms-flexbox;\n display: flex;\n -ms-flex-align: center;\n align-items: center;\n padding: calc(var(--menu-space) * 1.5) var(--menu-space);\n}\n\n.jobber-retheme ._7HB7dWnqCi0- h6 {\n /* can move into the Typography component post re-theme */\n font-size: calc((16px * 1) * 0.875);\n font-size: calc(calc(16px * 1) * 0.875);\n font-size: var(--typography--fontSize-base);\n font-weight: 400;\n text-transform: none;\n}\n\n.ZuceCiefKqw- {\n display: -ms-flexbox;\n display: flex;\n gap: calc(16px * 1);\n gap: var(--space-base);\n width: 100%;\n padding: var(--menu-space);\n border: none;\n border-radius: calc(16px / 8);\n border-radius: var(--radius-base);\n background-color: transparent;\n cursor: pointer;\n -ms-flex-align: center;\n align-items: center;\n}\n\n.jobber-retheme .ZuceCiefKqw- {\n gap: var(--menu-space);\n}\n\n.ZuceCiefKqw-:hover,\n.ZuceCiefKqw-:focus-visible {\n background-color: rgb(244, 246, 250);\n background-color: var(--color-surface--hover);\n outline-color: rgb(147, 161, 169);\n outline-color: var(--color-focus);\n}\n\n.jobber-retheme .ZuceCiefKqw- span {\n /* can move into the Typography component post re-theme */\n color: rgb(77, 105, 116);\n color: var(--color-text--secondary);\n font-weight: 600;\n}\n\n.jobber-retheme .Bz8TONF8kws- path {\n /* can move into the Icon component post re-theme */\n fill: rgba(101, 120, 132, 1);\n fill: var(--color-interactive--subtle);\n}\n\n.eKnUAucwwWU- {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 6;\n z-index: var(--elevation-menu);\n background-color: rgba(0, 0, 0, 0.32);\n background-color: var(--color-overlay);\n}\n\n@media (min-width: 490px) {\n\n.eKnUAucwwWU- {\n background-color: transparent;\n}\n }\n\n@media (--small-screens-and-up) {\n\n.eKnUAucwwWU- {\n background-color: transparent;\n}\n }\n\n.oaxefr58z-E- {\n width: 100%;\n}\n\n.vz9opIdwHFg- {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n}\n";
20
20
  var styles = {"wrapper":"dT6M9tp1sZc-","menu":"Qmxlsj0D3qM-","above":"QTisUfiHwL4-","below":"qsch1dlpOHc-","left":"_0xR9-oxWMOU-","right":"gaZwsdyoG0k-","section":"LaKFjYCLHZc-","sectionHeader":"_7HB7dWnqCi0-","action":"ZuceCiefKqw-","icon":"Bz8TONF8kws-","overlay":"eKnUAucwwWU-","fullWidth":"oaxefr58z-E-","screenReaderOnly":"vz9opIdwHFg-"};
21
21
  styleInject_es.styleInject(css_248z);
22
22
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
- var FormField = require('./FormField-a332b2a6.js');
4
+ var FormField = require('./FormField-b0e74d32.js');
5
5
 
6
6
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
7
 
@@ -11,7 +11,7 @@ var Text = require('../Text-259af966.js');
11
11
  var Content = require('../Content-2ca1ffe1.js');
12
12
  var Markdown = require('../Markdown-b80706ed.js');
13
13
  var Button = require('../Button-b73a5e01.js');
14
- var Menu = require('../Menu-da5d8217.js');
14
+ var Menu = require('../Menu-81b12936.js');
15
15
  var Emphasis = require('../Emphasis-bda56d3b.js');
16
16
  require('../Typography-c45bf216.js');
17
17
  require('../getAtlantisConfig-0f3e8af2.js');
@@ -9,11 +9,11 @@ var RadioGroup = require('../RadioGroup-ca7a5978.js');
9
9
  var Text = require('../Text-259af966.js');
10
10
  require('classnames');
11
11
  require('../Typography-c45bf216.js');
12
- var Option = require('../Option-e5274cd8.js');
13
- var InputNumber = require('../InputNumber-3f5d3f8d.js');
12
+ var Option = require('../Option-b715f6b4.js');
13
+ var InputNumber = require('../InputNumber-79da1cdc.js');
14
14
  var InputGroup = require('../InputGroup-8d4fd4eb.js');
15
15
  var Content = require('../Content-2ca1ffe1.js');
16
- require('../FormField-a332b2a6.js');
16
+ require('../FormField-b0e74d32.js');
17
17
  require('../tslib.es6-5b8768b7.js');
18
18
  require('react-hook-form');
19
19
  require('@jobber/hooks/useShowClear');
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var Option = require('../Option-e5274cd8.js');
5
+ var Option = require('../Option-b715f6b4.js');
6
6
  require('react');
7
- require('../FormField-a332b2a6.js');
7
+ require('../FormField-b0e74d32.js');
8
8
  require('../tslib.es6-5b8768b7.js');
9
9
  require('uuid');
10
10
  require('react-hook-form');