@tradly/asset 1.0.12 → 1.0.14

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 (72) hide show
  1. package/README.md +257 -13
  2. package/dist/components/FileUpload.js +8 -247
  3. package/dist/components/FileUpload.native.js +13 -0
  4. package/dist/components/Icons.js +10 -33
  5. package/dist/components/Icons.native.js +16 -0
  6. package/dist/components/ImagesSkeleton.js +7 -15
  7. package/dist/components/ImagesSkeleton.native.js +13 -0
  8. package/dist/components/MediaGallery.js +8 -148
  9. package/dist/components/MediaGallery.native.js +13 -0
  10. package/dist/components/MediaPopup.js +8 -99
  11. package/dist/components/MediaPopup.native.js +13 -0
  12. package/dist/components/MediaTab.js +7 -180
  13. package/dist/components/MediaTab.native.js +13 -0
  14. package/dist/components/Pagination.js +8 -136
  15. package/dist/components/Pagination.native.js +13 -0
  16. package/dist/components/VideosGallery.js +8 -148
  17. package/dist/components/VideosGallery.native.js +13 -0
  18. package/dist/core/MediaApiService.js +396 -0
  19. package/dist/esm/components/FileUpload.js +1 -246
  20. package/dist/esm/components/FileUpload.native.js +1 -0
  21. package/dist/esm/components/Icons.js +1 -32
  22. package/dist/esm/components/Icons.native.js +1 -0
  23. package/dist/esm/components/ImagesSkeleton.js +1 -14
  24. package/dist/esm/components/ImagesSkeleton.native.js +1 -0
  25. package/dist/esm/components/MediaGallery.js +1 -144
  26. package/dist/esm/components/MediaGallery.native.js +1 -0
  27. package/dist/esm/components/MediaPopup.js +1 -97
  28. package/dist/esm/components/MediaPopup.native.js +1 -0
  29. package/dist/esm/components/MediaTab.js +1 -177
  30. package/dist/esm/components/MediaTab.native.js +1 -0
  31. package/dist/esm/components/Pagination.js +1 -134
  32. package/dist/esm/components/Pagination.native.js +1 -0
  33. package/dist/esm/components/VideosGallery.js +1 -144
  34. package/dist/esm/components/VideosGallery.native.js +1 -0
  35. package/dist/esm/core/MediaApiService.js +390 -0
  36. package/dist/esm/index.js +1 -1
  37. package/dist/esm/native/FileUpload.native.js +298 -0
  38. package/dist/esm/native/Icons.native.js +51 -0
  39. package/dist/esm/native/ImagesSkeleton.native.js +45 -0
  40. package/dist/esm/native/MediaGallery.native.js +221 -0
  41. package/dist/esm/native/MediaPopup.native.js +151 -0
  42. package/dist/esm/native/MediaTab.native.js +175 -0
  43. package/dist/esm/native/Pagination.native.js +186 -0
  44. package/dist/esm/native/VideosGallery.native.js +233 -0
  45. package/dist/esm/services/apiService.js +1 -372
  46. package/dist/esm/web/FileUpload.web.js +253 -0
  47. package/dist/esm/web/Icons.web.js +32 -0
  48. package/dist/esm/web/ImagesSkeleton.web.js +14 -0
  49. package/dist/esm/web/MediaGallery.web.js +144 -0
  50. package/dist/esm/web/MediaPopup.web.js +97 -0
  51. package/dist/esm/web/MediaTab.web.js +177 -0
  52. package/dist/esm/web/Pagination.web.js +134 -0
  53. package/dist/esm/web/VideosGallery.web.js +144 -0
  54. package/dist/index.js +2 -2
  55. package/dist/native/FileUpload.native.js +304 -0
  56. package/dist/native/Icons.native.js +59 -0
  57. package/dist/native/ImagesSkeleton.native.js +52 -0
  58. package/dist/native/MediaGallery.native.js +230 -0
  59. package/dist/native/MediaPopup.native.js +158 -0
  60. package/dist/native/MediaTab.native.js +184 -0
  61. package/dist/native/Pagination.native.js +193 -0
  62. package/dist/native/VideosGallery.native.js +241 -0
  63. package/dist/services/apiService.js +2 -372
  64. package/dist/web/FileUpload.web.js +259 -0
  65. package/dist/web/Icons.web.js +39 -0
  66. package/dist/web/ImagesSkeleton.web.js +21 -0
  67. package/dist/web/MediaGallery.web.js +153 -0
  68. package/dist/web/MediaPopup.web.js +104 -0
  69. package/dist/web/MediaTab.web.js +186 -0
  70. package/dist/web/Pagination.web.js +141 -0
  71. package/dist/web/VideosGallery.web.js +153 -0
  72. package/package.json +4 -3
