@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
@@ -0,0 +1,170 @@
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ 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."); }
3
+ 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; } }
4
+ 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; }
5
+ 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; } }
6
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
+ import React from 'react';
8
+ import { Modal, View, Text, TouchableOpacity, StyleSheet, Dimensions, Animated, TouchableWithoutFeedback } from 'react-native';
9
+ import MediaTab from './MediaTab.native';
10
+ import { CloseIcon } from './Icons.native';
11
+ import { createTheme } from './theme';
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ var _Dimensions$get = Dimensions.get('window'),
14
+ SCREEN_HEIGHT = _Dimensions$get.height;
15
+ var MediaPopup = function MediaPopup(_ref) {
16
+ var isOpen = _ref.isOpen,
17
+ onClose = _ref.onClose,
18
+ onSelect = _ref.onSelect,
19
+ currentData = _ref.currentData,
20
+ _ref$options = _ref.options,
21
+ options = _ref$options === void 0 ? ['image'] : _ref$options,
22
+ apiService = _ref.apiService,
23
+ onError = _ref.onError,
24
+ _ref$title = _ref.title,
25
+ title = _ref$title === void 0 ? 'Media Gallery' : _ref$title,
26
+ picker = _ref.picker,
27
+ pickerOptions = _ref.pickerOptions,
28
+ theme = _ref.theme,
29
+ overlayStyle = _ref.overlayStyle,
30
+ containerStyle = _ref.containerStyle,
31
+ headerStyle = _ref.headerStyle,
32
+ titleStyle = _ref.titleStyle,
33
+ closeButtonStyle = _ref.closeButtonStyle,
34
+ closeButtonTextStyle = _ref.closeButtonTextStyle,
35
+ bottomSheetHeight = _ref.bottomSheetHeight;
36
+ var currentTheme = React.useMemo(function () {
37
+ return createTheme(theme);
38
+ }, [theme]);
39
+ var sheetHeight = bottomSheetHeight || currentTheme.bottomSheetHeight || 0.9;
40
+ var _React$useState = React.useState(new Animated.Value(SCREEN_HEIGHT)),
41
+ _React$useState2 = _slicedToArray(_React$useState, 1),
42
+ slideAnim = _React$useState2[0];
43
+ React.useEffect(function () {
44
+ if (isOpen) {
45
+ Animated.spring(slideAnim, {
46
+ toValue: 0,
47
+ useNativeDriver: true,
48
+ tension: 65,
49
+ friction: 11
50
+ }).start();
51
+ } else {
52
+ Animated.timing(slideAnim, {
53
+ toValue: SCREEN_HEIGHT,
54
+ duration: 250,
55
+ useNativeDriver: true
56
+ }).start();
57
+ }
58
+ }, [isOpen]);
59
+ var handleUpdate = function handleUpdate(data) {
60
+ if (onSelect) {
61
+ onSelect(data);
62
+ }
63
+ };
64
+ var handleClose = function handleClose() {
65
+ if (onClose) {
66
+ onClose();
67
+ }
68
+ };
69
+ if (!isOpen) return null;
70
+ return /*#__PURE__*/_jsx(Modal, {
71
+ visible: isOpen,
72
+ transparent: true,
73
+ animationType: "none",
74
+ onRequestClose: handleClose,
75
+ children: /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
76
+ onPress: handleClose,
77
+ children: /*#__PURE__*/_jsx(View, {
78
+ style: [styles.overlay, {
79
+ backgroundColor: currentTheme.colors.overlay
80
+ }, overlayStyle],
81
+ children: /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
82
+ children: /*#__PURE__*/_jsxs(Animated.View, {
83
+ style: [styles.container, {
84
+ backgroundColor: currentTheme.colors.background,
85
+ borderTopLeftRadius: currentTheme.radius.xxl,
86
+ borderTopRightRadius: currentTheme.radius.xxl,
87
+ maxHeight: SCREEN_HEIGHT * sheetHeight,
88
+ padding: currentTheme.spacing.xl
89
+ }, containerStyle, {
90
+ transform: [{
91
+ translateY: slideAnim
92
+ }]
93
+ }],
94
+ children: [/*#__PURE__*/_jsxs(View, {
95
+ style: [styles.header, {
96
+ borderBottomColor: currentTheme.colors.border,
97
+ marginBottom: currentTheme.spacing.lg,
98
+ paddingBottom: currentTheme.spacing.md
99
+ }, headerStyle],
100
+ children: [/*#__PURE__*/_jsx(Text, {
101
+ style: [styles.title, {
102
+ fontSize: currentTheme.typography.title.fontSize,
103
+ fontWeight: currentTheme.typography.title.fontWeight,
104
+ color: currentTheme.colors.text
105
+ }, titleStyle],
106
+ children: title
107
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
108
+ onPress: handleClose,
109
+ style: [styles.closeButton, closeButtonStyle],
110
+ hitSlop: {
111
+ top: 10,
112
+ bottom: 10,
113
+ left: 10,
114
+ right: 10
115
+ },
116
+ children: /*#__PURE__*/_jsx(CloseIcon, {
117
+ size: 24,
118
+ color: currentTheme.colors.text
119
+ })
120
+ })]
121
+ }), /*#__PURE__*/_jsx(MediaTab, {
122
+ imagePopup: isOpen,
123
+ update_data: handleUpdate,
124
+ current_data: currentData,
125
+ closePopup: handleClose,
126
+ options: options,
127
+ apiService: apiService,
128
+ onError: onError,
129
+ picker: picker,
130
+ pickerOptions: pickerOptions,
131
+ theme: currentTheme
132
+ })]
133
+ })
134
+ })
135
+ })
136
+ })
137
+ });
138
+ };
139
+ var styles = StyleSheet.create({
140
+ overlay: {
141
+ flex: 1,
142
+ justifyContent: 'flex-end'
143
+ },
144
+ container: {
145
+ minHeight: 200,
146
+ shadowColor: '#000',
147
+ shadowOffset: {
148
+ width: 0,
149
+ height: -2
150
+ },
151
+ shadowOpacity: 0.25,
152
+ shadowRadius: 3.84,
153
+ elevation: 5
154
+ },
155
+ header: {
156
+ flexDirection: 'row',
157
+ alignItems: 'center',
158
+ justifyContent: 'space-between',
159
+ borderBottomWidth: 1
160
+ },
161
+ title: {
162
+ flex: 1
163
+ },
164
+ closeButton: {
165
+ padding: 8,
166
+ borderRadius: 20,
167
+ marginLeft: 12
168
+ }
169
+ });
170
+ export default MediaPopup;
@@ -0,0 +1,192 @@
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ 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."); }
3
+ 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; } }
4
+ 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; }
5
+ 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; } }
6
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
+ import React, { useMemo, useState } from 'react';
8
+ import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
9
+ import ImagesGallery from './MediaGallery.native';
10
+ import VideosGallery from './VideosGallery.native';
11
+ import { defaultTheme } from './theme';
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ var MediaTab = function MediaTab(_ref) {
14
+ var imagePopup = _ref.imagePopup,
15
+ current_data = _ref.current_data,
16
+ update_data = _ref.update_data,
17
+ closePopup = _ref.closePopup,
18
+ options = _ref.options,
19
+ apiService = _ref.apiService,
20
+ onError = _ref.onError,
21
+ picker = _ref.picker,
22
+ pickerOptions = _ref.pickerOptions,
23
+ _ref$theme = _ref.theme,
24
+ theme = _ref$theme === void 0 ? defaultTheme : _ref$theme,
25
+ containerStyle = _ref.containerStyle,
26
+ tabListStyle = _ref.tabListStyle,
27
+ tabButtonStyle = _ref.tabButtonStyle,
28
+ tabButtonActiveStyle = _ref.tabButtonActiveStyle,
29
+ tabButtonInactiveStyle = _ref.tabButtonInactiveStyle,
30
+ tabButtonTextStyle = _ref.tabButtonTextStyle,
31
+ tabButtonTextActiveStyle = _ref.tabButtonTextActiveStyle,
32
+ tabButtonTextInactiveStyle = _ref.tabButtonTextInactiveStyle,
33
+ tabIndicatorStyle = _ref.tabIndicatorStyle,
34
+ tabPanelStyle = _ref.tabPanelStyle;
35
+ // Build a stable list of enabled tabs in order
36
+ var availableTabs = useMemo(function () {
37
+ var tabs = [];
38
+ if (options !== null && options !== void 0 && options.includes('image')) tabs.push('image');
39
+ if (options !== null && options !== void 0 && options.includes('video')) tabs.push('video');
40
+ if (options !== null && options !== void 0 && options.includes('file')) tabs.push('file');
41
+ return tabs;
42
+ }, [options]);
43
+ var _useState = useState(0),
44
+ _useState2 = _slicedToArray(_useState, 2),
45
+ selectedIndex = _useState2[0],
46
+ setSelectedIndex = _useState2[1];
47
+
48
+ // Guard: if no options passed, render nothing
49
+ if (!availableTabs.length) {
50
+ return null;
51
+ }
52
+ var renderTabLabel = function renderTabLabel(type) {
53
+ if (type === 'image') return 'Images';
54
+ if (type === 'video') return 'Videos';
55
+ if (type === 'file') return 'Files';
56
+ return type;
57
+ };
58
+ var renderPanel = function renderPanel(type) {
59
+ if (type === 'image') {
60
+ return /*#__PURE__*/_jsx(ImagesGallery, {
61
+ imagePopup: imagePopup,
62
+ update_data: update_data,
63
+ current_data: current_data,
64
+ closePopup: closePopup,
65
+ apiService: apiService,
66
+ onError: onError,
67
+ picker: picker,
68
+ pickerOptions: pickerOptions
69
+ });
70
+ }
71
+ if (type === 'video') {
72
+ return /*#__PURE__*/_jsx(VideosGallery, {
73
+ imagePopup: imagePopup,
74
+ update_data: update_data,
75
+ current_data: current_data,
76
+ closePopup: closePopup,
77
+ apiService: apiService,
78
+ onError: onError,
79
+ picker: picker,
80
+ pickerOptions: pickerOptions,
81
+ theme: theme
82
+ });
83
+ }
84
+ if (type === 'file') {
85
+ // Reuse ImagesGallery for files as in original implementation
86
+ return /*#__PURE__*/_jsx(ImagesGallery, {
87
+ imagePopup: imagePopup,
88
+ update_data: update_data,
89
+ current_data: current_data,
90
+ closePopup: closePopup,
91
+ apiService: apiService,
92
+ onError: onError,
93
+ picker: picker,
94
+ pickerOptions: pickerOptions
95
+ });
96
+ }
97
+ return null;
98
+ };
99
+ return /*#__PURE__*/_jsxs(View, {
100
+ style: [styles.container, containerStyle],
101
+ children: [/*#__PURE__*/_jsx(View, {
102
+ style: [styles.tabList, {
103
+ backgroundColor: theme.colors.tabBackground,
104
+ borderBottomColor: theme.colors.border,
105
+ paddingHorizontal: theme.spacing.xs
106
+ }, tabListStyle],
107
+ children: availableTabs.map(function (type, index) {
108
+ var isSelected = index === selectedIndex;
109
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
110
+ onPress: function onPress() {
111
+ return setSelectedIndex(index);
112
+ },
113
+ style: [styles.tabButton, {
114
+ paddingVertical: theme.spacing.md,
115
+ paddingHorizontal: theme.spacing.lg
116
+ }, tabButtonStyle, isSelected ? [styles.tabButtonActive, tabButtonActiveStyle] : [styles.tabButtonInactive, tabButtonInactiveStyle]],
117
+ children: [/*#__PURE__*/_jsx(Text, {
118
+ style: [styles.tabButtonText, {
119
+ fontSize: theme.typography.body.fontSize,
120
+ fontWeight: theme.typography.body.fontWeight
121
+ }, isSelected ? [styles.tabButtonTextActive, {
122
+ color: theme.colors.tabActive
123
+ }, tabButtonTextActiveStyle] : [styles.tabButtonTextInactive, {
124
+ color: theme.colors.tabInactive
125
+ }, tabButtonTextInactiveStyle], tabButtonTextStyle],
126
+ children: renderTabLabel(type)
127
+ }), isSelected && /*#__PURE__*/_jsx(View, {
128
+ style: [styles.tabIndicator, {
129
+ backgroundColor: theme.colors.tabIndicator
130
+ }, tabIndicatorStyle]
131
+ })]
132
+ }, type);
133
+ })
134
+ }), /*#__PURE__*/_jsx(View, {
135
+ style: [styles.tabPanel, tabPanelStyle],
136
+ children: availableTabs.map(function (type, index) {
137
+ var isSelected = index === selectedIndex;
138
+ return /*#__PURE__*/_jsx(View, {
139
+ style: isSelected ? styles.panelVisible : styles.panelHidden,
140
+ children: isSelected && renderPanel(type)
141
+ }, type);
142
+ })
143
+ })]
144
+ });
145
+ };
146
+ var styles = StyleSheet.create({
147
+ container: {
148
+ flex: 1
149
+ },
150
+ tabList: {
151
+ flexDirection: 'row',
152
+ borderBottomWidth: 2
153
+ },
154
+ tabButton: {
155
+ flex: 1,
156
+ alignItems: 'center',
157
+ justifyContent: 'center',
158
+ position: 'relative'
159
+ },
160
+ tabButtonActive: {
161
+ // Active state styling applied via theme
162
+ },
163
+ tabButtonInactive: {
164
+ // Inactive state styling applied via theme
165
+ },
166
+ tabButtonText: {
167
+ // Base text styling applied via theme
168
+ },
169
+ tabButtonTextActive: {
170
+ // Active text color applied via theme
171
+ },
172
+ tabButtonTextInactive: {
173
+ // Inactive text color applied via theme
174
+ },
175
+ tabIndicator: {
176
+ position: 'absolute',
177
+ bottom: -2,
178
+ left: 0,
179
+ right: 0,
180
+ height: 2
181
+ },
182
+ tabPanel: {
183
+ flex: 1
184
+ },
185
+ panelVisible: {
186
+ flex: 1
187
+ },
188
+ panelHidden: {
189
+ display: 'none'
190
+ }
191
+ });
192
+ export default MediaTab;
@@ -0,0 +1,210 @@
1
+ import React from 'react';
2
+ import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
3
+ import { defaultTheme } from './theme';
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ var Pagination = function Pagination(_ref) {
6
+ var nextPage = _ref.nextPage,
7
+ current_page = _ref.current_page,
8
+ pageCount = _ref.pageCount,
9
+ _ref$theme = _ref.theme,
10
+ theme = _ref$theme === void 0 ? defaultTheme : _ref$theme,
11
+ containerStyle = _ref.containerStyle,
12
+ navStyle = _ref.navStyle,
13
+ previousButtonStyle = _ref.previousButtonStyle,
14
+ nextButtonStyle = _ref.nextButtonStyle,
15
+ pageButtonStyle = _ref.pageButtonStyle,
16
+ pageButtonActiveStyle = _ref.pageButtonActiveStyle,
17
+ ellipsisStyle = _ref.ellipsisStyle,
18
+ pageButtonTextStyle = _ref.pageButtonTextStyle,
19
+ pageButtonTextActiveStyle = _ref.pageButtonTextActiveStyle;
20
+ var totalPages = Math.ceil(pageCount) || 1;
21
+ var currentPage = current_page || 1;
22
+
23
+ // Generate page numbers to display
24
+ var getPageNumbers = function getPageNumbers() {
25
+ var pages = [];
26
+ var maxVisible = 5;
27
+ var startPage = Math.max(1, currentPage - Math.floor(maxVisible / 2));
28
+ var endPage = Math.min(totalPages, startPage + maxVisible - 1);
29
+ if (endPage - startPage < maxVisible - 1) {
30
+ startPage = Math.max(1, endPage - maxVisible + 1);
31
+ }
32
+
33
+ // Add first page and ellipsis
34
+ if (startPage > 1) {
35
+ pages.push(1);
36
+ if (startPage > 2) {
37
+ pages.push('...');
38
+ }
39
+ }
40
+
41
+ // Add visible pages
42
+ for (var i = startPage; i <= endPage; i++) {
43
+ pages.push(i);
44
+ }
45
+
46
+ // Add ellipsis and last page
47
+ if (endPage < totalPages) {
48
+ if (endPage < totalPages - 1) {
49
+ pages.push('...');
50
+ }
51
+ pages.push(totalPages);
52
+ }
53
+ return pages;
54
+ };
55
+ var handlePageClick = function handlePageClick(page) {
56
+ if (page !== currentPage && page >= 1 && page <= totalPages && typeof page === 'number') {
57
+ nextPage(page);
58
+ }
59
+ };
60
+ var handlePrevious = function handlePrevious() {
61
+ if (currentPage > 1) {
62
+ nextPage(currentPage - 1);
63
+ }
64
+ };
65
+ var handleNext = function handleNext() {
66
+ if (currentPage < totalPages) {
67
+ nextPage(currentPage + 1);
68
+ }
69
+ };
70
+ if (totalPages <= 1) return null;
71
+ var pageNumbers = getPageNumbers();
72
+ return /*#__PURE__*/_jsx(View, {
73
+ style: [styles.container, containerStyle],
74
+ children: /*#__PURE__*/_jsxs(View, {
75
+ style: [styles.nav, navStyle],
76
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
77
+ onPress: handlePrevious,
78
+ disabled: currentPage === 1,
79
+ style: [styles.button, styles.previousButton, {
80
+ backgroundColor: theme.colors.paginationButton,
81
+ borderColor: theme.colors.paginationBorder
82
+ }, previousButtonStyle, currentPage === 1 && styles.buttonDisabled],
83
+ children: /*#__PURE__*/_jsx(Text, {
84
+ style: [styles.buttonText, {
85
+ color: theme.colors.paginationText
86
+ }],
87
+ children: "\u2039"
88
+ })
89
+ }), pageNumbers.map(function (page, index) {
90
+ if (page === '...') {
91
+ return /*#__PURE__*/_jsx(View, {
92
+ style: [styles.ellipsis, {
93
+ backgroundColor: theme.colors.paginationButton,
94
+ borderColor: theme.colors.paginationBorder
95
+ }, ellipsisStyle],
96
+ children: /*#__PURE__*/_jsx(Text, {
97
+ style: [styles.ellipsisText, {
98
+ color: theme.colors.paginationText
99
+ }],
100
+ children: "..."
101
+ })
102
+ }, "ellipsis-".concat(index));
103
+ }
104
+ var isActive = page === currentPage;
105
+ return /*#__PURE__*/_jsx(TouchableOpacity, {
106
+ onPress: function onPress() {
107
+ return handlePageClick(page);
108
+ },
109
+ style: [styles.button, styles.pageButton, {
110
+ backgroundColor: isActive ? theme.colors.paginationButtonActive : theme.colors.paginationButton,
111
+ borderColor: isActive ? theme.colors.paginationButtonActive : theme.colors.paginationBorder
112
+ }, pageButtonStyle, isActive && [styles.pageButtonActive, pageButtonActiveStyle]],
113
+ children: /*#__PURE__*/_jsx(Text, {
114
+ style: [styles.pageButtonText, {
115
+ color: isActive ? theme.colors.paginationTextActive : theme.colors.paginationText,
116
+ fontWeight: isActive ? '600' : '500'
117
+ }, isActive && pageButtonTextActiveStyle, pageButtonTextStyle],
118
+ children: page
119
+ })
120
+ }, page);
121
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
122
+ onPress: handleNext,
123
+ disabled: currentPage === totalPages,
124
+ style: [styles.button, styles.nextButton, {
125
+ backgroundColor: theme.colors.paginationButton,
126
+ borderColor: theme.colors.paginationBorder
127
+ }, nextButtonStyle, currentPage === totalPages && styles.buttonDisabled],
128
+ children: /*#__PURE__*/_jsx(Text, {
129
+ style: [styles.buttonText, {
130
+ color: theme.colors.paginationText
131
+ }],
132
+ children: "\u203A"
133
+ })
134
+ })]
135
+ })
136
+ });
137
+ };
138
+ var styles = StyleSheet.create({
139
+ container: {
140
+ alignItems: 'center',
141
+ justifyContent: 'center'
142
+ },
143
+ nav: {
144
+ flexDirection: 'row',
145
+ alignItems: 'center',
146
+ justifyContent: 'center',
147
+ flexWrap: 'wrap'
148
+ },
149
+ button: {
150
+ minWidth: 40,
151
+ height: 40,
152
+ paddingHorizontal: 12,
153
+ justifyContent: 'center',
154
+ alignItems: 'center',
155
+ borderWidth: 1
156
+ // Colors applied via theme
157
+ },
158
+ previousButton: {
159
+ borderTopLeftRadius: 6,
160
+ borderBottomLeftRadius: 6,
161
+ borderRightWidth: 0
162
+ },
163
+ nextButton: {
164
+ borderTopRightRadius: 6,
165
+ borderBottomRightRadius: 6,
166
+ borderLeftWidth: 0
167
+ },
168
+ pageButton: {
169
+ borderLeftWidth: 0,
170
+ borderRightWidth: 0
171
+ },
172
+ pageButtonActive: {
173
+ backgroundColor: '#3B3269',
174
+ borderColor: '#3B3269'
175
+ },
176
+ buttonDisabled: {
177
+ opacity: 0.5
178
+ },
179
+ buttonText: {
180
+ fontSize: 18,
181
+ fontWeight: '500'
182
+ // Color applied via theme
183
+ },
184
+ pageButtonText: {
185
+ fontSize: 14,
186
+ fontWeight: '500'
187
+ // Color applied via theme
188
+ },
189
+ pageButtonTextActive: {
190
+ fontWeight: '600'
191
+ // Color applied via theme
192
+ },
193
+ ellipsis: {
194
+ minWidth: 40,
195
+ height: 40,
196
+ paddingHorizontal: 12,
197
+ justifyContent: 'center',
198
+ alignItems: 'center',
199
+ borderWidth: 1,
200
+ borderLeftWidth: 0,
201
+ borderRightWidth: 0
202
+ // Colors applied via theme
203
+ },
204
+ ellipsisText: {
205
+ fontSize: 14,
206
+ fontWeight: '500'
207
+ // Color applied via theme
208
+ }
209
+ });
210
+ export default Pagination;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Theme Configuration Examples
3
+ *
4
+ * This file shows how to customize the Media Gallery theme for React Native
5
+ */
6
+
7
+ import { createTheme } from './theme';
8
+
9
+ // Example 1: Light Mode (Default)
10
+ export var lightTheme = createTheme({
11
+ mode: 'light'
12
+ });
13
+
14
+ // Example 2: Dark Mode
15
+ export var darkTheme = createTheme({
16
+ mode: 'dark'
17
+ });
18
+
19
+ // Example 3: Custom Brand Colors
20
+ export var customBrandTheme = createTheme({
21
+ mode: 'light',
22
+ colors: {
23
+ primary: '#FF6B6B',
24
+ // Custom red primary
25
+ tabActive: '#FF6B6B',
26
+ tabIndicator: '#FF6B6B',
27
+ uploadBorder: '#FF6B6B',
28
+ uploadIconBackground: '#FF6B6B',
29
+ paginationButtonActive: '#FF6B6B'
30
+ },
31
+ bottomSheetHeight: 0.85 // 85% of screen height
32
+ });
33
+
34
+ // Example 4: Full Customization
35
+ export var fullyCustomTheme = createTheme({
36
+ mode: 'dark',
37
+ colors: {
38
+ // Primary colors
39
+ primary: '#6366F1',
40
+ primaryLight: '#818CF8',
41
+ primaryDark: '#4F46E5',
42
+ // Backgrounds
43
+ background: '#0F172A',
44
+ backgroundSecondary: '#1E293B',
45
+ backgroundTertiary: '#334155',
46
+ // Text
47
+ text: '#F1F5F9',
48
+ textSecondary: '#CBD5E1',
49
+ textTertiary: '#94A3B8',
50
+ // Tabs
51
+ tabActive: '#6366F1',
52
+ tabInactive: '#94A3B8',
53
+ tabIndicator: '#6366F1',
54
+ tabBackground: '#0F172A',
55
+ // Borders
56
+ border: '#334155',
57
+ borderLight: '#1E293B',
58
+ borderDark: '#475569',
59
+ // Overlay
60
+ overlay: 'rgba(0, 0, 0, 0.8)',
61
+ // Pagination
62
+ paginationBackground: '#1E293B',
63
+ paginationButton: '#0F172A',
64
+ paginationButtonActive: '#6366F1',
65
+ paginationText: '#CBD5E1',
66
+ paginationTextActive: '#FFFFFF',
67
+ paginationBorder: '#334155',
68
+ // Upload
69
+ uploadBorder: '#6366F1',
70
+ uploadBackground: '#0F172A',
71
+ uploadIconBackground: '#6366F1',
72
+ uploadText: '#F1F5F9',
73
+ // Items
74
+ itemBackground: '#1E293B',
75
+ itemShadow: '#000000',
76
+ // Loading
77
+ loadingBackground: '#1E293B',
78
+ loadingText: '#94A3B8'
79
+ },
80
+ spacing: {
81
+ xs: 4,
82
+ sm: 8,
83
+ md: 12,
84
+ lg: 16,
85
+ xl: 20,
86
+ xxl: 24
87
+ },
88
+ radius: {
89
+ sm: 6,
90
+ md: 8,
91
+ lg: 12,
92
+ xl: 16,
93
+ xxl: 20
94
+ },
95
+ bottomSheetHeight: 0.92 // 92% of screen height
96
+ });
97
+
98
+ // Usage in your component:
99
+ /*
100
+ import { MediaPopup, MediaApiService } from '@tradly/asset'
101
+ import { darkTheme } from './theme'
102
+
103
+ <MediaPopup
104
+ isOpen={isOpen}
105
+ onClose={() => setIsOpen(false)}
106
+ onSelect={handleSelect}
107
+ apiService={apiService}
108
+ picker={picker}
109
+ theme={darkTheme} // Pass your custom theme
110
+ bottomSheetHeight={0.9} // Or override height directly
111
+ />
112
+ */