@aws-amplify/ui-react-core 3.0.29 → 3.1.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.
Files changed (38) hide show
  1. package/dist/elements.js +116 -3
  2. package/dist/esm/elements/ControlsContext.mjs +71 -0
  3. package/dist/esm/elements/ElementsContext.mjs +3 -2
  4. package/dist/esm/elements/defineBaseElement.mjs +30 -1
  5. package/dist/esm/elements/utils.mjs +11 -0
  6. package/dist/esm/elements/withBaseElementProps.mjs +1 -1
  7. package/dist/esm/elements.mjs +3 -1
  8. package/dist/esm/hooks/useDataState.mjs +10 -4
  9. package/dist/esm/hooks/useDropZone.mjs +13 -4
  10. package/dist/esm/utils/createContextUtilities.mjs +6 -3
  11. package/dist/esm/utils/processDroppedItems.mjs +66 -0
  12. package/dist/index.js +92 -11
  13. package/dist/types/elements/ControlsContext.d.ts +63 -0
  14. package/dist/types/elements/ElementsContext.d.ts +3 -2
  15. package/dist/types/elements/defineBaseElement.d.ts +19 -2
  16. package/dist/types/elements/index.d.ts +4 -1
  17. package/dist/types/elements/types.d.ts +88 -6
  18. package/dist/types/elements/utils.d.ts +3 -0
  19. package/dist/types/elements/withBaseElementProps.d.ts +3 -3
  20. package/dist/types/hooks/index.d.ts +1 -1
  21. package/dist/types/hooks/useDataState.d.ts +6 -1
  22. package/dist/types/index.d.ts +1 -1
  23. package/dist/types/utils/createContextUtilities.d.ts +1 -1
  24. package/dist/types/utils/processDroppedItems.d.ts +1 -0
  25. package/package.json +3 -3
  26. package/src/elements/ControlsContext.tsx +89 -0
  27. package/src/elements/ElementsContext.tsx +3 -2
  28. package/src/elements/defineBaseElement.tsx +50 -2
  29. package/src/elements/index.ts +7 -1
  30. package/src/elements/types.ts +114 -6
  31. package/src/elements/utils.ts +20 -0
  32. package/src/elements/withBaseElementProps.tsx +3 -3
  33. package/src/hooks/index.ts +6 -1
  34. package/src/hooks/useDataState.ts +25 -7
  35. package/src/hooks/useDropZone.ts +18 -7
  36. package/src/index.ts +2 -0
  37. package/src/utils/createContextUtilities.tsx +9 -6
  38. package/src/utils/processDroppedItems.ts +79 -0
package/dist/elements.js CHANGED
@@ -8,13 +8,91 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
 
9
9
  var React__default = /*#__PURE__*/_interopDefault(React);
10
10
 
