@spaced-out/ui-design-system 0.1.30 → 0.1.32

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 (51) hide show
  1. package/.cspell/custom-words.txt +5 -0
  2. package/.github/workflows/pages.yml +3 -0
  3. package/.github/workflows/publish_to_npm.yml +1 -1
  4. package/.github/workflows/pull_request_checks.yml +44 -0
  5. package/.github/workflows/pull_request_semantics_checker.yml +1 -0
  6. package/.storybook/preview-head.html +2 -2
  7. package/CHANGELOG.md +25 -0
  8. package/design-tokens/color/app-color.json +3 -0
  9. package/design-tokens/color/base-color.json +3 -0
  10. package/design-tokens/size/base-size.json +15 -0
  11. package/lib/components/Dialog/Dialog.module.css +1 -1
  12. package/lib/components/FileUpload/FileUpload.js +195 -0
  13. package/lib/components/FileUpload/FileUpload.js.flow +301 -0
  14. package/lib/components/FileUpload/FileUpload.module.css +186 -0
  15. package/lib/components/FileUpload/index.js +16 -0
  16. package/lib/components/FileUpload/index.js.flow +3 -0
  17. package/lib/components/Input/Input.js +2 -2
  18. package/lib/components/Input/Input.js.flow +11 -7
  19. package/lib/components/Input/Input.module.css +16 -5
  20. package/lib/components/LinearLoader/LinearLoader.js +10 -3
  21. package/lib/components/LinearLoader/LinearLoader.js.flow +15 -2
  22. package/lib/components/LinearLoader/LinearLoader.module.css +34 -1
  23. package/lib/components/Modal/Modal.js +3 -2
  24. package/lib/components/Modal/Modal.js.flow +10 -4
  25. package/lib/components/Modal/Modal.module.css +13 -1
  26. package/lib/components/Modal/index.js.flow +1 -0
  27. package/lib/components/Textarea/Textarea.js +2 -2
  28. package/lib/components/Textarea/Textarea.js.flow +10 -6
  29. package/lib/components/Textarea/Textarea.module.css +16 -6
  30. package/lib/components/index.js +11 -0
  31. package/lib/components/index.js.flow +1 -0
  32. package/lib/hooks/index.js +11 -0
  33. package/lib/hooks/index.js.flow +1 -0
  34. package/lib/hooks/useFileUpload/index.js +16 -0
  35. package/lib/hooks/useFileUpload/index.js.flow +3 -0
  36. package/lib/hooks/useFileUpload/useFileUpload.js +279 -0
  37. package/lib/hooks/useFileUpload/useFileUpload.js.flow +304 -0
  38. package/lib/styles/index.css +12 -0
  39. package/lib/styles/index.js +15 -3
  40. package/lib/styles/index.js.flow +12 -0
  41. package/lib/styles/variables/_color.css +2 -0
  42. package/lib/styles/variables/_color.js +3 -1
  43. package/lib/styles/variables/_color.js.flow +2 -0
  44. package/lib/styles/variables/_size.css +10 -0
  45. package/lib/styles/variables/_size.js +11 -1
  46. package/lib/styles/variables/_size.js.flow +10 -0
  47. package/lib/utils/helpers/helpers.js +39 -2
  48. package/lib/utils/helpers/helpers.js.flow +37 -0
  49. package/lib/utils/tokens/tokens.js +1 -2
  50. package/lib/utils/tokens/tokens.js.flow +1 -3
  51. package/package.json +3 -2
@@ -1,6 +1,7 @@
1
1
  @value (
2
2
  borderRadiusSmall
3
3
  ) from '../../styles/variables/_border.css';
4
+
4
5
  @value (colorFillPrimary, colorBorderPrimary) from '../../styles/variables/_color.css';
5
6
 
6
7
  @value (
@@ -11,10 +12,18 @@
11
12
  ) from '../../styles/variables/_size.css';
12
13
 
13
14
  @value (
14
- motionDurationSlow
15
+ motionDurationSlow,
16
+ motionDurationSlowest,
17
+ motionEaseInEaseOut
15
18
  ) from '../../styles/variables/_motion.css';
16
19
 
