react-native-molecules 0.5.0-beta.11 → 0.5.0-beta.13

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.
@@ -7,15 +7,11 @@ import {
7
7
  } from '../utils/DocumentPicker';
8
8
  import { isNil, omitBy } from '../utils/lodash';
9
9
 
10
- export const useFilePicker = ({
11
- multiple,
12
- onCancel,
13
- onError,
14
- ...options
15
- }: DocumentPickerOptions) => {
10
+ export const useFilePicker = (options: DocumentPickerOptions) => {
16
11
  const openFilePicker = useCallback(
17
- async (callback: (response: DocumentResult | DocumentResult[]) => void): Promise<void> => {
18
- const omittedOptions = omitBy(options, isNil);
12
+ async (callback: (response: DocumentResult[]) => void) => {
13
+ const { multiple, ...rest } = options;
14
+ const omittedOptions = omitBy(rest, isNil);
19
15
 
20
16
  try {
21
17
  let response;
@@ -30,16 +26,10 @@ export const useFilePicker = ({
30
26
  } catch (e: any) {
31
27
  // eslint-disable-next-line no-console
32
28
  console.log('FilePicker Error', e, e?.code);
33
-
34
- if (e?.code === 'DOCUMENT_PICKER_CANCELED.') {
35
- onCancel?.();
36
- return;
37
- }
38
- // It might result in an error.
39
- onError?.(e);
29
+ // Error and cancel callbacks are handled by DocumentPicker itself
40
30
  }
41
31
  },
42
- [multiple, onCancel, onError, options],
32
+ [options],
43
33
  );
44
34
 
45
35
  return { openFilePicker };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-molecules",
3
- "version": "0.5.0-beta.11",
3
+ "version": "0.5.0-beta.13",
4
4
  "author": "Thet Aung <thetaung.dev@gmail.com>",
5
5
  "license": "MIT",
6
6
  "main": "index.ts",
@@ -2,6 +2,14 @@ import { Platform } from 'react-native';
2
2
 
3
3
  import type { DocumentPickerOptions, DocumentResult } from './types';
4
4
 
5
+ class OperationCanceledError extends Error {
6
+ code = 'OPERATION_CANCELED';
7
+ constructor() {
8
+ super('user canceled the document picker');
9
+ this.name = 'OperationCanceledError';
10
+ }
11
+ }
12
+
5
13
  const resolveFileData = (file: File): Promise<DocumentResult> => {
6
14
  return new Promise((resolve, reject) => {
7
15
  const mimeType = file.type;
@@ -31,46 +39,89 @@ const resolveFileData = (file: File): Promise<DocumentResult> => {
31
39
  const getDocumentAsyncWeb = async ({
32
40
  type = '*/*',
33
41
  multiple = false,
34
- }: DocumentPickerOptions): Promise<DocumentResult | DocumentResult[]> => {
42
+ onCancel,
43
+ onError,
44
+ }: DocumentPickerOptions): Promise<DocumentResult[]> => {
35
45
  // SSR guard
36
46
  if (Platform.OS !== 'web') {
37
- return { type: 'cancel' };
47
+ const error = new OperationCanceledError();
48
+ onCancel?.();
49
+ throw error;
38
50
  }
39
51
 
40
- const input = document.createElement('input');
41
- input.style.display = 'none';
42
- input.setAttribute('type', 'file');
43
- // @ts-expect-error
44
- input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);
52
+ return new Promise((resolve, reject) => {
53
+ try {
54
+ const input = document.createElement('input');
55
+ input.style.display = 'none';
56
+ input.setAttribute('type', 'file');
57
+ // @ts-expect-error
58
+ input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);
45
59
 
46
- if (multiple) {
47
- input.setAttribute('multiple', 'multiple');
48
- }
60
+ if (multiple) {
61
+ input.setAttribute('multiple', 'multiple');
62
+ }
49
63
 
50
- document.body.appendChild(input);
64
+ document.body.appendChild(input);
51
65
 
52
- return new Promise(resolve => {
53
- input.addEventListener('change', () => {
54
- if (input.files) {
55
- const response: Promise<DocumentResult>[] = [];
66
+ const cleanup = () => {
67
+ try {
68
+ document.body.removeChild(input);
69
+ } catch (e) {
70
+ // Input already removed, ignore
71
+ }
72
+ };
56
73
 
57
- Array.from(input.files).forEach(file => response.push(resolveFileData(file)));
74
+ input.addEventListener('change', async () => {
75
+ try {
76
+ if (input.files && input.files.length > 0) {
77
+ const response: Promise<DocumentResult>[] = [];
58
78
 
59
- return resolve(Promise.all(response));
60
- } else {
61
- resolve({ type: 'cancel' });
62
- }
79
+ Array.from(input.files).forEach(file =>
80
+ response.push(resolveFileData(file)),
81
+ );
63
82
 
64
- document.body.removeChild(input);
65
- });
83
+ const results = await Promise.all(response);
84
+ resolve(results);
85
+ }
86
+ } catch (error) {
87
+ onError?.(error);
88
+ reject(error);
89
+ } finally {
90
+ cleanup();
91
+ }
92
+ });
66
93
 
67
- const event = new MouseEvent('click');
68
- input.dispatchEvent(event);
94
+ input.addEventListener('cancel', () => {
95
+ const error = new OperationCanceledError();
96
+ onCancel?.();
97
+ cleanup();
98
+ reject(error);
99
+ });
100
+
101
+ input.addEventListener('error', () => {
102
+ const error = new Error('File picker error occurred');
103
+ onError?.(error);
104
+ cleanup();
105
+ reject(error);
106
+ });
107
+
108
+ const event = new MouseEvent('click');
109
+ input.dispatchEvent(event);
110
+ } catch (error) {
111
+ // Handle errors from file picker setup or opening
112
+ onError?.(error);
113
+ reject(error);
114
+ }
69
115
  });
70
116
  };
71
117
 
118
+ const pickSingle = (options: DocumentPickerOptions = {}) =>
119
+ getDocumentAsyncWeb({ ...options, multiple: false });
120
+
121
+ const pickMultiple = (options: DocumentPickerOptions = {}) =>
122
+ getDocumentAsyncWeb({ ...options, multiple: true });
123
+
72
124
  export default {
73
- pickSingle: ({ type }: DocumentPickerOptions) => getDocumentAsyncWeb({ type, multiple: false }),
74
- pickMultiple: ({ type }: DocumentPickerOptions) =>
75
- getDocumentAsyncWeb({ type, multiple: true }),
125
+ pickSingle,
126
+ pickMultiple,
76
127
  };
@@ -12,7 +12,6 @@ export type DocumentPickerOptions = Omit<RNDocumentPickerOptions, 'allowMultiSel
12
12
  multiple?: boolean;
13
13
  /**
14
14
  * runs when the DocumentPicker is cancelled
15
- * currently, only supported on IOS and Android
16
15
  */
17
16
  onCancel?: () => void;
18
17
  /**