11
+ function isComponent(component) {
12
+ return typeof component === 'function';
13
+ }
14
+ function isForwardRefExoticComponent(component) {
15
+ return (typeof component === 'object' &&
16
+ typeof component.$$typeof ===
17
+ 'symbol' &&
18
+ ['react.memo', 'react.forward_ref'].includes(component.$$typeof.description));
19
+ }
20
+
21
+ /**
22
+ * @internal @unstable
23
+ */
24
+ const ControlsContext = React__default["default"].createContext(undefined);
25
+ /**
26
+ * @internal @unstable
27
+ *
28
+ * `ControlsProvider` provides the values contained in `ControlsContext`
29
+ * to consumers. `ControlsContext` lookup is handled directly
30
+ * by `Control` components returned by `withControls`.
31
+ *
32
+ * @example
33
+ *
34
+ * Add `ControlsContext` aware `Controls` components to a Connected
35
+ * Component:
36
+ *
37
+ * ```tsx
38
+ * const DataList = withControls(function DataList<T>(data: T[]) {
39
+ * return <ScrollView>data.map(ListItem)</ScrollView>;
40
+ * }, 'DataList');
41
+ *
42
+ * const DataListControl = () => {
43
+ * const data = useData();
44
+ * return <DataList data={data} />;
45
+ * }
46
+ *
47
+ * interface ComponentControls {
48
+ * DataList: typeof DataListControl;
49
+ * }
50
+ *
51
+ * function Component<T extends ComponentControls>(
52
+ * controls?: T
53
+ * ) {
54
+ * function ConnectedComponent({
55
+ * children,
56
+ * }: { children?: React.ReactNode }) {
57
+ * return (
58
+ * <ControlsProvider controls={controls}>
59
+ * {children}
60
+ * </ControlsProvider>
61
+ * );
62
+ * }
63
+ *
64
+ * return ConnectedComponent;
65
+ * }
66
+ * ```
67
+ */
68
+ function ControlsProvider({ controls, ...props }) {
69
+ return React__default["default"].createElement(ControlsContext.Provider, { ...props, value: controls });
70
+ }
71
+ /**
72
+ * @internal @unstable
73
+ *
74
+ * @note reference `ControlsProvider` for example usage
75
+ */
76
+ function withControls(Default, name) {
77
+ const Component = (props) => {
78
+ const Override = React__default["default"].useContext(ControlsContext)?.[name];
79
+ if (isComponent(Override)) {
80
+ return React__default["default"].createElement(Override, { ...props });
81
+ }
82
+ return React__default["default"].createElement(Default, { ...props });
83
+ };
84
+ Component.displayName = name;
85
+ return Component;
86
+ }
87
+
11
88
  const ElementsContext = React__default["default"].createContext(undefined);
12
89
  /**
13
90
  * @internal @unstable
14
91
  *
15
92
  * `ElementsProvider` provides the values contained in `ElementsContext`
16
93
  * to its `children`. `ElementsContext` lookup is handled directly
17
- * by `BaseElement`components returned by `defineBaseElement`.
94
+ * by `BaseElement`components returned by `defineBaseElement` and
95
+ * `defineBaseElementWithRef`.
18
96
  *
19
97
  * @example
20
98
  *
@@ -23,7 +101,7 @@ const ElementsContext = React__default["default"].createContext(undefined);
23
101
  *
24
102
  * ```tsx
25
103
  * // `BaseElement`, renders custom or default element defintion
26
- * const ViewElement = defineBaseElement({
104
+ * const ViewElement = defineBaseElementWithRef({
27
105
  * displayName: "View",
28
106
  * type: "div",
29
107
  * });
@@ -77,6 +155,35 @@ function ElementsProvider({ elements, ...props }) {
77
155
  * @returns {BaseElement} `ElementsContext` aware UI component
78
156
  */
