@tradly/asset 1.0.6 → 1.0.8

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.
@@ -18,20 +18,90 @@ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructur
18
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
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
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; }
22
- var FileUpload = function FileUpload(_ref) {
23
- var loadMedia = _ref.loadMedia,
24
- accept = _ref.accept,
25
- title = _ref.title,
26
- apiService = _ref.apiService,
27
- onUploadStart = _ref.onUploadStart,
28
- onUploadComplete = _ref.onUploadComplete,
29
- onUploadError = _ref.onUploadError,
30
- className = _ref.className,
31
- buttonClassName = _ref.buttonClassName,
32
- iconContainerClassName = _ref.iconContainerClassName,
33
- titleClassName = _ref.titleClassName,
34
- loadingClassName = _ref.loadingClassName;
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 PNG to JPEG by default so quality applies (PNG ignores quality).
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 ? 1300 : _ref$maxWidth,
29
+ _ref$maxHeight = _ref.maxHeight,
30
+ maxHeight = _ref$maxHeight === void 0 ? 1300 : _ref$maxHeight,
31
+ _ref$quality = _ref.quality,
32
+ quality = _ref$quality === void 0 ? 0.85 : _ref$quality,
33
+ _ref$convertPngToJpeg = _ref.convertPngToJpeg,
34
+ convertPngToJpeg = _ref$convertPngToJpeg === void 0 ? false : _ref$convertPngToJpeg;
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
+ // Use JPEG for PNG to allow lossy compression (optional)
65
+ var targetType = file.type === "image/png" && convertPngToJpeg ? "image/jpeg" : file.type;
66
+ canvas.toBlob(function (blob) {
67
+ if (!blob) {
68
+ resolve(file);
69
+ return;
70
+ }
71
+ var compressedFile = new File([blob], file.name, {
72
+ type: targetType,
73
+ lastModified: Date.now()
74
+ });
75
+ resolve(compressedFile);
76
+ }, targetType, quality);
77
+ };
78
+ img.onerror = function () {
79
+ resolve(file);
80
+ };
81
+ var reader = new FileReader();
82
+ reader.onload = function (event) {
83
+ var _event$target;
84
+ img.src = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result;
85
+ };
86
+ reader.onerror = function () {
87
+ return resolve(file);
88
+ };
89
+ reader.readAsDataURL(file);
90
+ });
91
+ };
92
+ var FileUpload = function FileUpload(_ref2) {
93
+ var loadMedia = _ref2.loadMedia,
94
+ accept = _ref2.accept,
95
+ title = _ref2.title,
96
+ apiService = _ref2.apiService,
97
+ onUploadStart = _ref2.onUploadStart,
98
+ onUploadComplete = _ref2.onUploadComplete,
99
+ onUploadError = _ref2.onUploadError,
100
+ className = _ref2.className,
101
+ buttonClassName = _ref2.buttonClassName,
102
+ iconContainerClassName = _ref2.iconContainerClassName,
103
+ titleClassName = _ref2.titleClassName,
104
+ loadingClassName = _ref2.loadingClassName;
35
105
  var _useState = (0, _react.useState)([]),
36
106
  _useState2 = _slicedToArray(_useState, 2),
37
107
  files = _useState2[0],
@@ -47,8 +117,8 @@ var FileUpload = function FileUpload(_ref) {
47
117
 
48
118
  // Upload files
49
119
  var uploadFiles = /*#__PURE__*/function () {
50
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
51
- var uploadedUrls, _t;
120
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
121
+ var filesToUpload, uploadedUrls, _t;
52
122
  return _regenerator().w(function (_context) {
53
123
  while (1) switch (_context.p = _context.n) {
54
124
  case 0:
@@ -58,9 +128,25 @@ var FileUpload = function FileUpload(_ref) {
58
128
  setISLoading(true);
59
129
  setLength(fileList.length);
60
130
  _context.p = 1;
131
+ filesToUpload = fileList; // For image uploads, compress on the client before sending
132
+ if (!(accept && accept.includes("image"))) {
133
+ _context.n = 3;
134
+ break;
135
+ }
61
136
  _context.n = 2;
62
- return apiService.uploadMedia(fileList, apiService.authKey);
137
+ return Promise.all(fileList.map(function (file) {
138
+ return compressImage(file, {
139
+ maxWidth: 1600,
140
+ maxHeight: 1600,
141
+ quality: 0.85
142
+ });
143
+ }));
63
144
  case 2:
145
+ filesToUpload = _context.v;
146
+ case 3:
147
+ _context.n = 4;
148
+ return apiService.uploadMedia(filesToUpload, apiService.authKey);
149
+ case 4:
64
150
  uploadedUrls = _context.v;
65
151
  if (onUploadComplete) {
66
152
  onUploadComplete(uploadedUrls);
@@ -69,35 +155,35 @@ var FileUpload = function FileUpload(_ref) {
69
155
  if (loadMedia) {
70
156
  loadMedia();
71
157
  }
72
- _context.n = 4;
158
+ _context.n = 6;
73
159
  break;
74
- case 3:
75
- _context.p = 3;
160
+ case 5:
161
+ _context.p = 5;
76
162
  _t = _context.v;
77
- console.error('Upload error:', _t);
163
+ console.error("Upload error:", _t);
78
164
  if (onUploadError) {
79
165
  onUploadError(_t);
80
166
  }
81
- case 4:
82
- _context.p = 4;
167
+ case 6:
168
+ _context.p = 6;
83
169
  setISLoading(false);
84
- return _context.f(4);
85
- case 5:
170
+ return _context.f(6);
171
+ case 7:
86
172
  return _context.a(2);
87
173
  }
88
- }, _callee, null, [[1, 3, 4, 5]]);
174
+ }, _callee, null, [[1, 5, 6, 7]]);
89
175
  }));
90
176
  return function uploadFiles(_x) {
91
- return _ref2.apply(this, arguments);
177
+ return _ref3.apply(this, arguments);
92
178
  };
93
179
  }();
