@codeleap/web 6.1.2 → 6.3.0

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 (31) hide show
  1. package/dist/components/CropPicker/components/CropPickerFooter.d.ts +11 -0
  2. package/dist/components/CropPicker/components/CropPickerFooter.js +12 -0
  3. package/dist/components/CropPicker/components/CropPickerFooter.js.map +1 -0
  4. package/dist/components/CropPicker/hooks.d.ts +39 -0
  5. package/dist/components/CropPicker/hooks.js +184 -0
  6. package/dist/components/CropPicker/hooks.js.map +1 -0
  7. package/dist/components/CropPicker/index.d.ts +3 -1
  8. package/dist/components/CropPicker/index.js +19 -32
  9. package/dist/components/CropPicker/index.js.map +1 -1
  10. package/dist/components/CropPicker/styles.d.ts +2 -2
  11. package/dist/components/CropPicker/types.d.ts +13 -15
  12. package/dist/components/CropPicker/utils.d.ts +10 -0
  13. package/dist/components/CropPicker/utils.js +117 -0
  14. package/dist/components/CropPicker/utils.js.map +1 -0
  15. package/dist/lib/hooks/index.d.ts +0 -1
  16. package/dist/lib/hooks/index.js +0 -1
  17. package/dist/lib/hooks/index.js.map +1 -1
  18. package/package.json +17 -17
  19. package/package.json.bak +1 -1
  20. package/src/components/CropPicker/components/CropPickerFooter.tsx +39 -0
  21. package/src/components/CropPicker/hooks.ts +173 -0
  22. package/src/components/CropPicker/index.tsx +49 -77
  23. package/src/components/CropPicker/styles.ts +8 -5
  24. package/src/components/CropPicker/types.ts +11 -16
  25. package/src/components/CropPicker/utils.ts +95 -0
  26. package/src/components/View/index.tsx +1 -1
  27. package/src/lib/hooks/index.ts +0 -1
  28. package/dist/lib/hooks/useCropPicker.d.ts +0 -36
  29. package/dist/lib/hooks/useCropPicker.js +0 -216
  30. package/dist/lib/hooks/useCropPicker.js.map +0 -1
  31. package/src/lib/hooks/useCropPicker.ts +0 -192