package/README.md CHANGED
@@ -10,9 +10,10 @@ videos, files) with Tradly authentication support.
10
10
  - 📁 Upload and browse files
11
11
  - 🔐 Tradly authentication support
12
12
  - 🎨 Customizable UI
13
- - 📱 Responsive design
13
+ - 📱 Responsive design (Web) + Native mobile support (React Native)
14
14
  - 🔄 Pagination support
15
15
  - ⚡ Lightweight and performant
16
+ - 🌐 **Cross-platform**: Works on Web (React) and Mobile (React Native)
16
17
 
17
18
  ## Installation
18
19
 
@@ -24,20 +25,33 @@ yarn add @tradly/asset
24
25
 
25
26
  ## Peer Dependencies
26
27
 
27
- This package requires the following peer dependencies:
28
+ ### Web (React)
28
29
 
29
30
  - `react` (>=16.8.0)
30
31
  - `react-dom` (>=16.8.0)
31
- - `@headlessui/react` (^1.7.0) - for Tab components
32
32
  - `axios` (^0.24.0) - for API calls
33
33
 
34
+ ### React Native
35
+
36
+ - `react` (>=16.8.0)
37
+ - `react-native` (>=0.60.0)
38
+ - `axios` (^0.24.0) - for API calls
39
+ - **File Picker Library** (choose one):
40
+ - `react-native-image-picker` - Recommended for React Native CLI
41
+ - `expo-image-picker` - For Expo projects
42
+ - Any other picker library that returns `{ uri, type, fileName }` format
43
+
34
44
  **Note:**
35
45
 
36
46
  - All pagination logic is built-in, no external pagination library needed!
37
47
  - No Tradly SDK dependency - uses direct API calls
48
+ - **React Native**: File picker is configurable - you choose which library to
49
+ use
38
50
 
39
51
  ## Basic Usage
40
52
 
53
+ ### Web (React)
54
+
41
55
  ```jsx
42
56
  import React, { useState } from "react";
43
57
  import { MediaPopup, MediaApiService } from "@tradly/asset";
@@ -80,6 +94,154 @@ function MyComponent() {
80
94
  }
81
95
  ```
82
96
 