20
+ @value (
21
+ spaceNone,
22
+ spaceFluid
23
+ ) from '../../styles/variables/_space.css';
24
+
17
25
  .lineContainer {
26
+ position: relative;
18
27
  display: flex;
19
28
  justify-content: flex-start;
20
29
  align-items: center;
@@ -41,3 +50,27 @@
41
50
  height: sizeFluid;
42
51
  transition: motionDurationSlow;
43
52
  }
53
+
54
+ .indeterminate {
55
+ position: absolute;
56
+
57
+ animation: infiniteProgressBar calc(motionDurationSlowest * 3)
58
+ motionEaseInEaseOut;
59
+ animation-iteration-count: infinite;
60
+ animation-fill-mode: both;
61
+ }
62
+
63
+ @keyframes infiniteProgressBar {
64
+ 0% {
65
+ left: spaceNone;
66
+ width: spaceNone;
67
+ }
68
+ 50% {
69
+ left: spaceNone;
70
+ width: spaceFluid;
71
+ }
72
+ 100% {
73
+ left: spaceFluid;
74
+ width: spaceNone;
75
+ }
76
+ }
@@ -120,7 +120,8 @@ const Modal = _ref4 => {
120
120
  hideBackdrop = false,
121
121
  tapOutsideToClose = true,
122
122
  initialFocus = -1,
123
- customAnimation
123
+ customAnimation,
124
+ size = 'small'
124
125
  } = _ref4;
125
126
  const {
126
127
  refs,
@@ -213,7 +214,7 @@ const Modal = _ref4 => {
213
214
  }, classNames?.backdrop),
214
215
  onClick: onBackdropClick