@@ -1,216 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
- if (ar || !(i in from)) {
52
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
- ar[i] = from[i];
54
- }
55
- }
56
- return to.concat(ar || Array.prototype.slice.call(from));
57
- };
58
- Object.defineProperty(exports, "__esModule", { value: true });
59
- exports.readImage = readImage;
60
- exports.cropImage = cropImage;
61
- exports.useCropPicker = useCropPicker;
62
- var hooks_1 = require("@codeleap/hooks");
63
- function readImage(file) {
64
- var reader = new FileReader();
65
- return new Promise(function (resolve) {
66
- reader.onload = function () {
67
- var image = new Image();
68
- image.onload = function () { return resolve(image); };
69
- image.src = reader.result;
70
- };
71
- reader.readAsDataURL(file);
72
- });
73
- }
74
- function cropImage(image, crop, type) {
75
- var canvas = document.createElement('canvas');
76
- var ctx = canvas.getContext('2d', { alpha: true });
77
- if (!ctx)
78
- throw new Error('No 2d context');
79
- canvas.width = image.naturalWidth * (crop.width / 100);
80
- canvas.height = image.naturalHeight * (crop.height / 100);
81
- var x = image.naturalWidth * (crop.x / 100);
82
- var y = image.naturalHeight * (crop.y / 100);
83
- ctx.drawImage(image, x, y, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height);
84
- return new Promise(function (resolve, reject) {
85
- canvas.toBlob(function (blob) {
86
- if (!blob) {
87
- reject(new Error('Canvas is empty'));
88
- return;
89
- }
90
- readImage(blob).then(function (cropped) {
91
- resolve([cropped.src, blob]);
92
- }).catch(reject);
93
- }, "image/".concat(type));
94
- });
95
- }
96
- function useCropPicker(_a) {
97
- var _this = this;
98
- var onFileSelect = _a.onFileSelect, ref = _a.ref, aspect = _a.aspect, minW = _a.minWidth, minH = _a.minHeight;
99
- var _b = (0, hooks_1.useBooleanToggle)(false), visible = _b[0], toggle = _b[1];
100
- var _c = (0, hooks_1.useState)(null), image = _c[0], setImage = _c[1];
101
- var _d = (0, hooks_1.useState)(), crop = _d[0], setCrop = _d[1];
102
- var _e = (0, hooks_1.useState)(), relativeCrop = _e[0], setRelativeCrop = _e[1];
103
- var _f = (0, hooks_1.useState)(false), isLoading = _f[0], setIsLoading = _f[1];
104
- var croppedPromise = (0, hooks_1.usePromise)({});
105
- var onCancel = function () { return croppedPromise.resolve([]); };
106
- var onResolved = function (files) {
107
- var _a;
108
- (_a = croppedPromise.resolve) === null || _a === void 0 ? void 0 : _a.call(croppedPromise, files);
109
- onFileSelect === null || onFileSelect === void 0 ? void 0 : onFileSelect(files);
110
- };
111
- var cleanup = function () {
112
- toggle();
113
- setRelativeCrop(null);
114
- setCrop(undefined);
115
- setTimeout(function () { return setImage(null); }, 500);
116
- };
117
- var onConfirmCrop = function () {
118
- var args_1 = [];
119
- for (var _i = 0; _i < arguments.length; _i++) {
120
- args_1[_i] = arguments[_i];
121
- }
122
- return __awaiter(_this, __spreadArray([], args_1, true), void 0, function (imageType) {
123
- var _a, preview, croppedFile;
124
- if (imageType === void 0) { imageType = 'jpeg'; }
125
- return __generator(this, function (_b) {
126
- switch (_b.label) {
127
- case 0:
128
- setIsLoading(true);
129
- return [4 /*yield*/, cropImage(image, relativeCrop, imageType)];
130
- case 1:
131
- _a = _b.sent(), preview = _a[0], croppedFile = _a[1];
132
- onResolved([
133
- {
134
- file: new File([croppedFile], 'cropped.jpg'),
135
- preview: preview,
136
- },
137
- ]);
138
- setIsLoading(false);
139
- setTimeout(function () { return cleanup(); });
140
- return [2 /*return*/];
141
- }
142
- });
143
- });
144
- };
145
- var onFilesReturned = function (event) { return __awaiter(_this, void 0, void 0, function () {
146
- var file, imageData, naturalWidth, naturalHeight, imageAspect, v, initialCrop;
147
- var _a, _b;
148
- return __generator(this, function (_c) {
149
- switch (_c.label) {
150
- case 0:
151
- file = (_b = (_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0];
152
- return [4 /*yield*/, readImage(file)];
153
- case 1:
154
- imageData = _c.sent();
155
- naturalWidth = imageData.naturalWidth, naturalHeight = imageData.naturalHeight;
156
- imageAspect = naturalWidth / naturalHeight;
157
- v = imageAspect >= aspect
158
- ? {
159
- width: ((naturalHeight * aspect) / naturalWidth) * 100,
160
- height: 100,
161
- }
162
- : {
163
- width: 100,
164
- height: (naturalWidth / aspect / naturalHeight) * 100,
165
- };
166
- initialCrop = __assign(__assign({}, v), { x: (100 - v.width) / 2, y: (100 - v.height) / 2, unit: '%' });
167
- setCrop(initialCrop);
168
- setRelativeCrop(initialCrop);
169
- setImage(imageData);
170
- setTimeout(function () { return toggle(); });
171
- return [2 /*return*/];
172
- }
173
- });
174
- }); };
175
- var onClose = function () {
176
- onCancel();
177
- setTimeout(function () { return cleanup(); });
178
- };
179
- var fileInputRef = (0, hooks_1.useRef)(null);
180
- (0, hooks_1.useImperativeHandle)(ref, function () { return ({
181
- openFilePicker: function () {
182
- fileInputRef.current.openFilePicker();
183
- return croppedPromise._await();
184
- },
185
- clear: function () {
186
- fileInputRef.current.clear();
187
- return croppedPromise._await();
188
- },
189
- }); });
190
- var minWidth = (minW !== null && minW !== void 0 ? minW : 100) * aspect;
191
- var minHeight = minH !== null && minH !== void 0 ? minH : 100;
192
- var handleCropChange = (0, hooks_1.useCallback)(function (newCrop) {
193
- setCrop(__assign(__assign({}, newCrop), { width: newCrop.width < minWidth ? minWidth : newCrop.width, height: newCrop.height < minHeight ? minHeight : newCrop.height }));
194
- }, [crop]);
195
- return {
196
- onCancel: onCancel,
197
- onResolved: onResolved,
198
- cleanup: cleanup,
199
- onConfirmCrop: onConfirmCrop,
200
- onFilesReturned: onFilesReturned,
201
- onClose: onClose,
202
- fileInputRef: fileInputRef,
203
- visible: visible,
204
- toggle: toggle,
205
- image: image,
206
- setImage: setImage,
207
- crop: crop,
208
- setCrop: setCrop,
209
- relativeCrop: relativeCrop,
210
- setRelativeCrop: setRelativeCrop,
211
- isLoading: isLoading,
212
- croppedPromise: croppedPromise,
213
- handleCropChange: handleCropChange,
214
- };
215
- }
216
- //# sourceMappingURL=useCropPicker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCropPicker.js","sourceRoot":"","sources":["../../../src/lib/hooks/useCropPicker.ts"],"names":[],"mappings":"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"}
@@ -1,192 +0,0 @@
1
- import {
2
- useBooleanToggle,
3
- useCallback,
4
- useImperativeHandle,
5
- usePromise,
6
- useRef,
7
- useState,
8
- } from '@codeleap/hooks'
9
- import { WebInputFile } from '@codeleap/types'
10
- import { ImageReading } from '../../components/CropPicker'
11
- import { FileInputProps, FileInputRef } from '../../components/FileInput'
12
- import { Crop, ReactCropProps } from 'react-image-crop'
13
-
14
- export type UseCropPickerProps = Partial<ReactCropProps> & {
15
- onFileSelect: FileInputProps['onFileSelect']
16
- ref: React.MutableRefObject<FileInputRef> | React.Ref<FileInputRef>
17
- }
18
-
19
- type ImageType = 'png' | 'jpeg' | 'webp'
20
-
21
- export function readImage(file: File | Blob): Promise<ImageReading> {
22
- const reader = new FileReader()
23
- return new Promise<ImageReading>((resolve) => {
24
- reader.onload = () => {
25
- const image = new Image()
26
- image.onload = () => resolve(image)
27
- image.src = reader.result as string
28
- }
29
- reader.readAsDataURL(file)
30
- })
31
- }
32
-
33
- export function cropImage(image: ImageReading, crop: Crop, type: ImageType): Promise<[string, Blob]> {
34
- const canvas = document.createElement('canvas')
35
- const ctx = canvas.getContext('2d', { alpha: true })
36
-
37
- if (!ctx) throw new Error('No 2d context')
38
-
39
- canvas.width = image.naturalWidth * (crop.width / 100)
40
- canvas.height = image.naturalHeight * (crop.height / 100)
41
-
42
- const x = image.naturalWidth * (crop.x / 100)
43
- const y = image.naturalHeight * (crop.y / 100)
44
-
45
- ctx.drawImage(
46
- image,
47
- x,
48
- y,
49
- canvas.width,
50
- canvas.height,
51
- 0,
52
- 0,
53
- canvas.width,
54
- canvas.height,
55
- )
56
-
57
- return new Promise<[string, Blob]>((resolve, reject) => {
58
- canvas.toBlob(blob => {
59
- if (!blob) {
60
- reject(new Error('Canvas is empty'))
61
- return
62
- }
63
- readImage(blob).then(cropped => {
64
- resolve([cropped.src, blob])
65
- }).catch(reject)
66
- }, `image/${type}`)
67
- })
68
- }
69
-
70
- export function useCropPicker({
71
- onFileSelect,
72
- ref,
73
- aspect,
74
- minWidth: minW,
75
- minHeight: minH,
76
- }: UseCropPickerProps) {
77
- const [visible, toggle] = useBooleanToggle(false)
78
- const [image, setImage] = useState<ImageReading>(null)
79
- const [crop, setCrop] = useState<Crop>()
80
- const [relativeCrop, setRelativeCrop] = useState<Crop>()
81
- const [isLoading, setIsLoading] = useState(false)
82
- const croppedPromise = usePromise<WebInputFile[]>({})
83
-
84
- const onCancel = () => croppedPromise.resolve([])
85
-
86
- const onResolved = (files: WebInputFile[]) => {
87
- croppedPromise.resolve?.(files)
88
- onFileSelect?.(files)
89
- }
90
-
91
- const cleanup = () => {
92
- toggle()
93
- setRelativeCrop(null)
94
- setCrop(undefined)
95
- setTimeout(() => setImage(null), 500)
96
- }
97
-
98
- const onConfirmCrop = async (imageType: ImageType = 'jpeg') => {
99
- setIsLoading(true)
100
- const [preview, croppedFile] = await cropImage(image, relativeCrop, imageType)
101
- onResolved([
102
- {
103
- file: new File([croppedFile], 'cropped.jpg'),
104
- preview,
105
- },
106
- ])
107
- setIsLoading(false)
108
- setTimeout(() => cleanup())
109
- }
110
-
111
- const onFilesReturned = async (
112
- event: React.ChangeEvent<HTMLInputElement>,
113
- ) => {
114
- const file = event?.target?.files?.[0]
115
- const imageData = await readImage(file)
116
- const { naturalWidth, naturalHeight } = imageData
117
- const imageAspect = naturalWidth / naturalHeight
118
- const v =
119
- imageAspect >= aspect
120
- ? {
121
- width: ((naturalHeight * aspect) / naturalWidth) * 100,
122
- height: 100,
123
- }
124
- : {
125
- width: 100,
126
- height: (naturalWidth / aspect / naturalHeight) * 100,
127
- }
128
- const initialCrop: Crop = {
129
- ...v,
130
- x: (100 - v.width) / 2,
131
- y: (100 - v.height) / 2,
132
- unit: '%',
133
- }
134
- setCrop(initialCrop)
135
- setRelativeCrop(initialCrop)
136
- setImage(imageData)
137
- setTimeout(() => toggle())
138
- }
139
-
140
- const onClose = () => {
141
- onCancel()
142
- setTimeout(() => cleanup())
143
- }
144
-
145
- const fileInputRef = useRef<FileInputRef>(null)
146
-
147
- useImperativeHandle(ref, () => ({
148
- openFilePicker: () => {
149
- fileInputRef.current.openFilePicker()
150
- return croppedPromise._await()
151
- },
152
- clear: () => {
153
- fileInputRef.current.clear()
154
- return croppedPromise._await()
155
- },
156
- }))
157
-
158
- const minWidth = (minW ?? 100) * aspect
159
- const minHeight = minH ?? 100
160
-
161
- const handleCropChange = useCallback(
162
- (newCrop: Crop) => {
163
- setCrop({
164
- ...newCrop,
165
- width: newCrop.width < minWidth ? minWidth : newCrop.width,
166
- height: newCrop.height < minHeight ? minHeight : newCrop.height,
167
- })
168
- },
169
- [crop],
170
- )
171
-
172
- return {
173
- onCancel,
174
- onResolved,
175
- cleanup,
176
- onConfirmCrop,
177
- onFilesReturned,
178
- onClose,
179
- fileInputRef,
180
- visible,
181
- toggle,
182
- image,
183
- setImage,
184
- crop,
185
- setCrop,
186
- relativeCrop,
187
- setRelativeCrop,
188
- isLoading,
189
- croppedPromise,
190
- handleCropChange,
191
- }
192
- }