allaw-ui 5.1.2 → 5.1.4
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.
|
@@ -14,6 +14,7 @@ export interface TextAreaProps {
|
|
|
14
14
|
error?: string;
|
|
15
15
|
maxHeight?: number;
|
|
16
16
|
minHeight?: number;
|
|
17
|
+
maxLength?: number;
|
|
17
18
|
variant?: "bold" | "semiBold" | "medium";
|
|
18
19
|
color?: "bleu-allaw" | "mid-grey" | "dark-grey" | "noir" | "pure-white" | "grey-venom" | "venom-grey-dark";
|
|
19
20
|
dataTestId?: string;
|
|
@@ -6,7 +6,7 @@ import Paragraph from "../typography/Paragraph";
|
|
|
6
6
|
import TinyInfo from "../typography/TinyInfo";
|
|
7
7
|
import "./TextArea.css";
|
|
8
8
|
var TextArea = forwardRef(function (_a, ref) {
|
|
9
|
-
var title = _a.title, _b = _a.style, style = _b === void 0 ? "default" : _b, placeholder = _a.placeholder, _c = _a.isRequired, isRequired = _c === void 0 ? false : _c, validate = _a.validate, onError = _a.onError, onChange = _a.onChange, propValue = _a.value, propError = _a.error, _d = _a.maxHeight, maxHeight = _d === void 0 ? 400 : _d, minHeight = _a.minHeight, _e = _a.variant, variant = _e === void 0 ? "medium" : _e, _f = _a.color, color = _f === void 0 ? "noir" : _f, dataTestId = _a.dataTestId, _g = _a.isPrefilled, isPrefilled = _g === void 0 ? false : _g;
|
|
9
|
+
var title = _a.title, _b = _a.style, style = _b === void 0 ? "default" : _b, placeholder = _a.placeholder, _c = _a.isRequired, isRequired = _c === void 0 ? false : _c, validate = _a.validate, onError = _a.onError, onChange = _a.onChange, propValue = _a.value, propError = _a.error, _d = _a.maxHeight, maxHeight = _d === void 0 ? 400 : _d, minHeight = _a.minHeight, maxLength = _a.maxLength, _e = _a.variant, variant = _e === void 0 ? "medium" : _e, _f = _a.color, color = _f === void 0 ? "noir" : _f, dataTestId = _a.dataTestId, _g = _a.isPrefilled, isPrefilled = _g === void 0 ? false : _g;
|
|
10
10
|
var _h = useState(propValue || ""), value = _h[0], setValue = _h[1];
|
|
11
11
|
var _j = useState(propError || ""), error = _j[0], setError = _j[1];
|
|
12
12
|
var _k = useState(false), isTouched = _k[0], setIsTouched = _k[1];
|
|
@@ -86,7 +86,7 @@ var TextArea = forwardRef(function (_a, ref) {
|
|
|
86
86
|
: ""), "data-testid": dataTestId || "text-area" },
|
|
87
87
|
React.createElement("textarea", { ref: textareaRef, placeholder: placeholder, className: minHeight !== undefined
|
|
88
88
|
? "text-area-placeholder no-transition"
|
|
89
|
-
: "text-area-placeholder", value: value, onChange: handleChange, onBlur: handleBlur, style: textareaStyle, "data-testid": dataTestId || "text-area" })),
|
|
89
|
+
: "text-area-placeholder", value: value, onChange: handleChange, onBlur: handleBlur, style: textareaStyle, maxLength: maxLength, "data-testid": dataTestId || "text-area" })),
|
|
90
90
|
error && isTouched && (React.createElement("div", { className: "error-message" },
|
|
91
91
|
React.createElement(TinyInfo, { variant: "medium12", color: "actions-error", text: error }))))));
|
|
92
92
|
});
|
|
@@ -213,6 +213,7 @@ var FileUploader = function (_a) {
|
|
|
213
213
|
};
|
|
214
214
|
/**
|
|
215
215
|
* Crop l'image côté client et retourne un Blob
|
|
216
|
+
* Utilise la même logique que ImageCropperModal pour calculer le crop
|
|
216
217
|
*/
|
|
217
218
|
var cropImageToBlob = function (imageUrl, cropMetadata, outputWidth, outputHeight) { return __awaiter(void 0, void 0, void 0, function () {
|
|
218
219
|
return __generator(this, function (_a) {
|
|
@@ -230,47 +231,64 @@ var FileUploader = function (_a) {
|
|
|
230
231
|
reject(new Error("Impossible de créer le contexte canvas"));
|
|
231
232
|
return;
|
|
232
233
|
}
|
|
233
|
-
// Dimensions de la zone de crop (
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
var cropAreaWidth = 400;
|
|
238
|
-
var cropAreaHeight = 400;
|
|
234
|
+
// Dimensions de la zone de crop dans le modal (selon le CSS)
|
|
235
|
+
// Ces dimensions correspondent exactement à celles utilisées dans ImageCropperModal.module.css
|
|
236
|
+
var cropAreaWidth = 280; // Dimensions réelles du cadre de crop pour square/circle
|
|
237
|
+
var cropAreaHeight = 280;
|
|
239
238
|
if (cropMetadata.shape === "banner") {
|
|
240
|
-
cropAreaWidth =
|
|
241
|
-
cropAreaHeight =
|
|
239
|
+
cropAreaWidth = 320;
|
|
240
|
+
cropAreaHeight = 60;
|
|
242
241
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
//
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
|
|
242
|
+
// Le zoom dans cropMetadata est le zoom total (baseZoom * zoom relatif)
|
|
243
|
+
// baseZoom est calculé dans le modal comme Math.max(cropWidth / imgWidth, cropHeight / imgHeight)
|
|
244
|
+
// puis multiplié par le zoom relatif (1-3) pour obtenir le zoom total
|
|
245
|
+
var totalZoom = cropMetadata.zoom;
|
|
246
|
+
// Dans le modal, la transform CSS est appliquée sur le container de l'image :
|
|
247
|
+
// transform: translate(offsetX, offsetY) scale(totalZoom)
|
|
248
|
+
// transform-origin: center
|
|
249
|
+
//
|
|
250
|
+
// L'ordre d'application est : scale d'abord (depuis le centre), puis translate
|
|
251
|
+
// Géométriquement, cela signifie :
|
|
252
|
+
// 1. L'image est agrandie avec scale(totalZoom) depuis son centre
|
|
253
|
+
// 2. L'image agrandie est déplacée de (offsetX, offsetY)
|
|
254
|
+
//
|
|
255
|
+
// La cropArea est fixe et centrée dans le container
|
|
256
|
+
// Pour trouver quelle partie de l'image originale correspond à la cropArea :
|
|
257
|
+
// - Le centre de la cropArea correspond au point (0, 0) dans le système de coordonnées du container
|
|
258
|
+
// - Ce point (0, 0) dans l'image transformée correspond à (-offsetX, -offsetY) dans l'image agrandie
|
|
259
|
+
// - Ce point dans l'image agrandie correspond à (-offsetX/totalZoom, -offsetY/totalZoom) dans l'image originale
|
|
260
|
+
// Centre de l'image originale
|
|
261
|
+
var imgCenterX = img.width / 2;
|
|
262
|
+
var imgCenterY = img.height / 2;
|
|
263
|
+
// Position du centre de la cropArea dans l'image originale
|
|
264
|
+
// Si l'image transformée est déplacée de offsetX vers la droite,
|
|
265
|
+
// alors le centre de la cropArea (qui reste au centre du container)
|
|
266
|
+
// correspond à un point qui est offsetX pixels à gauche du centre de l'image transformée
|
|
267
|
+
// Converti en coordonnées de l'image originale :
|
|
268
|
+
var cropCenterXInOriginal = imgCenterX - cropMetadata.offsetX / totalZoom;
|
|
269
|
+
var cropCenterYInOriginal = imgCenterY - cropMetadata.offsetY / totalZoom;
|
|
270
|
+
// Dimensions de la zone de crop dans l'image originale
|
|
271
|
+
var cropWidthInOriginal = cropAreaWidth / totalZoom;
|
|
272
|
+
var cropHeightInOriginal = cropAreaHeight / totalZoom;
|
|
273
|
+
// Coordonnées du coin supérieur gauche de la zone à cropper dans l'image originale
|
|
274
|
+
var sourceX = cropCenterXInOriginal - cropWidthInOriginal / 2;
|
|
275
|
+
var sourceY = cropCenterYInOriginal - cropHeightInOriginal / 2;
|
|
276
|
+
var sourceWidth = cropWidthInOriginal;
|
|
277
|
+
var sourceHeight = cropHeightInOriginal;
|
|
278
|
+
// S'assurer que les coordonnées sont valides (pas en dehors de l'image)
|
|
279
|
+
var clampedSourceX = Math.max(0, Math.min(sourceX, img.width - 1));
|
|
280
|
+
var clampedSourceY = Math.max(0, Math.min(sourceY, img.height - 1));
|
|
281
|
+
var clampedSourceWidth = Math.min(sourceWidth, img.width - clampedSourceX);
|
|
282
|
+
var clampedSourceHeight = Math.min(sourceHeight, img.height - clampedSourceY);
|
|
261
283
|
// Dessiner l'image croppée sur le canvas
|
|
262
|
-
ctx.drawImage(img,
|
|
263
|
-
sourceY / cropMetadata.zoom, // source y dans l'image originale
|
|
264
|
-
cropAreaWidth / cropMetadata.zoom, // largeur source
|
|
265
|
-
cropAreaHeight / cropMetadata.zoom, // hauteur source
|
|
266
|
-
0, 0, outputWidth, outputHeight);
|
|
284
|
+
ctx.drawImage(img, clampedSourceX, clampedSourceY, clampedSourceWidth, clampedSourceHeight, 0, 0, outputWidth, outputHeight);
|
|
267
285
|
// Si c'est un cercle, appliquer un masque
|
|
268
286
|
if (cropMetadata.shape === "circle") {
|
|
269
287
|
var imageData = ctx.getImageData(0, 0, outputWidth, outputHeight);
|
|
270
288
|
var pixels = imageData.data;
|
|
271
289
|
var centerX = outputWidth / 2;
|
|
272
290
|
var centerY = outputHeight / 2;
|
|
273
|
-
var radius = outputWidth / 2;
|
|
291
|
+
var radius = Math.min(outputWidth, outputHeight) / 2;
|
|
274
292
|
for (var y = 0; y < outputHeight; y++) {
|
|
275
293
|
for (var x = 0; x < outputWidth; x++) {
|
|
276
294
|
var distance = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
|
|
@@ -322,8 +340,7 @@ var FileUploader = function (_a) {
|
|
|
322
340
|
case 1:
|
|
323
341
|
_a.trys.push([1, 4, , 5]);
|
|
324
342
|
dimensions = cropOutputDimensions[cropMetadata.shape] ||
|
|
325
|
-
cropOutputDimensions.square ||
|
|
326
|
-
{ width: 200, height: 200 };
|
|
343
|
+
cropOutputDimensions.square || { width: 200, height: 200 };
|
|
327
344
|
return [4 /*yield*/, cropImageToBlob(previewUrl, cropMetadata, dimensions.width, dimensions.height)];
|
|
328
345
|
case 2:
|
|
329
346
|
croppedBlob = _a.sent();
|