215
216
  }), isMounted && /*#__PURE__*/React.createElement("div", {
216
- className: (0, _classify.default)(_ModalModule.default.modal, classNames?.content),
217
+ className: (0, _classify.default)(_ModalModule.default.modal, _ModalModule.default[size], classNames?.content),
217
218
  role: "dialog",
218
219
  style: {
219
220
  // Transition styles
@@ -51,13 +51,18 @@ export type ModalProps = {
51
51
  isOpen?: boolean,
52
52
  onClose?: ?(SyntheticEvent<HTMLElement>) => mixed,
53
53
  hideBackdrop?: boolean,
54
- // This prop is removed now
55
- removeWhenClosed?: boolean,
56
54
  tapOutsideToClose?: boolean,
57
55
  initialFocus?: number,
58
56
  customAnimation?: UseTransitionStylesProps,
59
57
  };
60
58
 
59
+ export type ModalSize = 'small' | 'medium' | 'large';
60
+
61
+ export type BaseModalProps = {
62
+ ...ModalProps,
63
+ size?: ModalSize,
64
+ };
65
+
61
66
  export type ModalHeaderProps = {
62
67
  children?: React.Node,
63
68
  hideCloseBtn?: boolean,
@@ -189,7 +194,8 @@ export const Modal = ({
189
194
  tapOutsideToClose = true,
190
195
  initialFocus = -1,
191
196
  customAnimation,
192
- }: ModalProps): React.Node => {
197
+ size = 'small',
198
+ }: BaseModalProps): React.Node => {
193
199
  const {refs, context} = useFloating({open: isOpen});
194
200
  const {isMounted, styles} = useTransitionStyles(
195
201
  context,
@@ -301,7 +307,7 @@ export const Modal = ({
301
307
  />
302
308
  {isMounted && (
303
309
  <div
304
- className={classify(css.modal, classNames?.content)}
310
+ className={classify(css.modal, css[size], classNames?.content)}
305
311
  role="dialog"
306
312
  style={{
307
313
  // Transition styles
@@ -1,6 +1,6 @@
1
1
  @value (colorBackgroundTertiary, colorBackgroundPrimary, colorBackdropFill) from '../../styles/variables/_color.css';
2
2
  @value (spaceNone, spaceSmall, spaceMedium, spaceXXSmall, spaceHalfFluid, spaceNegHalfFluid) from '../../styles/variables/_space.css';
3
- @value (sizeFluid, size60) from '../../styles/variables/_size.css';
3
+ @value (sizeFluid, size60, size320, size480, size640) from '../../styles/variables/_size.css';
4
4
  @value (elevationNone, elevationModal, elevationBackdrop) from '../../styles/variables/_elevation.css';
5
5
  @value (opacity100, opacity0) from '../../styles/variables/_opacity.css';
6
6
  @value (motionDurationNormal, motionEaseInEaseOut) from '../../styles/variables/_motion.css';
@@ -27,6 +27,18 @@
27
27
  border-radius: borderRadiusMedium;
28
28
  }
29
29
 
30
+ .modal.small {
31
+ width: size320;
32
+ }
33
+
34
+ .modal.medium {
35
+ width: size480;
36
+ }
37
+
38
+ .modal.large {
39
+ width: size640;
40
+ }
41
+
30
42
  .modalContainer.open.in .modal {
31
43
  opacity: opacity100;
32
44
  transform: translate(spaceNegHalfFluid, spaceNegHalfFluid) scale(1);
@@ -1,5 +1,6 @@
1
1
  //@flow strict
2
2
  export type {
3
+ BaseModalProps,
3
4
  ModalBodyProps,
4
5
  ModalFooterProps,
5
6
  ModalHeaderProps,
@@ -59,12 +59,12 @@ const Textarea_ = (props, ref) => {
59
59
  }, '*')), /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
60
60
  color: error || textCountError ? 'danger' : 'secondary'
61
61
  }, !!textCountLimit && (value && value.length || 0) + '/' + textCountLimit)), /*#__PURE__*/React.createElement("div", {
62
- className: (0, _classify.classify)(_TextareaModule.default.box, classNames?.box, {
62
+ className: (0, _classify.classify)(_TextareaModule.default.box, {
63
63
  [_TextareaModule.default.inputDisabled]: disabled ?? false,
64
64
  [_TextareaModule.default.medium]: size === 'medium',
65
65
  [_TextareaModule.default.small]: size === 'small',
66
66
  [_TextareaModule.default.locked]: locked
67
- })
67
+ }, classNames?.box)
68
68
  }, /*#__PURE__*/React.createElement("textarea", _extends({}, textareaProps, {
69
69
  disabled: locked || disabled,
70
70
  name: name,
@@ -91,12 +91,16 @@ const Textarea_ = (props: TextareaProps, ref): React.Node => {
91
91
  </div>
92
92
  )}
93
93
  <div
94
- className={classify(css.box, classNames?.box, {
95
- [css.inputDisabled]: disabled ?? false,
96
- [css.medium]: size === 'medium',
97
- [css.small]: size === 'small',
98
- [css.locked]: locked,
99
- })}
94
+ className={classify(
95
+ css.box,
96
+ {
97
+ [css.inputDisabled]: disabled ?? false,
98
+ [css.medium]: size === 'medium',
99
+ [css.small]: size === 'small',
100
+ [css.locked]: locked,
101
+ },
102
+ classNames?.box,
103
+ )}
100
104
  >
101
105
  <textarea
102
106
  {...textareaProps}
@@ -14,14 +14,14 @@
14
14
  @value (
15
15
  borderRadiusMedium,
16
16
  borderRadiusSmall,
17
- borderWidthSecondary,
17
+ borderWidthPrimary,
18
18
  borderWidthTertiary,
19
19
  borderWidthNone
20
20
  ) from '../../styles/variables/_border.css';
21
21
 
22
22
  @value (
23
23
  colorTextPrimary,
24
- colorTextSecondary,
24
+ colorTextTertiary,
25
25
  colorBorderPrimary,
26
26
  colorFillPrimary,
27
27
  colorFocusPrimary,
@@ -29,7 +29,8 @@
29
29
  colorTextDisabled,
30
30
  colorFillDisabled,
31
31
  colorTextDanger,
32
- colorBackgroundTertiary
32
+ colorBackgroundTertiary,
33
+ colorBorderTertiary
33
34
  ) from '../../styles/variables/_color.css';
34
35
 
35
36
  .container {
@@ -43,10 +44,19 @@
43
44
  color: colorTextPrimary;
44
45
  gap: spaceSmall;
45
46
  height: size160;
46
- border: borderWidthSecondary solid colorBorderPrimary;
47
+ border: borderWidthPrimary solid colorBorderPrimary;
47
48
  background-color: colorBackgroundTertiary;
48
49
  }
49
50
 
51
+ .wrapper:not(.withError) .box:not(.inputDisabled):not(.locked):hover {
52
+ border-color: colorBorderTertiary;
53
+ }
54
+
55
+ .wrapper:not(.withError):focus-within
56
+ .box:not(.inputDisabled):not(.locked):hover {
57
+ border-color: colorFillPrimary;
58
+ }
59
+
50
60
  .box textarea {
51
61
  padding: spaceXSmall spaceSmall;
52
62
  }
@@ -82,7 +92,7 @@
82
92
  resize: none;
83
93
  }
84
94
 
85
- .wrapper:not(.inputDisabled):not(.withError):focus-within .box {
95
+ .wrapper:not(.withError):focus-within .box:not(.inputDisabled) {
86
96
  border-color: colorFillPrimary;
87
97
  box-shadow: borderWidthNone borderWidthNone borderWidthNone
88
98
  borderWidthTertiary colorFocusPrimary;
@@ -95,7 +105,7 @@
95
105
  }
96
106
 
97
107
  textarea::placeholder {
98
- color: colorTextSecondary;
108
+ color: colorTextTertiary;
99
109
  }
100
110
 
101
111
  .inputDisabled textarea::placeholder {
@@ -201,6 +201,17 @@ Object.keys(_ErrorMessage).forEach(function (key) {
201
201
  }
202
202
  });
203
203
  });
204
+ var _FileUpload = require("./FileUpload");
205
+ Object.keys(_FileUpload).forEach(function (key) {
206
+ if (key === "default" || key === "__esModule") return;
207
+ if (key in exports && exports[key] === _FileUpload[key]) return;
208
+ Object.defineProperty(exports, key, {
209
+ enumerable: true,
210
+ get: function () {
211
+ return _FileUpload[key];
212
+ }
213
+ });
214
+ });
204
215
  var _FocusManager = require("./FocusManager");
205
216
  Object.keys(_FocusManager).forEach(function (key) {
206
217
  if (key === "default" || key === "__esModule") return;
@@ -18,6 +18,7 @@ export * from './Dialog';
18
18
  export * from './Dropdown';
19
19
  export * from './EmptyState';
20
20
  export * from './ErrorMessage';
21
+ export * from './FileUpload';
21
22
  export * from './FocusManager';
22
23
  export * from './Grid';
23
24
  export * from './Icon';
@@ -14,6 +14,17 @@ Object.keys(_useCopyToClipboard).forEach(function (key) {
14
14
  }
15
15
  });
16
16
  });
17
+ var _useFileUpload = require("./useFileUpload");
18
+ Object.keys(_useFileUpload).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _useFileUpload[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _useFileUpload[key];
25
+ }
26
+ });
27
+ });
17
28
  var _useInputState = require("./useInputState");
18
29
  Object.keys(_useInputState).forEach(function (key) {
19
30
  if (key === "default" || key === "__esModule") return;
@@ -1,6 +1,7 @@
1
1
  // @flow strict
2
2
 
3
3
  export * from './useCopyToClipboard';
4
+ export * from './useFileUpload';
4
5
  export * from './useInputState';
5
6
  export * from './useLockedBody';
6
7
  export * from './useMountTransition';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _useFileUpload = require("./useFileUpload");
7
+ Object.keys(_useFileUpload).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _useFileUpload[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _useFileUpload[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,3 @@
1
+ // @flow strict
2
+
3
+ export * from './useFileUpload';
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useFileUpload = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _reactDropzone = require("react-dropzone");
9
+ var _helpers = require("../../utils/helpers");
10
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
11
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
12
+
13
+ // $FlowFixMe[untyped-import]
14
+
15
+ const initialState = {
16
+ validFiles: [],
17
+ rejectedFiles: []
18
+ };
19
+ const reducer = (state, action) => {
20
+ switch (action.type) {
21
+ case 'ADD_VALID_FILES':
22
+ return {
23
+ ...state,
24
+ validFiles: [...state.validFiles, ...action.files]
25
+ };
26
+ case 'ADD_REJECTED_FILES':
27
+ return {
28
+ ...state,
29
+ rejectedFiles: [...state.rejectedFiles, ...action.files]
30
+ };
31
+ case 'REMOVE_FILE':
32
+ return {
33
+ ...state,
34
+ validFiles: state.validFiles.filter(file => file.id !== action.id),
35
+ rejectedFiles: state.rejectedFiles.filter(file => file.id !== action.id)
36
+ };
37
+ case 'CLEAR_FILES':
38
+ return {
39
+ validFiles: [],
40
+ rejectedFiles: []
41
+ };
42
+ case 'UPDATE_FILE_PROGRESS':
43
+ return {
44
+ ...state,
45
+ validFiles: state.validFiles.map(file => file.id === action.id ? {
46
+ ...file,
47
+ progress: action.progress,
48
+ showReUpload: false,
49
+ successMessage: undefined,
50
+ rejectReason: undefined
51
+ } : file),
52
+ rejectedFiles: state.rejectedFiles.map(file => file.id === action.id ? {
53
+ ...file,
54
+ progress: action.progress,
55
+ showReUpload: false,
56
+ successMessage: undefined,
57
+ rejectReason: undefined
58
+ } : file)
59
+ };
60
+ case 'SET_FILE_RE_UPLOAD':
61
+ return {
62
+ ...state,
63
+ validFiles: state.validFiles.map(file => file.id === action.id ? {
64
+ ...file,
65
+ progress: undefined,
66
+ showReUpload: action.showReUpload
67
+ } : file),
68
+ rejectedFiles: state.rejectedFiles.map(file => file.id === action.id ? {
69
+ ...file,
70
+ progress: undefined,
71
+ showReUpload: action.showReUpload
72
+ } : file)
73
+ };
74
+ case 'SET_FILE_SUCCESS':
75
+ {
76
+ // Note: When a file is accepted manually we would move a file from rejected files(if found) to valid files first
77
+ const fileIndex = state.rejectedFiles.findIndex(file => file.id === action.id);
78
+ let validFiles = [...state.validFiles];
79
+ const rejectedFiles = [...state.rejectedFiles];
80
+ if (fileIndex !== -1) {
81
+ const file = rejectedFiles[fileIndex];
82
+ rejectedFiles.splice(fileIndex, 1);
83
+ validFiles = [...validFiles, {
84
+ ...file
85
+ }];
86
+ }
87
+ validFiles = validFiles.map(file => file.id === action.id ? {
88
+ ...file,
89
+ success: true,
90
+ successMessage: action.successMessage,
91
+ reject: false,
92
+ rejectReason: undefined,
93
+ progress: undefined,
94
+ showReUpload: false
95
+ } : file);
96
+ return {
97
+ ...state,
98
+ validFiles,
99
+ rejectedFiles
100
+ };
101
+ }
102
+ case 'SET_FILE_REJECT':
103
+ {
104
+ // Note: When a file is rejected manually we would move a file from valid files(if found) to rejected files first
105
+ const fileIndex = state.validFiles.findIndex(file => file.id === action.id);
106
+ const validFiles = [...state.validFiles];
107
+ let rejectedFiles = [...state.rejectedFiles];
108
+ if (fileIndex !== -1) {
109
+ const file = validFiles[fileIndex];
110
+ validFiles.splice(fileIndex, 1);
111
+ rejectedFiles = [...rejectedFiles, {
112
+ ...file
113
+ }];
114
+ }
115
+ rejectedFiles = rejectedFiles.map(file => file.id === action.id ? {
116
+ ...file,
117
+ reject: true,
118
+ rejectReason: action.rejectReason,
119
+ success: false,
120
+ successMessage: undefined,
121
+ progress: undefined,
122
+ showReUpload: false
123
+ } : file);
124
+ return {
125
+ ...state,
126
+ validFiles,
127
+ rejectedFiles
128
+ };
129
+ }
130
+ default:
131
+ return state;
132
+ }
133
+ };
134
+
135
+ // This is a map of error codes returned by react-dropzone and their corresponding error messages
136
+ const DROPZONE_ERROR_MESSAGES = {
137
+ 'file-too-large': 'File exceeds maximum size',
138
+ 'file-invalid-type': 'Wrong file type',
139
+ 'too-many-files': 'Too many files',
140
+ 'file-too-small': 'File is too small'
141
+ };
142
+ const useFileUpload = _ref => {
143
+ let {
144
+ maxFiles = 1,
145
+ maxSize,
146
+ accept,
147
+ disabled,
148
+ onValidFilesDrop,
149
+ onRejectedFilesDrop,
150
+ onFileClear,
151
+ onClear
152
+ } = _ref;
153
+ const [state, dispatch] = React.useReducer(reducer, initialState);
154
+
155
+ // Callbacks for when files are dropped / selected and are valid
156
+ const handleDropAccepted = acceptedFiles => {
157
+ const validFiles = acceptedFiles.map(file => ({
158
+ file,
159
+ id: (0, _helpers.uuid)(),
160
+ reject: false,
161
+ rejectReason: undefined,
162
+ success: true,
163
+ successMessage: undefined,
164
+ progress: undefined,
165
+ showReUpload: false
166
+ }));
167
+ dispatch({
168
+ type: 'ADD_VALID_FILES',
169
+ files: validFiles
170
+ });
171
+ onValidFilesDrop?.(validFiles);
172
+ };
173
+
174
+ // Callbacks for when files are dropped / selected and are invalid
175
+ const handleDropRejected = fileRejections => {
176
+ const rejectedFiles = fileRejections.map(_ref2 => {
177
+ let {
178
+ file,
179
+ errors
180
+ } = _ref2;
181
+ return {
182
+ file,
183
+ id: (0, _helpers.uuid)(),
184
+ reject: true,
185
+ rejectReason: DROPZONE_ERROR_MESSAGES[errors[0].code] || 'Some error occurred uploading this file',
186
+ success: false,
187
+ successMessage: undefined,
188
+ progress: undefined,
189
+ showReUpload: false
190
+ };
191
+ });
192
+ dispatch({
193
+ type: 'ADD_REJECTED_FILES',
194
+ files: rejectedFiles
195
+ });
196
+ onRejectedFilesDrop?.(rejectedFiles);
197
+ };
198
+ const handleFileClear = id => {
199
+ dispatch({
200
+ type: 'REMOVE_FILE',
201
+ id
202
+ });
203
+ onFileClear?.(id);
204
+ };
205
+ const handleClear = () => {
206
+ dispatch({
207
+ type: 'CLEAR_FILES'
208
+ });
209
+ onClear?.();
210
+ };
211
+ const moveFileToProgress = (id, progress) => {
212
+ dispatch({
213
+ type: 'UPDATE_FILE_PROGRESS',
214
+ id,
215
+ progress
216
+ });
217
+ };
218
+
219
+ // Note(Nishant): If the file is found in rejected files, we move it to valid files first in the reducer
220
+ const moveFileToSuccess = (id, successMessage) => {
221
+ dispatch({
222
+ type: 'SET_FILE_SUCCESS',
223
+ id,
224
+ successMessage
225
+ });
226
+ };
227
+
228
+ // Note(Nishant): If the file is found in valid files, we move it to rejected files first in the reducer
229
+ const moveFileToReject = (id, rejectReason) => {
230
+ dispatch({
231
+ type: 'SET_FILE_REJECT',
232
+ id,
233
+ rejectReason
234
+ });
235
+ };
236
+
237
+ // Note: This is used to show the re-upload button on the file
238
+ const setShowReUpload = (id, showReUpload) => {
239
+ dispatch({
240
+ type: 'SET_FILE_RE_UPLOAD',
241
+ id,
242
+ showReUpload
243
+ });
244
+ };
245
+ const totalFiles = state.validFiles.length + state.rejectedFiles.length;
246
+ const shouldAcceptFiles = !disabled && (maxFiles === 0 || totalFiles < maxFiles);
247
+
248
+ // We are using react-dropzone's useDropzone hook to get the drag and drop props
249
+ const {
250
+ isDragActive,
251
+ getRootProps,
252
+ getInputProps
253
+ } = (0, _reactDropzone.useDropzone)({
254
+ maxFiles,
255
+ multiple: maxFiles > 1 || maxFiles === 0,
256
+ maxSize,
257
+ accept,
258
+ disabled,
259
+ noClick: !shouldAcceptFiles,
260
+ noDrag: !shouldAcceptFiles,
261
+ onDropAccepted: handleDropAccepted,
262
+ onDropRejected: handleDropRejected
263
+ });
264
+ return {
265
+ validFiles: state.validFiles,
266
+ rejectedFiles: state.rejectedFiles,
267
+ shouldAcceptFiles,
268
+ isDragActive,
269
+ getRootProps,
270
+ getInputProps,
271
+ handleFileClear,
272
+ handleClear,
273
+ moveFileToProgress,
274
+ moveFileToSuccess,
275
+ moveFileToReject,
276
+ setShowReUpload
277
+ };
278
+ };
279
+ exports.useFileUpload = useFileUpload;