94
180
 
95
181
  // Default classes with customization support
96
- var defaultContainerClass = 'min-w-40 h-40';
97
- 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';
98
- var defaultIconContainerClass = 'p-[10px] bg-primary rounded-full';
99
- var defaultTitleClass = 'mt-2';
100
- var defaultLoadingClass = 'flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse';
182
+ var defaultContainerClass = "min-w-40 h-40";
183
+ 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";
184
+ var defaultIconContainerClass = "p-[10px] bg-primary rounded-full";
185
+ var defaultTitleClass = "mt-2";
186
+ var defaultLoadingClass = "flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse";
101
187
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
102
188
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
103
189
  className: className || defaultContainerClass,
@@ -109,13 +195,13 @@ var FileUpload = function FileUpload(_ref) {
109
195
  accept: accept,
110
196
  placeholder: "",
111
197
  onChange: (/*#__PURE__*/function () {
112
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
198
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
113
199
  var all_files;
114
200
  return _regenerator().w(function (_context2) {
115
201
  while (1) switch (_context2.n) {
116
202
  case 0:
117
203
  e.stopPropagation();
118
- all_files = Array.from(e.target.files);
204
+ all_files = Array.from(e.target.files || []);
119
205
  if (!((all_files === null || all_files === void 0 ? void 0 : all_files.length) > 0)) {
120
206
  _context2.n = 1;
121
207
  break;
@@ -124,14 +210,14 @@ var FileUpload = function FileUpload(_ref) {
124
210
  return uploadFiles(all_files);
125
211
  case 1:
126
212
  // Reset input
127
- e.target.value = '';
213
+ e.target.value = "";
128
214
  case 2:
129
215
  return _context2.a(2);
130
216
  }
131
217
  }, _callee2);
132
218
  }));
133
219
  return function (_x2) {
134
- return _ref3.apply(this, arguments);
220
+ return _ref4.apply(this, arguments);
135
221
  };
136
222
  }()),
137
223
  multiple: true
@@ -8,22 +8,94 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
8
8
  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; }
9
9
  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; } }
