@tradly/asset 1.0.13 → 1.0.15

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 (76) hide show
  1. package/README.md +414 -13
  2. package/dist/components/FileUpload.js +8 -254
  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 -253
  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 +4 -1
  37. package/dist/esm/native/FileUpload.native.js +310 -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 +228 -0
  41. package/dist/esm/native/MediaPopup.native.js +170 -0
  42. package/dist/esm/native/MediaTab.native.js +192 -0
  43. package/dist/esm/native/Pagination.native.js +210 -0
  44. package/dist/esm/native/THEME_EXAMPLE.js +112 -0
  45. package/dist/esm/native/VideosGallery.native.js +240 -0
  46. package/dist/esm/native/theme.js +167 -0
  47. package/dist/esm/services/apiService.js +1 -372
  48. package/dist/esm/web/FileUpload.web.js +253 -0
  49. package/dist/esm/web/Icons.web.js +32 -0
  50. package/dist/esm/web/ImagesSkeleton.web.js +14 -0
  51. package/dist/esm/web/MediaGallery.web.js +144 -0
  52. package/dist/esm/web/MediaPopup.web.js +97 -0
  53. package/dist/esm/web/MediaTab.web.js +177 -0
  54. package/dist/esm/web/Pagination.web.js +134 -0
  55. package/dist/esm/web/VideosGallery.web.js +144 -0
  56. package/dist/index.js +16 -2
  57. package/dist/native/FileUpload.native.js +316 -0
  58. package/dist/native/Icons.native.js +59 -0
  59. package/dist/native/ImagesSkeleton.native.js +52 -0
  60. package/dist/native/MediaGallery.native.js +237 -0
  61. package/dist/native/MediaPopup.native.js +177 -0
  62. package/dist/native/MediaTab.native.js +201 -0
  63. package/dist/native/Pagination.native.js +217 -0
  64. package/dist/native/THEME_EXAMPLE.js +117 -0
  65. package/dist/native/VideosGallery.native.js +248 -0
  66. package/dist/native/theme.js +173 -0
  67. package/dist/services/apiService.js +2 -372
  68. package/dist/web/FileUpload.web.js +259 -0
  69. package/dist/web/Icons.web.js +39 -0
  70. package/dist/web/ImagesSkeleton.web.js +21 -0
  71. package/dist/web/MediaGallery.web.js +153 -0
  72. package/dist/web/MediaPopup.web.js +104 -0
  73. package/dist/web/MediaTab.web.js +186 -0
  74. package/dist/web/Pagination.web.js +141 -0
  75. package/dist/web/VideosGallery.web.js +153 -0
  76. package/package.json +3 -2
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,273 @@ 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) - defaults to 90% of screen height, customizable
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
+ - **Theme System**: Full theme support for easy dark/light mode customization
245
+
246
+ ### React Native Theme & Customization
247
+
248
+ The package includes a comprehensive theme system that makes it easy to
249
+ customize colors, spacing, and styling for dark/light mode.
250
+
251
+ #### Basic Theme Usage
252
+
253
+ ```jsx
254
+ import { MediaPopup, MediaApiService } from "@tradly/asset";
255
+ import { createTheme } from "@tradly/asset/native/theme";
256
+
257
+ // Use dark mode
258
+ const darkTheme = createTheme({ mode: "dark" });
259
+
260
+ // Use light mode (default)
261
+ const lightTheme = createTheme({ mode: "light" });
262
+
263
+ <MediaPopup
264
+ apiService={apiService}
265
+ picker={picker}
266
+ theme={darkTheme} // Pass your theme
267
+ bottomSheetHeight={0.9} // 90% of screen (default), customize as needed
268
+ />;
269
+ ```
270
+
271
+ #### Custom Theme Colors
272
+
273
+ ```jsx
274
+ import { createTheme } from "@tradly/asset/native/theme";
275
+
276
+ const customTheme = createTheme({
277
+ mode: "dark", // or "light"
278
+ colors: {
279
+ // Primary colors
280
+ primary: "#6366F1",
281
+ tabActive: "#6366F1",
282
+ tabIndicator: "#6366F1",
283
+
284
+ // Backgrounds
285
+ background: "#0F172A",
286
+ backgroundSecondary: "#1E293B",
287
+
288
+ // Text
289
+ text: "#F1F5F9",
290
+ textSecondary: "#CBD5E1",
291
+
292
+ // Tabs
293
+ tabActive: "#6366F1",
294
+ tabInactive: "#94A3B8",
295
+ tabBackground: "#0F172A",
296
+
297
+ // Borders
298
+ border: "#334155",
299
+
300
+ // Pagination
301
+ paginationButtonActive: "#6366F1",
302
+ paginationTextActive: "#FFFFFF",
303
+
304
+ // Upload button
305
+ uploadBorder: "#6366F1",
306
+ uploadIconBackground: "#6366F1",
307
+
308
+ // And many more...
309
+ },
310
+ bottomSheetHeight: 0.92, // 92% of screen height
311
+ });
312
+
313
+ <MediaPopup theme={customTheme} ... />
314
+ ```
315
+
316
+ #### Available Theme Colors
317
+
318
+ All colors are customizable via the theme object:
319
+
320
+ - **Primary**: `primary`, `primaryLight`, `primaryDark`
321
+ - **Backgrounds**: `background`, `backgroundSecondary`, `backgroundTertiary`
322
+ - **Text**: `text`, `textSecondary`, `textTertiary`, `textInverse`
323
+ - **Borders**: `border`, `borderLight`, `borderDark`
324
+ - **Tabs**: `tabActive`, `tabInactive`, `tabIndicator`, `tabBackground`
325
+ - **Pagination**: `paginationBackground`, `paginationButton`,
326
+ `paginationButtonActive`, `paginationText`, `paginationTextActive`,
327
+ `paginationBorder`
328
+ - **Upload**: `uploadBorder`, `uploadBackground`, `uploadIconBackground`,
329
+ `uploadText`
330
+ - **Items**: `itemBackground`, `itemShadow`
331
+ - **Loading**: `loadingBackground`, `loadingText`
332
+ - **Overlay**: `overlay`
333
+
334
+ #### Customizing Bottom Sheet Height
335
+
336
+ ```jsx
337
+ <MediaPopup
338
+ bottomSheetHeight={0.85} // 85% of screen height
339
+ // or via theme:
340
+ theme={createTheme({ bottomSheetHeight: 0.92 })}
341
+ />
342
+ ```
343
+
344
+ #### Individual Component Styling
345
+
346
+ You can also override individual component styles:
347
+
348
+ ```jsx
349
+ <MediaPopup
350
+ theme={darkTheme}
351
+ // Override specific styles
352
+ containerStyle={{ padding: 24 }}
353
+ headerStyle={{ paddingBottom: 16 }}
354
+ titleStyle={{ fontSize: 28 }}
355
+ closeButtonStyle={{ padding: 12 }}
356
+ tabListStyle={{ paddingHorizontal: 8 }}
357
+ tabButtonStyle={{ paddingVertical: 16 }}
358
+ tabButtonActiveStyle={{ backgroundColor: "#F0F0F0" }}
359
+ tabButtonTextActiveStyle={{ fontWeight: "700" }}
360
+ // ... and many more style props
361
+ />
362
+ ```
363
+
83
364
  ## Advanced Usage