97
+ ### React Native
98
+
99
+ ```jsx
100
+ import React, { useState } from "react";
101
+ import { View, Button } from "react-native";
102
+ import { MediaPopup, MediaApiService } from "@tradly/asset";
103
+ import { launchImageLibrary } from "react-native-image-picker";
104
+
105
+ function MyComponent() {
106
+ const [isOpen, setIsOpen] = useState(false);
107
+ const [selectedMedia, setSelectedMedia] = useState(null);
108
+
109
+ const apiService = new MediaApiService({
110
+ authKey: "your-tradly-auth-key",
111
+ bearerToken: "your-bearer-token",
112
+ environment: "dev", // or "production"
113
+ });
114
+
115
+ const handleSelect = (mediaUrl) => {
116
+ setSelectedMedia(mediaUrl);
117
+ setIsOpen(false);
118
+ };
119
+
120
+ // Configure file picker - REQUIRED for React Native
121
+ const picker = (options) => {
122
+ return new Promise((resolve) => {
123
+ launchImageLibrary(options, (response) => {
124
+ resolve(response.assets || []);
125
+ });
126
+ });
127
+ };
128
+
129
+ return (
130
+ <View>
131
+ <Button
132
+ title="Open Media Gallery"
133
+ onPress={() => setIsOpen(true)}
134
+ />
135
+
136
+ <MediaPopup
137
+ isOpen={isOpen}
138
+ onClose={() => setIsOpen(false)}
139
+ onSelect={handleSelect}
140
+ options={["image", "video"]}
141
+ apiService={apiService}
142
+ picker={picker} // REQUIRED: Your file picker function
143
+ />
144
+ </View>
145
+ );
146
+ }
147
+ ```
148
+
149
+ ## React Native Setup
150
+
151
+ ### File Picker Configuration
152
+
153
+ React Native requires you to provide a file picker function. The package
154
+ supports any picker library that returns files in the format
155
+ `{ uri, type, fileName }`.
156
+
157
+ #### Option 1: Using react-native-image-picker
158
+
159
+ ```bash
160
+ npm install react-native-image-picker
161
+ # or
162
+ yarn add react-native-image-picker
163
+ ```
164
+
165
+ ```jsx
166
+ import { launchImageLibrary } from "react-native-image-picker";
167
+
168
+ <MediaPopup
169
+ picker={(options) => {
170
+ return new Promise((resolve) => {
171
+ launchImageLibrary(options, (response) => {
172
+ if (response.didCancel) {
173
+ resolve([]);
174
+ return;
175
+ }
176
+ resolve(response.assets || []);
177
+ });
178
+ });
179
+ }}
180
+ apiService={apiService}
181
+ // ... other props
182
+ />;
183
+ ```
184
+
185
+ #### Option 2: Using expo-image-picker
186
+
187
+ ```bash
188
+ npx expo install expo-image-picker
189
+ ```
190
+
191
+ ```jsx
192
+ import * as ImagePicker from "expo-image-picker";
193
+
194
+ <MediaPopup
195
+ picker={async (options) => {
196
+ const result = await ImagePicker.launchImageLibraryAsync({
197
+ mediaTypes:
198
+ options.mediaType === "photo"
199
+ ? ImagePicker.MediaTypeOptions.Images
200
+ : options.mediaType === "video"
201
+ ? ImagePicker.MediaTypeOptions.Videos
202
+ : ImagePicker.MediaTypeOptions.All,
203
+ allowsMultipleSelection: options.allowsMultiple,
204
+ quality: options.quality,
205
+ });
206
+
207
+ if (result.canceled) {
208
+ return [];
209
+ }
210
+
211
+ return result.assets || [];
212
+ }}
213
+ apiService={apiService}
214
+ // ... other props
215
+ />;
216
+ ```
217
+
218
+ #### Option 3: Custom Picker Options
219
+
220
+ You can customize picker options based on the accept type:
221
+
222
+ ```jsx
223
+ <MediaPopup
224
+ picker={yourPickerFunction}
225
+ pickerOptions={(accept) => ({
226
+ mediaType: accept?.includes("image") ? "photo" : "video",
227
+ quality: 0.9,
228
+ allowsMultiple: true,
229
+ // Add any other options your picker library supports
230
+ })}
231
+ apiService={apiService}
232
+ // ... other props
233
+ />
234
+ ```
235
+
236
+ ### React Native UI Differences
237
+
238
+ - **Bottom Sheet**: Media gallery opens as a bottom sheet (slides up from
239
+ bottom)
240
+ - **Native Styling**: Uses React Native `StyleSheet` instead of Tailwind CSS
241
+ - **Components**: Uses React Native primitives (`View`, `Text`,
242
+ `TouchableOpacity`, `FlatList`, `Image`)
243
+ - **File Upload**: Requires `picker` prop to be provided
244
+
83
245
  ## Advanced Usage
84
246
 
85
247
  ### Upload Functionality
@@ -179,19 +341,31 @@ apiService.setBearerToken("new-bearer-token");
179
341
 
180
342
  ### MediaPopup Props
181
343
 