10
10
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
11
- import React, { useState } from 'react';
12
- import { CameraIcon } from './Icons';
11
+ import React, { useState } from "react";
12
+ import { CameraIcon } from "./Icons";
13
+
14
+ // Helper: compress image on the client before upload
15
+ // - Downscale to fit within maxWidth/maxHeight.
16
+ // - Convert PNG to JPEG by default so quality applies (PNG ignores quality).
17
+ // - Skip SVG (vector) to avoid degradation.
13
18
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
- var FileUpload = function FileUpload(_ref) {
15
- var loadMedia = _ref.loadMedia,
16
- accept = _ref.accept,
17
- title = _ref.title,
18
- apiService = _ref.apiService,
19
- onUploadStart = _ref.onUploadStart,
20
- onUploadComplete = _ref.onUploadComplete,
21
- onUploadError = _ref.onUploadError,
22
- className = _ref.className,
23
- buttonClassName = _ref.buttonClassName,
24
- iconContainerClassName = _ref.iconContainerClassName,
25
- titleClassName = _ref.titleClassName,
26
- loadingClassName = _ref.loadingClassName;
19
+ var compressImage = function compressImage(file) {
20
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
21
+ _ref$maxWidth = _ref.maxWidth,
22
+ maxWidth = _ref$maxWidth === void 0 ? 1300 : _ref$maxWidth,
23
+ _ref$maxHeight = _ref.maxHeight,
24
+ maxHeight = _ref$maxHeight === void 0 ? 1300 : _ref$maxHeight,
25
+ _ref$quality = _ref.quality,
26
+ quality = _ref$quality === void 0 ? 0.85 : _ref$quality,
27
+ _ref$convertPngToJpeg = _ref.convertPngToJpeg,
28
+ convertPngToJpeg = _ref$convertPngToJpeg === void 0 ? false : _ref$convertPngToJpeg;
29
+ return new Promise(function (resolve) {
30
+ // Non-image or SVG: skip compression to avoid losing vector quality
31
+ if (!file.type.startsWith("image/") || file.type === "image/svg+xml") {
32
+ resolve(file);
33
+ return;
34
+ }
35
+ var img = new Image();
36
+ img.onload = function () {
37
+ var width = img.width,
38
+ height = img.height;
39
+
40
+ // If the image is already small, keep it as-is
41
+ if (width <= maxWidth && height <= maxHeight) {
42
+ resolve(file);
43
+ return;
44
+ }
45
+ var scale = Math.min(maxWidth / width, maxHeight / height);
46
+ var targetWidth = Math.round(width * scale);
47
+ var targetHeight = Math.round(height * scale);
48
+ var canvas = document.createElement("canvas");
49
+ canvas.width = targetWidth;
50
+ canvas.height = targetHeight;
51
+ var ctx = canvas.getContext("2d");
52
+ if (!ctx) {
53
+ resolve(file);
54
+ return;
55
+ }
56
+ ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
57
+
58
+ // Use JPEG for PNG to allow lossy compression (optional)
59
+ var targetType = file.type === "image/png" && convertPngToJpeg ? "image/jpeg" : file.type;
60
+ canvas.toBlob(function (blob) {
61
+ if (!blob) {
62
+ resolve(file);
63
+ return;
64
+ }
65
+ var compressedFile = new File([blob], file.name, {
66
+ type: targetType,
67
+ lastModified: Date.now()
68
+ });
69
+ resolve(compressedFile);
70
+ }, targetType, quality);
71
+ };
72
+ img.onerror = function () {
73
+ resolve(file);
74
+ };
75
+ var reader = new FileReader();
76
+ reader.onload = function (event) {
77
+ var _event$target;
78
+ img.src = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.result;
79
+ };
80
+ reader.onerror = function () {
81
+ return resolve(file);
82
+ };
83
+ reader.readAsDataURL(file);
84
+ });
85
+ };
86
+ var FileUpload = function FileUpload(_ref2) {
87
+ var loadMedia = _ref2.loadMedia,
88
+ accept = _ref2.accept,
89
+ title = _ref2.title,
90
+ apiService = _ref2.apiService,
91
+ onUploadStart = _ref2.onUploadStart,
92
+ onUploadComplete = _ref2.onUploadComplete,
93
+ onUploadError = _ref2.onUploadError,
94
+ className = _ref2.className,
95
+ buttonClassName = _ref2.buttonClassName,
96
+ iconContainerClassName = _ref2.iconContainerClassName,
97
+ titleClassName = _ref2.titleClassName,
98
+ loadingClassName = _ref2.loadingClassName;
27
99
  var _useState = useState([]),
28
100
  _useState2 = _slicedToArray(_useState, 2),
29
101
  files = _useState2[0],
@@ -39,8 +111,8 @@ var FileUpload = function FileUpload(_ref) {
39
111
 
40
112
  // Upload files
41
113
  var uploadFiles = /*#__PURE__*/function () {
42
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
43
- var uploadedUrls, _t;
114
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(fileList) {
115
+ var filesToUpload, uploadedUrls, _t;
44
116
  return _regenerator().w(function (_context) {
45
117
  while (1) switch (_context.p = _context.n) {
46
118
  case 0:
@@ -50,9 +122,25 @@ var FileUpload = function FileUpload(_ref) {
50
122
  setISLoading(true);
51
123
  setLength(fileList.length);
52
124
  _context.p = 1;
125
+ filesToUpload = fileList; // For image uploads, compress on the client before sending
126
+ if (!(accept && accept.includes("image"))) {
127
+ _context.n = 3;
128
+ break;
129
+ }
53
130
  _context.n = 2;
54
- return apiService.uploadMedia(fileList, apiService.authKey);
131
+ return Promise.all(fileList.map(function (file) {
132
+ return compressImage(file, {
133
+ maxWidth: 1600,
134
+ maxHeight: 1600,
135
+ quality: 0.85
136
+ });
137
+ }));
55
138
  case 2:
139
+ filesToUpload = _context.v;
140
+ case 3:
141
+ _context.n = 4;
142
+ return apiService.uploadMedia(filesToUpload, apiService.authKey);
143
+ case 4:
56
144
  uploadedUrls = _context.v;
57
145
  if (onUploadComplete) {
58
146
  onUploadComplete(uploadedUrls);
@@ -61,35 +149,35 @@ var FileUpload = function FileUpload(_ref) {
61
149
  if (loadMedia) {
62
150
  loadMedia();
63
151
  }
64
- _context.n = 4;
152
+ _context.n = 6;
65
153
  break;
66
- case 3:
67
- _context.p = 3;
154
+ case 5:
155
+ _context.p = 5;
68
156
  _t = _context.v;
69
- console.error('Upload error:', _t);
157
+ console.error("Upload error:", _t);
70
158
  if (onUploadError) {
71
159
  onUploadError(_t);
72
160
  }
73
- case 4:
74
- _context.p = 4;
161
+ case 6:
162
+ _context.p = 6;
75
163
  setISLoading(false);
76
- return _context.f(4);
77
- case 5:
164
+ return _context.f(6);
165
+ case 7:
78
166
  return _context.a(2);
79
167
  }
80
- }, _callee, null, [[1, 3, 4, 5]]);
168
+ }, _callee, null, [[1, 5, 6, 7]]);
81
169
  }));
82
170
  return function uploadFiles(_x) {
83
- return _ref2.apply(this, arguments);
171
+ return _ref3.apply(this, arguments);
84
172
  };
85
173
  }();
86
174
 
87
175
  // Default classes with customization support
88
- var defaultContainerClass = 'min-w-40 h-40';
89
- 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';
90
- var defaultIconContainerClass = 'p-[10px] bg-primary rounded-full';
91
- var defaultTitleClass = 'mt-2';
92
- var defaultLoadingClass = 'flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse';
176
+ var defaultContainerClass = "min-w-40 h-40";
177
+ 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";
178
+ var defaultIconContainerClass = "p-[10px] bg-primary rounded-full";
179
+ var defaultTitleClass = "mt-2";
180
+ var defaultLoadingClass = "flex items-center justify-center h-40 bg-gray-200 rounded-lg shadow-md animate-pulse";
93
181
  return /*#__PURE__*/_jsxs(_Fragment, {
94
182
  children: [/*#__PURE__*/_jsxs("div", {
95
183
  className: className || defaultContainerClass,
@@ -101,13 +189,13 @@ var FileUpload = function FileUpload(_ref) {
101
189
  accept: accept,
102
190
  placeholder: "",
103
191
  onChange: (/*#__PURE__*/function () {
104
- var _ref3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
192
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(e) {
105
193
  var all_files;
106
194
  return _regenerator().w(function (_context2) {
107
195
  while (1) switch (_context2.n) {
108
196
  case 0:
109
197
  e.stopPropagation();
110
- all_files = Array.from(e.target.files);
198
+ all_files = Array.from(e.target.files || []);
111
199
  if (!((all_files === null || all_files === void 0 ? void 0 : all_files.length) > 0)) {
112
200
  _context2.n = 1;
113
201
  break;
@@ -116,14 +204,14 @@ var FileUpload = function FileUpload(_ref) {
116
204
  return uploadFiles(all_files);
117
205
  case 1:
118
206
  // Reset input
119
- e.target.value = '';
207
+ e.target.value = "";
120
208
  case 2:
121
209
  return _context2.a(2);
122
210
  }
123
211
  }, _callee2);
124
212
  }));
125
213
  return function (_x2) {
126
- return _ref3.apply(this, arguments);
214
+ return _ref4.apply(this, arguments);
127
215
  };
128
216
  }()),
129
217
  multiple: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradly/asset",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "A reusable media gallery component for uploading and selecting images, videos, and files with Tradly authentication",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",