84
365
 
85
366
  ### Upload Functionality
@@ -179,19 +460,33 @@ apiService.setBearerToken("new-bearer-token");
179
460
 
180
461
  ### MediaPopup Props
181
462
 
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 |
463
+ | Prop | Type | Default | Description | Platform |
464
+ | ------------------- | ----------------- | ----------------- | --------------------------------------------------- | ------------ |
465
+ | `isOpen` | `boolean` | `false` | Controls popup visibility | Web & Native |
466
+ | `onClose` | `function` | - | Callback when popup closes | Web & Native |
467
+ | `onSelect` | `function` | - | Callback when media is selected | Web & Native |
468
+ | `currentData` | `any` | - | Currently selected media data | Web & Native |
469
+ | `options` | `array` | `['image']` | Media types to show: `'image'`, `'video'`, `'file'` | Web & Native |
470
+ | `apiService` | `MediaApiService` | - | **Required**: API service instance | Web & Native |
471
+ | `onError` | `function` | - | Error handler callback | Web & Native |
472
+ | `title` | `string` | `'Media Gallery'` | Popup title | Web & Native |
473
+ | `picker` | `function` | - | **Required for React Native**: File picker function | Native only |
474
+ | `pickerOptions` | `function` | - | Optional: Function to generate picker options | Native only |
475
+ | `theme` | `object` | - | Theme object for colors/spacing (see Theme docs) | Native only |
476
+ | `bottomSheetHeight` | `number` | `0.9` | Bottom sheet height (0.85 = 85%, 0.9 = 90%, etc.) | Native only |
477
+
478
+ **React Native Required Props:**
479
+
480
+ - `picker`: A function that accepts options and returns a Promise resolving to
481
+ an array of file objects
482
+ - Each file object should have:
483
+ `{ uri: string, type?: string, fileName?: string }`
484
+ - Example: `picker={(options) => launchImageLibrary(options, callback)}`
192
485
 
193
486
  ## Styling
194
487
 
488
+ ### Web (React)
489
+
195
490
  This package uses Tailwind CSS classes and supports full customization at every
196
491
  component level. All components accept `className` props that allow you to
197
492
  override default styles.
@@ -237,6 +532,74 @@ override default styles.
237
532
  **Individual Components:** You can also style individual components when using
238
533
  them separately. See `STYLING_GUIDE.md` for complete documentation.