79
157
  function defineBaseElement(input) {
158
+ const { displayName, type } = input;
159
+ const Element = ({ variant, ...props }) => {
160
+ const Element = React__default["default"].useContext(ElementsContext)?.[displayName];
161
+ if (Element) {
162
+ // only pass `variant` to provided `Element` values
163
+ return React__default["default"].createElement(Element, { ...props, variant });
164
+ }
165
+ return React__default["default"].createElement(type, props);
166
+ };
167
+ Element.displayName = displayName;
168
+ return Element;
169
+ }
170
+ /**
171
+ * @internal @unstable
172
+ *
173
+ * Defines a `ElementsContext` aware `BaseElement` UI component of the
174
+ * provided `type` with an assigned `displayName` and element `ref`.
175
+ *
176
+ * If `BaseElement` is used as a child of an `ElementsProvider`, returns the
177
+ * `BaseElement` value of the provided `displayName` of `ElementsContext`.
178
+ *
179
+ * When used outside of a parent `ElementsProvider` or no `BaseElement`
180
+ * of `displayName` is found in the `ElementsContext`, returns a stateless,
181
+ * unstyled HTML element of the provided `type`.
182
+ *
183
+ * @param {DefineBaseElementInput} input `BaseElement` parameters
184
+ * @returns {BaseElementWithRefProps} `ElementsContext` aware UI component
185
+ */
186
+ function defineBaseElementWithRef(input) {
80
187
  const { displayName, type } = input;
81
188
  const Element = React__default["default"].forwardRef(({ variant, ...props }, ref) => {
82
189
  const Element = React__default["default"].useContext(ElementsContext)?.[displayName];
@@ -105,7 +212,7 @@ function defineBaseElement(input) {
105
212
  * type InputElementPropKey = 'onChange' | 'type';
106
213
  *
107
214
  * // create `InputElement` base with `type` generic and extended `props` key
108
- * export const InputElement = defineBaseElement<"input", InputElementPropKey>({
215
+ * export const InputElement = defineBaseElementWithRef<"input", InputElementPropKey>({
109
216
  * type: "input",
110
217
  * displayName: "Input",
111
218
  * });
@@ -130,6 +237,12 @@ function withBaseElementProps(Target, defaultProps) {
130
237
  return Component;
131
238
  }
132
239
 
240
+ exports.ControlsContext = ControlsContext;
241
+ exports.ControlsProvider = ControlsProvider;
133
242
  exports.ElementsProvider = ElementsProvider;
134
243
  exports.defineBaseElement = defineBaseElement;
244
+ exports.defineBaseElementWithRef = defineBaseElementWithRef;
245
+ exports.isComponent = isComponent;
246
+ exports.isForwardRefExoticComponent = isForwardRefExoticComponent;
135
247
  exports.withBaseElementProps = withBaseElementProps;
248
+ exports.withControls = withControls;
@@ -0,0 +1,71 @@
1
+ import React__default from 'react';
2
+ import { isComponent } from './utils.mjs';
3
+
4
+ /**
5
+ * @internal @unstable
6
+ */
7
+ const ControlsContext = React__default.createContext(undefined);
8
+ /**
9
+ * @internal @unstable
10
+ *
11
+ * `ControlsProvider` provides the values contained in `ControlsContext`
12
+ * to consumers. `ControlsContext` lookup is handled directly
13
+ * by `Control` components returned by `withControls`.
14
+ *
15
+ * @example
16
+ *
17
+ * Add `ControlsContext` aware `Controls` components to a Connected
18
+ * Component:
19
+ *
20
+ * ```tsx
21
+ * const DataList = withControls(function DataList<T>(data: T[]) {
22
+ * return <ScrollView>data.map(ListItem)</ScrollView>;
23
+ * }, 'DataList');
24
+ *
25
+ * const DataListControl = () => {
26
+ * const data = useData();
27
+ * return <DataList data={data} />;
28
+ * }
29
+ *
30
+ * interface ComponentControls {
31
+ * DataList: typeof DataListControl;
32
+ * }
33
+ *
34
+ * function Component<T extends ComponentControls>(
35
+ * controls?: T
36
+ * ) {
37
+ * function ConnectedComponent({
38
+ * children,
39
+ * }: { children?: React.ReactNode }) {
40
+ * return (
41
+ * <ControlsProvider controls={controls}>
42
+ * {children}
43
+ * </ControlsProvider>
44
+ * );
45
+ * }
46
+ *
47
+ * return ConnectedComponent;
48
+ * }
49
+ * ```
50
+ */
51
+ function ControlsProvider({ controls, ...props }) {
52
+ return React__default.createElement(ControlsContext.Provider, { ...props, value: controls });
53
+ }
54
+ /**
55
+ * @internal @unstable
56
+ *
57
+ * @note reference `ControlsProvider` for example usage
58
+ */
59
+ function withControls(Default, name) {
60
+ const Component = (props) => {
61
+ const Override = React__default.useContext(ControlsContext)?.[name];
62
+ if (isComponent(Override)) {
63
+ return React__default.createElement(Override, { ...props });
64
+ }
65
+ return React__default.createElement(Default, { ...props });
66
+ };
67
+ Component.displayName = name;
68
+ return Component;
69
+ }
70
+
71
+ export { ControlsContext, ControlsProvider, withControls };
@@ -6,7 +6,8 @@ const ElementsContext = React__default.createContext(undefined);
6
6
  *
7
7
  * `ElementsProvider` provides the values contained in `ElementsContext`
8
8
  * to its `children`. `ElementsContext` lookup is handled directly
9
- * by `BaseElement`components returned by `defineBaseElement`.
9
+ * by `BaseElement`components returned by `defineBaseElement` and
10
+ * `defineBaseElementWithRef`.
10
11
  *
11
12
  * @example
12
13
  *
@@ -15,7 +16,7 @@ const ElementsContext = React__default.createContext(undefined);
15
16
  *
16
17
  * ```tsx
17
18
  * // `BaseElement`, renders custom or default element defintion
18
- * const ViewElement = defineBaseElement({
19
+ * const ViewElement = defineBaseElementWithRef({
19
20
  * displayName: "View",
20
21
  * type: "div",
21
22
  * });
@@ -18,6 +18,35 @@ import { ElementsContext } from './ElementsContext.mjs';
18
18
  * @returns {BaseElement} `ElementsContext` aware UI component
19
19
  */
20
20
  function defineBaseElement(input) {
21
+ const { displayName, type } = input;
22
+ const Element = ({ variant, ...props }) => {
23
+ const Element = React__default.useContext(ElementsContext)?.[displayName];
24
+ if (Element) {
25
+ // only pass `variant` to provided `Element` values
26
+ return React__default.createElement(Element, { ...props, variant });
27
+ }
28
+ return React__default.createElement(type, props);
29
+ };
30
+ Element.displayName = displayName;
31
+ return Element;
32
+ }
33
+ /**
34
+ * @internal @unstable
35
+ *
36
+ * Defines a `ElementsContext` aware `BaseElement` UI component of the
37
+ * provided `type` with an assigned `displayName` and element `ref`.
38
+ *
39
+ * If `BaseElement` is used as a child of an `ElementsProvider`, returns the
40
+ * `BaseElement` value of the provided `displayName` of `ElementsContext`.
41
+ *
42
+ * When used outside of a parent `ElementsProvider` or no `BaseElement`
43
+ * of `displayName` is found in the `ElementsContext`, returns a stateless,
44
+ * unstyled HTML element of the provided `type`.
45
+ *
46
+ * @param {DefineBaseElementInput} input `BaseElement` parameters
47
+ * @returns {BaseElementWithRefProps} `ElementsContext` aware UI component
48
+ */
49
+ function defineBaseElementWithRef(input) {
21
50
  const { displayName, type } = input;
22
51
  const Element = React__default.forwardRef(({ variant, ...props }, ref) => {
23
52
  const Element = React__default.useContext(ElementsContext)?.[displayName];
@@ -31,4 +60,4 @@ function defineBaseElement(input) {
31
60
  return Element;
32
61
  }
33
62
 
34
- export { defineBaseElement as default };
63
+ export { defineBaseElement, defineBaseElementWithRef };
@@ -0,0 +1,11 @@
1
+ function isComponent(component) {
2
+ return typeof component === 'function';
3
+ }
4
+ function isForwardRefExoticComponent(component) {
5
+ return (typeof component === 'object' &&
6
+ typeof component.$$typeof ===
7
+ 'symbol' &&
8
+ ['react.memo', 'react.forward_ref'].includes(component.$$typeof.description));
9
+ }
10
+
11
+ export { isComponent, isForwardRefExoticComponent };
@@ -15,7 +15,7 @@ import React__default from 'react';
15
15
  * type InputElementPropKey = 'onChange' | 'type';
16
16
  *
17
17
  * // create `InputElement` base with `type` generic and extended `props` key
18
- * export const InputElement = defineBaseElement<"input", InputElementPropKey>({
18
+ * export const InputElement = defineBaseElementWithRef<"input", InputElementPropKey>({
19
19
  * type: "input",
20
20
  * displayName: "Input",
21
21
  * });
@@ -1,3 +1,5 @@
1
- export { default as defineBaseElement } from './elements/defineBaseElement.mjs';
1
+ export { ControlsContext, ControlsProvider, withControls } from './elements/ControlsContext.mjs';
2
+ export { defineBaseElement, defineBaseElementWithRef } from './elements/defineBaseElement.mjs';
2
3
  export { default as withBaseElementProps } from './elements/withBaseElementProps.mjs';
3
4
  export { ElementsProvider } from './elements/ElementsContext.mjs';
5
+ export { isComponent, isForwardRefExoticComponent } from './elements/utils.mjs';
@@ -1,3 +1,4 @@
1
+ import { isFunction } from '@aws-amplify/ui';
1
2
  import React__default from 'react';
2
3
 
3
4
  // default state
@@ -8,23 +9,28 @@ const resolveMaybeAsync = async (value) => {
8
9
  const awaited = await value;
9
10
  return awaited;
10
11
  };
11
- function useDataState(action, initialData) {
12
+ function useDataState(action, initialData, options) {
12
13
  const [dataState, setDataState] = React__default.useState(() => ({
13
14
  ...INITIAL_STATE,
14
15
  data: initialData,
15
16
  }));
16
17
  const prevData = React__default.useRef(initialData);
17
- const handleAction = React__default.useCallback((...input) => {
18
+ const { onSuccess, onError } = options ?? {};
19
+ const handleAction = React__default.useCallback((input) => {
18
20
  setDataState(({ data }) => ({ ...LOADING_STATE, data }));
19
- resolveMaybeAsync(action(prevData.current, ...input))
21
+ resolveMaybeAsync(action(prevData.current, input))
20
22
  .then((data) => {
23
+ if (isFunction(onSuccess))
24
+ onSuccess(data);
21
25
  prevData.current = data;
22
26
  setDataState({ ...INITIAL_STATE, data });
23
27
  })
24
28
  .catch(({ message }) => {
29
+ if (isFunction(onError))
30
+ onError(message);
25
31
  setDataState(({ data }) => ({ ...ERROR_STATE, data, message }));
26
32
  });
27
- }, [action]);
33
+ }, [action, onError, onSuccess]);
28
34
  return [dataState, handleAction];
29
35
  }
30
36
 
@@ -1,6 +1,7 @@
1
1
  import { useState } from 'react';
2
2
  import { isFunction } from '@aws-amplify/ui';
3
3
  import { filterAllowedFiles } from '../utils/filterAllowedFiles.mjs';
4
+ import { processDroppedItems } from '../utils/processDroppedItems.mjs';
4
5
 
5
6
  function useDropZone({ onDropComplete, onDragEnter: _onDragEnter, onDragLeave: _onDragLeave, onDragOver: _onDragOver, onDragStart: _onDragStart, onDrop: _onDrop, acceptedFileTypes = [], }) {
6
7
  const [dragState, setDragState] = useState('inactive');
@@ -43,13 +44,21 @@ function useDropZone({ onDropComplete, onDragEnter: _onDragEnter, onDragLeave: _
43
44
  event.preventDefault();
44
45
  event.stopPropagation();
45
46
  setDragState('inactive');
46
- const files = Array.from(event.dataTransfer.files);
47
- const { acceptedFiles, rejectedFiles } = filterAllowedFiles(files, acceptedFileTypes);
47
+ const { files, items } = event.dataTransfer;
48
48
  if (isFunction(_onDrop)) {
49
49
  _onDrop(event);
50
50
  }
51
- if (isFunction(onDropComplete)) {
52
- onDropComplete({ acceptedFiles, rejectedFiles });
51
+ const completeDrop = (files) => {
52
+ const { acceptedFiles, rejectedFiles } = filterAllowedFiles(files, acceptedFileTypes);
53
+ if (isFunction(onDropComplete)) {
54
+ onDropComplete({ acceptedFiles, rejectedFiles });
55
+ }
56
+ };
57
+ if (!items) {
58
+ completeDrop(Array.from(files));
59
+ }
60
+ else {
61
+ processDroppedItems(Array.from(items)).then(completeDrop);
53
62
  }
54
63
  };
55
64
  return {
@@ -53,7 +53,10 @@ function createContextUtilities(options) {
53
53
  if (isUndefined(defaultValue) && !isString(errorMessage)) {
54
54
  throw new Error(INVALID_OPTIONS_MESSAGE);
55
55
  }
56
+ const contextDisplayName = `${contextName}Context`;
57
+ const providerDisplayName = `${contextName}Provider`;
56
58
  const Context = React__default.createContext(defaultValue);
59
+ Context.displayName = contextDisplayName;
57
60
  function Provider(props) {
58
61
  const { children, ...context } = props;
59
62
  const value = React__default.useMemo(() => context,
@@ -63,7 +66,7 @@ function createContextUtilities(options) {
63
66
  Object.values(context));
64
67
  return React__default.createElement(Context.Provider, { value: value }, children);
65
68
  }
66
- Provider.displayName = `${contextName}Provider`;
69
+ Provider.displayName = providerDisplayName;
67
70
  return {
68
71
  [`use${contextName}`]: function (params) {
69
72
  const context = React__default.useContext(Context);
@@ -72,8 +75,8 @@ function createContextUtilities(options) {
72
75
  }
73
76
  return context;
74
77
  },
75
- [`${contextName}Provider`]: Provider,
76
- [`${contextName}Context`]: Context,
78
+ [providerDisplayName]: Provider,
79
+ [contextDisplayName]: Context,
77
80
  };
78
81
  }
79
82
 
@@ -0,0 +1,66 @@
1
+ // Helper function to convert FileSystemFileEntry to File
2
+ const getFileFromEntry = (fileEntry) => {
3
+ return new Promise((resolve) => {
4
+ fileEntry.file(resolve);
5
+ });
6
+ };
7
+ // Helper function to read all entries in a directory
8
+ const readAllDirectoryEntries = async (dirReader) => {
9
+ const entries = [];
10
+ let readBatch = [];
11
+ do {
12
+ readBatch = await new Promise((resolve, reject) => {
13
+ try {
14
+ dirReader.readEntries(resolve, reject);
15
+ }
16
+ catch (error) {
17
+ reject(error);
18
+ }
19
+ });
20
+ entries.push(...readBatch);
21
+ } while (readBatch.length > 0);
22
+ return entries;
23
+ };
24
+ // Helper function to process files and folder contents
25
+ async function processDroppedItems(dataTransferItems) {
26
+ const files = [];
27
+ const processFileSystemEntry = async (entry) => {
28
+ if (entry.isFile) {
29
+ const file = await getFileFromEntry(entry);
30
+ // drag and dropped files do not have a webkitRelativePath property,
31
+ // but they do have a fullPath property which has the same information
32
+ // https://github.com/ant-design/ant-design/issues/16426
33
+ if (entry.fullPath && !file.webkitRelativePath) {
34
+ Object.defineProperties(file, {
35
+ webkitRelativePath: {
36
+ writable: true,
37
+ },
38
+ });
39
+ // intentionally overwriting webkitRelativePath
40
+ // @ts-expect-error
41
+ file.webkitRelativePath = entry.fullPath.replace(/^\//, '');
42
+ Object.defineProperties(file, {
43
+ webkitRelativePath: {
44
+ writable: false,
45
+ },
46
+ });
47
+ }
48
+ files.push(file);
49
+ }
50
+ else if (entry.isDirectory) {
51
+ const dirReader = entry.createReader();
52
+ const dirEntries = await readAllDirectoryEntries(dirReader);
53
+ await Promise.all(dirEntries.map(processFileSystemEntry));
54
+ }
55
+ };
56
+ // Filter out and process files from the data transfer items
57
+ await Promise.all(dataTransferItems
58
+ .reduce((acc, item) => {
59
+ const entry = item.webkitGetAsEntry();
60
+ return item.kind === 'file' && entry ? [...acc, entry] : acc;
61
+ }, [])
62
+ .map(processFileSystemEntry));
63
+ return files;
64
+ }
65
+
66
+ export { processDroppedItems };
package/dist/index.js CHANGED
@@ -563,23 +563,28 @@ const resolveMaybeAsync = async (value) => {
563
563
  const awaited = await value;
564
564
  return awaited;
565
565
  };
566
- function useDataState(action, initialData) {
566
+ function useDataState(action, initialData, options) {
567
567
  const [dataState, setDataState] = React__namespace["default"].useState(() => ({
568
568
  ...INITIAL_STATE,
569
569
  data: initialData,
570
570
  }));
571
571
  const prevData = React__namespace["default"].useRef(initialData);
572
- const handleAction = React__namespace["default"].useCallback((...input) => {
572
+ const { onSuccess, onError } = options ?? {};
573
+ const handleAction = React__namespace["default"].useCallback((input) => {
573
574
  setDataState(({ data }) => ({ ...LOADING_STATE, data }));
574
- resolveMaybeAsync(action(prevData.current, ...input))
575
+ resolveMaybeAsync(action(prevData.current, input))
575
576
  .then((data) => {
577
+ if (ui.isFunction(onSuccess))
578
+ onSuccess(data);
576
579
  prevData.current = data;
577
580
  setDataState({ ...INITIAL_STATE, data });
578
581
  })
579
582
  .catch(({ message }) => {
583
+ if (ui.isFunction(onError))
584
+ onError(message);
580
585
  setDataState(({ data }) => ({ ...ERROR_STATE, data, message }));
581
586
  });
582
- }, [action]);
587
+ }, [action, onError, onSuccess]);
583
588
  return [dataState, handleAction];
584
589
  }
585
590
 
@@ -726,6 +731,71 @@ function filterAllowedFiles(files, acceptedFileTypes) {
726
731
  return { acceptedFiles, rejectedFiles };
727
732
  }
728
733
 
734
+ // Helper function to convert FileSystemFileEntry to File
735
+ const getFileFromEntry = (fileEntry) => {
736
+ return new Promise((resolve) => {
737
+ fileEntry.file(resolve);
738
+ });
739
+ };
740
+ // Helper function to read all entries in a directory
741
+ const readAllDirectoryEntries = async (dirReader) => {
742
+ const entries = [];
743
+ let readBatch = [];
744
+ do {
745
+ readBatch = await new Promise((resolve, reject) => {
746
+ try {
747
+ dirReader.readEntries(resolve, reject);
748
+ }
749
+ catch (error) {
750
+ reject(error);
751
+ }
752
+ });
753
+ entries.push(...readBatch);
754
+ } while (readBatch.length > 0);
755
+ return entries;
756
+ };
757
+ // Helper function to process files and folder contents
758
+ async function processDroppedItems(dataTransferItems) {
759
+ const files = [];
760
+ const processFileSystemEntry = async (entry) => {
761
+ if (entry.isFile) {
762
+ const file = await getFileFromEntry(entry);
763
+ // drag and dropped files do not have a webkitRelativePath property,
764
+ // but they do have a fullPath property which has the same information
765
+ // https://github.com/ant-design/ant-design/issues/16426
766
+ if (entry.fullPath && !file.webkitRelativePath) {
767
+ Object.defineProperties(file, {
768
+ webkitRelativePath: {
769
+ writable: true,
770
+ },
771
+ });
772
+ // intentionally overwriting webkitRelativePath
773
+ // @ts-expect-error
774
+ file.webkitRelativePath = entry.fullPath.replace(/^\//, '');
775
+ Object.defineProperties(file, {
776
+ webkitRelativePath: {
777
+ writable: false,
778
+ },
779
+ });
780
+ }
781
+ files.push(file);
782
+ }
783
+ else if (entry.isDirectory) {
784
+ const dirReader = entry.createReader();
785
+ const dirEntries = await readAllDirectoryEntries(dirReader);
786
+ await Promise.all(dirEntries.map(processFileSystemEntry));
787
+ }
788
+ };
789
+ // Filter out and process files from the data transfer items
790
+ await Promise.all(dataTransferItems
791
+ .reduce((acc, item) => {
792
+ const entry = item.webkitGetAsEntry();
793
+ return item.kind === 'file' && entry ? [...acc, entry] : acc;
794
+ }, [])
795
+ .map(processFileSystemEntry));
796
+ return files;
797
+ }
798
+
729
799
  function useDropZone({ onDropComplete, onDragEnter: _onDragEnter, onDragLeave: _onDragLeave, onDragOver: _onDragOver, onDragStart: _onDragStart, onDrop: _onDrop, acceptedFileTypes = [], }) {
730
800
  const [dragState, setDragState] = React.useState('inactive');
731
801
  const onDragStart = (event) => {
@@ -767,13 +837,21 @@ function useDropZone({ onDropComplete, onDragEnter: _onDragEnter, onDragLeave: _
767
837
  event.preventDefault();
768
838
  event.stopPropagation();
769
839
  setDragState('inactive');
770
- const files = Array.from(event.dataTransfer.files);
771
- const { acceptedFiles, rejectedFiles } = filterAllowedFiles(files, acceptedFileTypes);
840
+ const { files, items } = event.dataTransfer;
772
841
  if (ui.isFunction(_onDrop)) {
773
842
  _onDrop(event);
774
843
  }
775
- if (ui.isFunction(onDropComplete)) {
776
- onDropComplete({ acceptedFiles, rejectedFiles });
844
+ const completeDrop = (files) => {
845
+ const { acceptedFiles, rejectedFiles } = filterAllowedFiles(files, acceptedFileTypes);
846
+ if (ui.isFunction(onDropComplete)) {
847
+ onDropComplete({ acceptedFiles, rejectedFiles });
848
+ }
849
+ };
850
+ if (!items) {
851
+ completeDrop(Array.from(files));
852
+ }
853
+ else {
854
+ processDroppedItems(Array.from(items)).then(completeDrop);
777
855
  }
778
856
  };
779
857
  return {
@@ -838,7 +916,10 @@ function createContextUtilities(options) {
838
916
  if (ui.isUndefined(defaultValue) && !ui.isString(errorMessage)) {
839
917
  throw new Error(INVALID_OPTIONS_MESSAGE);
840
918
  }
919
+ const contextDisplayName = `${contextName}Context`;
920
+ const providerDisplayName = `${contextName}Provider`;
841
921
  const Context = React__namespace["default"].createContext(defaultValue);
922
+ Context.displayName = contextDisplayName;
842
923
  function Provider(props) {
843
924
  const { children, ...context } = props;
844
925
  const value = React__namespace["default"].useMemo(() => context,
@@ -848,7 +929,7 @@ function createContextUtilities(options) {
848
929
  Object.values(context));
849
930
  return React__namespace["default"].createElement(Context.Provider, { value: value }, children);
850
931
  }
851
- Provider.displayName = `${contextName}Provider`;
932
+ Provider.displayName = providerDisplayName;
852
933
  return {
853
934
  [`use${contextName}`]: function (params) {
854
935
  const context = React__namespace["default"].useContext(Context);
@@ -857,8 +938,8 @@ function createContextUtilities(options) {
857
938
  }
858
939
  return context;
859
940
  },
860
- [`${contextName}Provider`]: Provider,
861
- [`${contextName}Context`]: Context,
941
+ [providerDisplayName]: Provider,
942
+ [contextDisplayName]: Context,
862
943
  };
863
944
  }
864
945