182
- | Prop | Type | Default | Description |
183
- | ------------- | ----------------- | ----------------- | --------------------------------------------------- |
184
- | `isOpen` | `boolean` | `false` | Controls popup visibility |
185
- | `onClose` | `function` | - | Callback when popup closes |
186
- | `onSelect` | `function` | - | Callback when media is selected |
187
- | `currentData` | `any` | - | Currently selected media data |
188
- | `options` | `array` | `['image']` | Media types to show: `'image'`, `'video'`, `'file'` |
189
- | `apiService` | `MediaApiService` | - | **Required**: API service instance |
190
- | `onError` | `function` | - | Error handler callback |
191
- | `title` | `string` | `'Media Gallery'` | Popup title |
344
+ | Prop | Type | Default | Description | Platform |
345
+ | --------------- | ----------------- | ----------------- | --------------------------------------------------- | ------------ |
346
+ | `isOpen` | `boolean` | `false` | Controls popup visibility | Web & Native |
347
+ | `onClose` | `function` | - | Callback when popup closes | Web & Native |
348
+ | `onSelect` | `function` | - | Callback when media is selected | Web & Native |
349
+ | `currentData` | `any` | - | Currently selected media data | Web & Native |
350
+ | `options` | `array` | `['image']` | Media types to show: `'image'`, `'video'`, `'file'` | Web & Native |
351
+ | `apiService` | `MediaApiService` | - | **Required**: API service instance | Web & Native |
352
+ | `onError` | `function` | - | Error handler callback | Web & Native |
353
+ | `title` | `string` | `'Media Gallery'` | Popup title | Web & Native |
354
+ | `picker` | `function` | - | **Required for React Native**: File picker function | Native only |
355
+ | `pickerOptions` | `function` | - | Optional: Function to generate picker options | Native only |
356
+
357
+ **React Native Required Props:**
358
+
359
+ - `picker`: A function that accepts options and returns a Promise resolving to
360
+ an array of file objects
361
+ - Each file object should have:
362
+ `{ uri: string, type?: string, fileName?: string }`
363
+ - Example: `picker={(options) => launchImageLibrary(options, callback)}`
192
364
 
193
365
  ## Styling
194
366
 
367
+ ### Web (React)
368
+
195
369
  This package uses Tailwind CSS classes and supports full customization at every
196
370
  component level. All components accept `className` props that allow you to
197
371
  override default styles.
@@ -237,6 +411,38 @@ override default styles.
237
411
  **Individual Components:** You can also style individual components when using
238
412
  them separately. See `STYLING_GUIDE.md` for complete documentation.
239
413
 
414
+ ### React Native
415
+
416
+ React Native components use `StyleSheet` for styling. You can customize styles
417
+ using style props:
418
+
419
+ ```jsx
420
+ <MediaPopup
421
+ apiService={apiService}
422
+ picker={picker}
423
+ // Customize styles
424
+ containerStyle={{ backgroundColor: "#F5F5F5" }}
425
+ headerStyle={{ padding: 20 }}
426
+ titleStyle={{ fontSize: 28, color: "#000" }}
427
+ // ... other props
428
+ />
429
+ ```
430
+
431
+ **Available Style Props (React Native):**
432
+
433
+ - `containerStyle` - Main popup container
434
+ - `headerStyle` - Header container
435
+ - `titleStyle` - Title text
436
+ - `closeButtonStyle` - Close button
437
+ - `tabListStyle` - Tab list
438
+ - `tabButtonStyle` - Base tab button
439
+ - `tabButtonActiveStyle` - Active tab button
440
+ - `tabButtonInactiveStyle` - Inactive tab button
441
+ - `gridStyle` - Media grid layout
442
+ - `imageItemStyle` - Image item styles
443
+ - `videoItemStyle` - Video item styles
444
+ - `paginationContainerStyle` - Pagination container
445
+
240
446
  ### Full Styling Guide
241
447
 
242
448
  For detailed styling documentation with examples, see
@@ -270,6 +476,8 @@ For detailed styling documentation with examples, see
270
476
 
271
477
  ### All Media Types
272
478
 
479
+ **Web:**
480
+
273
481
  ```jsx
274
482
  <MediaPopup
275
483
  isOpen={isOpen}
@@ -280,6 +488,36 @@ For detailed styling documentation with examples, see
280
488
  />
281
489
  ```
282
490
 
491
+ **React Native:**
492
+
493
+ ```jsx
494
+ <MediaPopup
495
+ isOpen={isOpen}
496
+ onClose={() => setIsOpen(false)}
497
+ onSelect={handleSelect}
498
+ options={["image", "video", "file"]}
499
+ apiService={apiService}
500
+ picker={picker} // Required
501
+ />
502
+ ```
503
+
504
+ ## Platform-Specific Notes
505
+
506
+ ### Web (React)
507
+
508
+ - Uses `react-dom` for portal rendering
509
+ - Tailwind CSS for styling
510
+ - HTML file input for file selection
511
+ - Canvas API for image compression
512
+
513
+ ### React Native
514
+
515
+ - Uses `Modal` component for bottom sheet
516
+ - React Native `StyleSheet` for styling
517
+ - Requires file picker library (configurable)
518
+ - Uses `FlatList` for efficient media rendering
519
+ - Supports both iOS and Android
520
+
283
521
  ## Development