239
534
 
535
+ ### React Native
536
+
537
+ React Native components use `StyleSheet` for styling. You can customize styles
538
+ using style props:
539
+
540
+ ```jsx
541
+ <MediaPopup
542
+ apiService={apiService}
543
+ picker={picker}
544
+ // Customize styles
545
+ containerStyle={{ backgroundColor: "#F5F5F5" }}
546
+ headerStyle={{ padding: 20 }}
547
+ titleStyle={{ fontSize: 28, color: "#000" }}
548
+ // ... other props
549
+ />
550
+ ```
551
+
552
+ **Available Style Props (React Native):**
553
+
554
+ **MediaPopup:**
555
+
556
+ - `overlayStyle` - Overlay/backdrop
557
+ - `containerStyle` - Main popup container
558
+ - `headerStyle` - Header container
559
+ - `titleStyle` - Title text
560
+ - `closeButtonStyle` - Close button
561
+ - `closeButtonTextStyle` - Close button text/icon
562
+
563
+ **MediaTab:**
564
+
565
+ - `containerStyle` - Tab container
566
+ - `tabListStyle` - Tab list
567
+ - `tabButtonStyle` - Base tab button
568
+ - `tabButtonActiveStyle` - Active tab button
569
+ - `tabButtonInactiveStyle` - Inactive tab button
570
+ - `tabButtonTextStyle` - Base tab text
571
+ - `tabButtonTextActiveStyle` - Active tab text
572
+ - `tabButtonTextInactiveStyle` - Inactive tab text
573
+ - `tabIndicatorStyle` - Tab indicator line
574
+ - `tabPanelStyle` - Tab panel container
575
+
576
+ **ImagesGallery/VideosGallery:**
577
+
578
+ - `containerStyle` - Gallery container
579
+ - `gridStyle` - Media grid layout
580
+ - `imageItemStyle` / `videoItemStyle` - Media item styles
581
+ - `paginationContainerStyle` - Pagination container
582
+
583
+ **FileUpload:**
584
+
585
+ - `containerStyle` - Upload container
586
+ - `buttonStyle` - Upload button
587
+ - `iconContainerStyle` - Icon container
588
+ - `titleStyle` - Upload title text
589
+ - `loadingStyle` - Loading state container
590
+
591
+ **Pagination:**
592
+
593
+ - `containerStyle` - Pagination container
594
+ - `navStyle` - Navigation container
595
+ - `previousButtonStyle` - Previous button
596
+ - `nextButtonStyle` - Next button
597
+ - `pageButtonStyle` - Page number button
598
+ - `pageButtonActiveStyle` - Active page button
599
+ - `pageButtonTextStyle` - Page button text
600
+ - `pageButtonTextActiveStyle` - Active page text
601
+ - `ellipsisStyle` - Ellipsis container
602
+
240
603
  ### Full Styling Guide
241
604
 
242
605
  For detailed styling documentation with examples, see
@@ -270,6 +633,20 @@ For detailed styling documentation with examples, see
270
633
 
271
634
  ### All Media Types
272
635
 
636
+ **Web:**
637
+
638
+ ```jsx
639
+ <MediaPopup
640
+ isOpen={isOpen}
641
+ onClose={() => setIsOpen(false)}
642
+ onSelect={handleSelect}
643
+ options={["image", "video", "file"]}
644
+ apiService={apiService}
645
+ />
646
+ ```
647
+
648
+ **React Native:**
649
+
273
650
  ```jsx
274
651
  <MediaPopup
275
652
  isOpen={isOpen}
@@ -277,9 +654,27 @@ For detailed styling documentation with examples, see
277
654
  onSelect={handleSelect}
278
655
  options={["image", "video", "file"]}
279
656
  apiService={apiService}
657
+ picker={picker} // Required
280
658
  />
281
659
  ```
282
660
 
661
+ ## Platform-Specific Notes
662
+
663
+ ### Web (React)
664
+
665
+ - Uses `react-dom` for portal rendering
666
+ - Tailwind CSS for styling
667
+ - HTML file input for file selection
668
+ - Canvas API for image compression
669
+
670
+ ### React Native
671
+
672
+ - Uses `Modal` component for bottom sheet
673
+ - React Native `StyleSheet` for styling
674
+ - Requires file picker library (configurable)
675
+ - Uses `FlatList` for efficient media rendering
676
+ - Supports both iOS and Android
677
+
283
678
  ## Development
284
679
 
285
680
  To develop or modify this package:
@@ -290,6 +685,12 @@ npm install
290
685
  npm run dev
291
686
  ```
292
687
 
688
+ **Note:** The package automatically detects the platform and uses the
689
+ appropriate components:
690
+
691
+ - Web bundlers will use `.web.jsx` files
692
+ - React Native bundlers (Metro) will use `.native.jsx` files
693
+
293
694
  ## License
294
695
 
295
696
  MIT