284
522
 
285
523
  To develop or modify this package:
@@ -290,6 +528,12 @@ npm install
290
528
  npm run dev
291
529
  ```
292
530
 
531
+ **Note:** The package automatically detects the platform and uses the
532
+ appropriate components:
533
+
534
+ - Web bundlers will use `.web.jsx` files
535
+ - React Native bundlers (Metro) will use `.native.jsx` files
536
+
293
537
  ## License
294
538
 
295
539
  MIT
@@ -1,252 +1,13 @@
1
1
  "use strict";
2
2
 
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
- exports.default = void 0;
8
- var _react = _interopRequireWildcard(require("react"));
9
- var _Icons = require("./Icons");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); }
12
- function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
13
- function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
14
- function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
15
- function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
16
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
17
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
18
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
19
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
20
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
21
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } // Helper: compress image on the client before upload
22
- // - Downscale to fit within maxWidth/maxHeight.
23
- // - Convert raster images (JPEG/PNG, etc.) to WebP for better compression.
24
- // - Skip SVG (vector) to avoid degradation.
25
- var compressImage = function compressImage(file) {
26
- var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
27
- _ref$maxWidth = _ref.maxWidth,
28
- maxWidth = _ref$maxWidth === void 0 ? 1600 : _ref$maxWidth,
29
- _ref$maxHeight = _ref.maxHeight,
30
- maxHeight = _ref$maxHeight === void 0 ? 1600 : _ref$maxHeight,
31
- _ref$quality = _ref.quality,
32
- quality = _ref$quality === void 0 ? 1 : _ref$quality,
33
- _ref$convertToWebp = _ref.convertToWebp,
34
- convertToWebp = _ref$convertToWebp === void 0 ? true : _ref$convertToWebp;
35
- return new Promise(function (resolve) {
36
- // Non-image or SVG: skip compression to avoid losing vector quality
37
- if (!file.type.startsWith("image/") || file.type === "image/svg+xml") {
38
- resolve(file);
39
- return;
40
- }
41
- var img = new Image();
42
- img.onload = function () {
43
- var width = img.width,
44
- height = img.height;
45
-
46
- // If the image is already small, keep it as-is
47
- if (width <= maxWidth && height <= maxHeight) {
48
- resolve(file);
49
- return;
50
- }
51
- var scale = Math.min(maxWidth / width, maxHeight / height);
52
- var targetWidth = Math.round(width * scale);
53
- var targetHeight = Math.round(height * scale);
54
- var canvas = document.createElement("canvas");
55
- canvas.width = targetWidth;
56
- canvas.height = targetHeight;
57
- var ctx = canvas.getContext("2d");
58
- if (!ctx) {
59
- resolve(file);
60
- return;
61
- }
62
- ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
63
-
64
- // Prefer WebP for raster images to reduce size (where supported)
65
- // Keep original type for GIF to avoid breaking animation.
66
- var isRaster = file.type === "image/jpeg" || file.type === "image/jpg" || file.type === "image/png" || file.type === "image/webp" || file.type === "image/heic" || file.type === "image/heif";
67
- var targetType = convertToWebp && isRaster && file.type !== "image/gif" ? "image/webp" : file.type;
68
- canvas.toBlob(function (blob) {
69
- if (!blob) {
70
- resolve(file);
71
- return;
72
- }
73
- var compressedFile = new File([blob], file.name, {
74
- type: targetType,
75
- lastModified: Date.now()
76
- });
77
- resolve(compressedFile);
78
- }, targetType, quality);
79
- };
80
- img.onerror = function () {
81
- resolve(file);
82
- };
83
- var reader = new FileReader();
84
- reader.onload = function (event) {
85
- var _event$target;
86
- img.src = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result;
87
- };
88
- reader.onerror = function () {
89
- return resolve(file);
90
- };
91
- reader.readAsDataURL(file);
92
- });
93
- };
94
- var FileUpload = function FileUpload(_ref2) {
95
- var loadMedia = _ref2.loadMedia,
96
- accept = _ref2.accept,
97
- title = _ref2.title,
98
- apiService = _ref2.apiService,
99
- onUploadStart = _ref2.onUploadStart,
100
- onUploadComplete = _ref2.onUploadComplete,
101
- onUploadError = _ref2.onUploadError,
102
- className = _ref2.className,
103
- buttonClassName = _ref2.buttonClassName,
104
- iconContainerClassName = _ref2.iconContainerClassName,
105
- titleClassName = _ref2.titleClassName,
106
- loadingClassName = _ref2.loadingClassName;
107
- var _useState = (0, _react.useState)([]),
108
- _useState2 = _slicedToArray(_useState, 2),
109
- files = _useState2[0],
110
- setFiles = _useState2[1];
111
- var _useState3 = (0, _react.useState)(false),
112
- _useState4 = _slicedToArray(_useState3, 2),
113
- isLoading = _useState4[0],
114
- setISLoading = _useState4[1];
115
- var _useState5 = (0, _react.useState)(0),
116
- _useState6 = _slicedToArray(_useState5, 2),
117
- length = _useState6[0],
118
- setLength = _useState6[1];
119
-
120
- // Upload files
121
- var uploadFiles = /*#__PURE__*/function () {
122
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
123
- var filesToUpload, uploadedUrls, _t;
124
- return _regenerator().w(function (_context) {
125
- while (1) switch (_context.p = _context.n) {
126
- case 0:
127
- if (onUploadStart) {
128
- onUploadStart(fileList);
129
- }
130
- setISLoading(true);
131
- setLength(fileList.length);
132
- _context.p = 1;
133
- filesToUpload = fileList; // For image uploads, compress on the client before sending
134
- if (!(accept && accept.includes("image"))) {
135
- _context.n = 3;
136
- break;
137
- }
138
- _context.n = 2;
139
- return Promise.all(fileList.map(function (file) {
140
- return compressImage(file, {
141
- maxWidth: 1600,
142
- maxHeight: 1600,
143
- quality: 0.95,
144
- convertToWebp: true
145
- });
146
- }));
147
- case 2:
148
- filesToUpload = _context.v;
149
- case 3:
150
- _context.n = 4;
151
- return apiService.uploadMedia(filesToUpload, apiService.authKey);
152
- case 4:
153
- uploadedUrls = _context.v;
154
- if (onUploadComplete) {
155
- onUploadComplete(uploadedUrls);
156
- }
157
- setLength(0);
158
- if (loadMedia) {
159
- loadMedia();
160
- }
161
- _context.n = 6;
162
- break;
163
- case 5:
164
- _context.p = 5;
165
- _t = _context.v;
166
- console.error("Upload error:", _t);
167
- if (onUploadError) {
168
- onUploadError(_t);
169
- }
170
- case 6:
171
- _context.p = 6;
172
- setISLoading(false);
173
- return _context.f(6);
174
- case 7:
175
- return _context.a(2);
176
- }
177
- }, _callee, null, [[1, 5, 6, 7]]);
178
- }));
179
- return function uploadFiles(_x) {
180
- return _ref3.apply(this, arguments);
181
- };
182
- }();
183
-
184
- // Default classes with customization support
185
- var defaultContainerClass = "min-w-40 h-40";
186
- var defaultButtonClass = "w-full h-full flex flex-col justify-center items-center text-sm border border-primary border-dashed rounded-lg hover:bg-gray-50 transition-colors";
187
- var defaultIconContainerClass = "p-[10px] bg-primary rounded-full";
188
- var defaultTitleClass = "mt-2";
189
- var defaultLoadingClass = "flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse";
190
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
191
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
192
- className: className || defaultContainerClass,
193
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
194
- required: true,
195
- id: "media_select_".concat(files === null || files === void 0 ? void 0 : files.length),
196
- type: "file",
197
- className: "hidden",
198
- accept: accept,
199
- placeholder: "",
200
- onChange: (/*#__PURE__*/function () {
201
- var _ref4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
202
- var all_files;
203
- return _regenerator().w(function (_context2) {
204
- while (1) switch (_context2.n) {
205
- case 0:
206
- e.stopPropagation();
207
- all_files = Array.from(e.target.files || []);
208
- if (!((all_files === null || all_files === void 0 ? void 0 : all_files.length) > 0)) {
209
- _context2.n = 1;
210
- break;
211
- }
212
- _context2.n = 1;
213
- return uploadFiles(all_files);
214
- case 1:
215
- // Reset input
216
- e.target.value = "";
217
- case 2:
218
- return _context2.a(2);
219
- }
220
- }, _callee2);
221
- }));
222
- return function (_x2) {
223
- return _ref4.apply(this, arguments);
224
- };
225
- }()),
226
- multiple: true
227
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
228
- type: "button",
229
- className: buttonClassName || defaultButtonClass,
230
- onClick: function onClick() {
231
- return document.getElementById("media_select_".concat(files === null || files === void 0 ? void 0 : files.length)).click();
232
- },
233
- disabled: isLoading,
234
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
235
- className: iconContainerClassName || defaultIconContainerClass,
236
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icons.CameraIcon, {})
237
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
238
- className: titleClassName || defaultTitleClass,
239
- children: title
240
- })]
241
- })]
242
- }), isLoading && Array.from({
243
- length: length
244
- }).map(function (_, index) {
245
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
246
- className: loadingClassName || defaultLoadingClass,
247
- children: ["File Uploading... ", index + 1, "/", length]
248
- }, index);
249
- })]
250
- });
251
- };
252
- var _default = exports.default = FileUpload;
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _FileUpload.default;
10
+ }
11
+ });
12
+ var _FileUpload = _interopRequireDefault(require("../web/FileUpload.web"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _FileUpload.default;
10
+ }
11
+ });
12
+ var _FileUpload = _interopRequireDefault(require("../native/FileUpload.native"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -3,37 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.CloseIcon = exports.CameraIcon = void 0;
7
- var _react = _interopRequireDefault(require("react"));
8
- var _jsxRuntime = require("react/jsx-runtime");
9
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
- var CloseIcon = exports.CloseIcon = function CloseIcon(_ref) {
11
- var _ref$className = _ref.className,
12
- className = _ref$className === void 0 ? 'w-8 h-8' : _ref$className;
13
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
14
- xmlns: "http://www.w3.org/2000/svg",
15
- fill: "none",
16
- viewBox: "0 0 24 24",
17
- strokeWidth: "1.5",
18
- stroke: "currentColor",
19
- className: className,
20
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
21
- strokeLinecap: "round",
22
- strokeLinejoin: "round",
23
- d: "M6 18L18 6M6 6l12 12"
24
- })
6
+ var _Icons = require("../web/Icons.web");
7
+ Object.keys(_Icons).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _Icons[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function get() {
13
+ return _Icons[key];
14
+ }
25
15
  });
26
- };
27
- var CameraIcon = exports.CameraIcon = function CameraIcon() {
28
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
29
- width: "22",
30
- height: "18",
31
- viewBox: "0 0 22 20",
32
- fill: "none",
33
- xmlns: "http://www.w3.org/2000/svg",
34
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
35
- d: "M7.75033 0.166672L5.76783 2.33334H2.33366C1.14199 2.33334 0.166992 3.30834 0.166992 4.50001V17.5C0.166992 18.6917 1.14199 19.6667 2.33366 19.6667H19.667C20.8587 19.6667 21.8337 18.6917 21.8337 17.5V4.50001C21.8337 3.30834 20.8587 2.33334 19.667 2.33334H16.2328L14.2503 0.166672H7.75033ZM11.0003 16.4167C8.01033 16.4167 5.58366 13.99 5.58366 11C5.58366 8.01001 8.01033 5.58334 11.0003 5.58334C13.9903 5.58334 16.417 8.01001 16.417 11C16.417 13.99 13.9903 16.4167 11.0003 16.4167Z",
36
- fill: "white"
37
- })
38
- });
39
- };
16
+ });
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _Icons = require("../native/Icons.native");
7
+ Object.keys(_Icons).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _Icons[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function get() {
13
+ return _Icons[key];
14
+ }
15
+ });
16
+ });