@zauru-sdk/components 2.0.202 → 2.0.204
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.
- package/CHANGELOG.md +16 -0
- package/dist/Containers/ButtonSectionContainer.d.ts +0 -1
- package/dist/DynamicTable/DynamicPrintTable.d.ts +0 -1
- package/dist/Form/DynamicBaculoForm/index.d.ts +2 -0
- package/dist/Form/FileUpload/index.d.ts +2 -1
- package/dist/Form/TimePicker/index.d.ts +0 -1
- package/dist/Form/YesNo/index.d.ts +0 -1
- package/dist/Modal/ItemModal.d.ts +1 -1
- package/dist/esm/BlockUI/BlockUI.js +1 -1
- package/dist/esm/Buttons/Button.js +7 -8
- package/dist/esm/Containers/ButtonSectionContainer.js +2 -2
- package/dist/esm/Containers/OutletContainer.js +2 -2
- package/dist/esm/DynamicTable/DynamicPrintTable.js +13 -14
- package/dist/esm/DynamicTable/GenericDynamicTable.js +1 -1
- package/dist/esm/Form/DynamicBaculoForm/index.js +21 -57
- package/dist/esm/Form/FileUpload/index.js +197 -103
- package/dist/esm/Layouts/errorLayout/index.js +3 -5
- package/dist/esm/Modal/ItemModal.js +21 -10
- package/dist/esm/Skeletons/LoadingWindow.js +8 -0
- package/package.json +6 -6
- package/src/BlockUI/BlockUI.tsx +2 -4
- package/src/Buttons/Button.tsx +28 -32
- package/src/Containers/ButtonSectionContainer.tsx +2 -5
- package/src/Containers/OutletContainer.tsx +3 -3
- package/src/DynamicTable/DynamicPrintTable.tsx +1 -4
- package/src/DynamicTable/GenericDynamicTable.tsx +1 -1
- package/src/Form/DynamicBaculoForm/index.tsx +55 -66
- package/src/Form/FileUpload/index.tsx +365 -150
- package/src/Form/TimePicker/index.tsx +0 -1
- package/src/Form/YesNo/index.tsx +0 -1
- package/src/Layouts/errorLayout/index.tsx +4 -11
- package/src/Modal/ItemModal.tsx +44 -13
- package/src/Skeletons/LoadingWindow.tsx +11 -1
|
@@ -1,18 +1,85 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { DownloadIconSVG, IdeaIconSVG } from "@zauru-sdk/icons";
|
|
3
3
|
import { useState, useEffect, useRef } from "react";
|
|
4
4
|
import { useFormContext } from "react-hook-form";
|
|
5
5
|
export const FileUploadField = (props) => {
|
|
6
|
-
const { id, name, title, helpText, hint, onChange, readOnly = false, fileTypes = [], showAvailableTypes = false, className, defaultValue, download = false, required = false, optimizeImages = true, zauruBaseURL = "https://zauru.herokuapp.com", } = props;
|
|
6
|
+
const { id, name, title, helpText, hint, onChange, readOnly = false, fileTypes = [], showAvailableTypes = false, className, defaultValue, download = false, required = false, optimizeImages = true, zauruBaseURL = "https://zauru.herokuapp.com", setProcessing, signature = false, } = props;
|
|
7
7
|
const { register: tempRegister, setValue, formState: { errors }, } = useFormContext() || { formState: {} };
|
|
8
8
|
const error = errors ? errors[name] : undefined;
|
|
9
9
|
const register = tempRegister ? tempRegister(name, { required }) : undefined;
|
|
10
10
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
11
11
|
const [previewSrc, setPreviewSrc] = useState(null);
|
|
12
|
-
const [fileDeleted, setFileDeleted] = useState(false);
|
|
13
12
|
const [uploading, setUploading] = useState(false);
|
|
14
13
|
const [uploadProgress, setUploadProgress] = useState(0);
|
|
14
|
+
const [openSignatureModal, setOpenSignatureModal] = useState(false);
|
|
15
|
+
// Estados para la optimización de imagen
|
|
16
|
+
const [optimizing, setOptimizing] = useState(false);
|
|
17
|
+
const [optimizationProgress, setOptimizationProgress] = useState(0);
|
|
15
18
|
const fileInputRef = useRef(null);
|
|
19
|
+
// For signature drawing mode
|
|
20
|
+
const canvasRef = useRef(null);
|
|
21
|
+
const isDrawing = useRef(false);
|
|
22
|
+
const lastX = useRef(0);
|
|
23
|
+
const lastY = useRef(0);
|
|
24
|
+
const handlePointerDown = (e) => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
const canvas = canvasRef.current;
|
|
27
|
+
if (!canvas)
|
|
28
|
+
return;
|
|
29
|
+
const rect = canvas.getBoundingClientRect();
|
|
30
|
+
lastX.current = e.clientX - rect.left;
|
|
31
|
+
lastY.current = e.clientY - rect.top;
|
|
32
|
+
isDrawing.current = true;
|
|
33
|
+
};
|
|
34
|
+
const handlePointerMove = (e) => {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
if (!isDrawing.current)
|
|
37
|
+
return;
|
|
38
|
+
const canvas = canvasRef.current;
|
|
39
|
+
if (!canvas)
|
|
40
|
+
return;
|
|
41
|
+
const ctx = canvas.getContext("2d");
|
|
42
|
+
if (!ctx)
|
|
43
|
+
return;
|
|
44
|
+
const rect = canvas.getBoundingClientRect();
|
|
45
|
+
const currentX = e.clientX - rect.left;
|
|
46
|
+
const currentY = e.clientY - rect.top;
|
|
47
|
+
ctx.beginPath();
|
|
48
|
+
ctx.moveTo(lastX.current, lastY.current);
|
|
49
|
+
ctx.lineTo(currentX, currentY);
|
|
50
|
+
ctx.strokeStyle = "black";
|
|
51
|
+
ctx.lineWidth = 2;
|
|
52
|
+
ctx.stroke();
|
|
53
|
+
lastX.current = currentX;
|
|
54
|
+
lastY.current = currentY;
|
|
55
|
+
};
|
|
56
|
+
const handlePointerUp = (e) => {
|
|
57
|
+
e?.preventDefault();
|
|
58
|
+
isDrawing.current = false;
|
|
59
|
+
};
|
|
60
|
+
const clearCanvas = () => {
|
|
61
|
+
const canvas = canvasRef.current;
|
|
62
|
+
if (!canvas)
|
|
63
|
+
return;
|
|
64
|
+
const ctx = canvas.getContext("2d");
|
|
65
|
+
if (!ctx)
|
|
66
|
+
return;
|
|
67
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
68
|
+
};
|
|
69
|
+
const handleSignatureConfirm = () => {
|
|
70
|
+
const canvas = canvasRef.current;
|
|
71
|
+
if (!canvas)
|
|
72
|
+
return;
|
|
73
|
+
canvas.toBlob(async (blob) => {
|
|
74
|
+
if (blob) {
|
|
75
|
+
const file = new File([blob], "signature.png", { type: "image/png" });
|
|
76
|
+
const objectUrl = URL.createObjectURL(file);
|
|
77
|
+
setPreviewSrc(objectUrl);
|
|
78
|
+
await processFile(file);
|
|
79
|
+
setOpenSignatureModal(false);
|
|
80
|
+
}
|
|
81
|
+
}, "image/png");
|
|
82
|
+
};
|
|
16
83
|
useEffect(() => {
|
|
17
84
|
return () => {
|
|
18
85
|
if (previewSrc) {
|
|
@@ -29,6 +96,102 @@ export const FileUploadField = (props) => {
|
|
|
29
96
|
const bgColor = isReadOnly ? "bg-gray-100" : `bg-${color}-50`;
|
|
30
97
|
const textColor = isReadOnly ? "text-gray-700" : `text-${color}-900`;
|
|
31
98
|
const borderColor = error ? "border-red-500" : `border-${color}-500`;
|
|
99
|
+
const processFile = async (file, event) => {
|
|
100
|
+
let processedFile = file;
|
|
101
|
+
/*
|
|
102
|
+
if (file && file.type.startsWith("image/") && optimizeImages) {
|
|
103
|
+
try {
|
|
104
|
+
setOptimizing(true);
|
|
105
|
+
setOptimizationProgress(0);
|
|
106
|
+
const options: Options = {
|
|
107
|
+
fileType: "image/webp",
|
|
108
|
+
initialQuality: 0.7,
|
|
109
|
+
maxSizeMB: 1,
|
|
110
|
+
maxWidthOrHeight: 1920,
|
|
111
|
+
useWebWorker: true,
|
|
112
|
+
onProgress: (progress: number) => {
|
|
113
|
+
setOptimizationProgress(progress);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
const compressedFile = await imageCompression(file, options);
|
|
117
|
+
setOptimizing(false);
|
|
118
|
+
processedFile = new File(
|
|
119
|
+
[compressedFile],
|
|
120
|
+
file.name.replace(/\.[^.]+$/, ".webp"),
|
|
121
|
+
{ type: "image/webp" }
|
|
122
|
+
);
|
|
123
|
+
const objectUrl = URL.createObjectURL(processedFile);
|
|
124
|
+
setPreviewSrc(objectUrl);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("Error al convertir la imagen a WebP:", error);
|
|
127
|
+
setOptimizing(false);
|
|
128
|
+
const objectUrl = URL.createObjectURL(file);
|
|
129
|
+
setPreviewSrc(objectUrl);
|
|
130
|
+
}
|
|
131
|
+
} else
|
|
132
|
+
*/
|
|
133
|
+
if (file && file.type.startsWith("image/")) {
|
|
134
|
+
const objectUrl = URL.createObjectURL(file);
|
|
135
|
+
setPreviewSrc(objectUrl);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
setPreviewSrc(null);
|
|
139
|
+
}
|
|
140
|
+
if (event && event.target) {
|
|
141
|
+
const dataTransfer = new DataTransfer();
|
|
142
|
+
dataTransfer.items.add(processedFile);
|
|
143
|
+
event.target.files = dataTransfer.files;
|
|
144
|
+
}
|
|
145
|
+
// Proceso de subida mediante DirectUpload
|
|
146
|
+
import("@rails/activestorage")
|
|
147
|
+
.then(({ DirectUpload }) => {
|
|
148
|
+
const uploadUrl = `${zauruBaseURL}/api/direct_uploads`;
|
|
149
|
+
setProcessing && setProcessing(true);
|
|
150
|
+
setUploading(true);
|
|
151
|
+
setUploadProgress(0);
|
|
152
|
+
const directUpload = new DirectUpload(processedFile, uploadUrl, {
|
|
153
|
+
directUploadWillStoreFileWithXHR: (xhr) => {
|
|
154
|
+
xhr.upload.addEventListener("progress", (event) => {
|
|
155
|
+
if (event.lengthComputable) {
|
|
156
|
+
const progress = Math.round((event.loaded / event.total) * 100);
|
|
157
|
+
setUploadProgress(progress);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
directUpload.create((error, blob) => {
|
|
163
|
+
setUploading(false);
|
|
164
|
+
setProcessing && setProcessing(false);
|
|
165
|
+
if (error) {
|
|
166
|
+
console.error("Error al subir el archivo:", error);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
setValue(name, blob.signed_id);
|
|
170
|
+
setValue(`${name}_file_type`, blob.content_type);
|
|
171
|
+
const hiddenField = document.createElement("input");
|
|
172
|
+
hiddenField.setAttribute("type", "hidden");
|
|
173
|
+
hiddenField.setAttribute("value", blob.signed_id);
|
|
174
|
+
hiddenField.setAttribute("name", name);
|
|
175
|
+
const typeHiddenField = document.createElement("input");
|
|
176
|
+
typeHiddenField.setAttribute("type", "hidden");
|
|
177
|
+
typeHiddenField.setAttribute("value", blob.content_type);
|
|
178
|
+
typeHiddenField.setAttribute("name", `${name}_file_type`);
|
|
179
|
+
const formElement = document.querySelector("form");
|
|
180
|
+
if (formElement) {
|
|
181
|
+
formElement.appendChild(hiddenField);
|
|
182
|
+
formElement.appendChild(typeHiddenField);
|
|
183
|
+
}
|
|
184
|
+
if (fileInputRef.current) {
|
|
185
|
+
fileInputRef.current.removeAttribute("name");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
})
|
|
190
|
+
.catch((err) => {
|
|
191
|
+
setProcessing && setProcessing(false);
|
|
192
|
+
console.error("Error al cargar DirectUpload:", err);
|
|
193
|
+
});
|
|
194
|
+
};
|
|
32
195
|
/**
|
|
33
196
|
* Función que se dispara cuando el usuario selecciona un archivo.
|
|
34
197
|
* Si optimizeImages está activo y se trata de una imagen, la convierte a WebP
|
|
@@ -36,100 +199,9 @@ export const FileUploadField = (props) => {
|
|
|
36
199
|
*/
|
|
37
200
|
const handleInputChange = async (event) => {
|
|
38
201
|
if (event.target.files && event.target.files.length > 0) {
|
|
39
|
-
|
|
40
|
-
// Si se activa la optimización y es imagen, se convierte a WebP
|
|
41
|
-
if (file && file.type.startsWith("image/") && optimizeImages) {
|
|
42
|
-
try {
|
|
43
|
-
/*
|
|
44
|
-
const options: Options = {
|
|
45
|
-
fileType: "image/webp", // Especificamos el formato WebP
|
|
46
|
-
initialQuality: 0.7, // Calidad inicial (puedes ajustar este valor)
|
|
47
|
-
maxSizeMB: 1, // Tamaño máximo (opcional)
|
|
48
|
-
maxWidthOrHeight: 1920, // Dimensión máxima (opcional)
|
|
49
|
-
useWebWorker: true,
|
|
50
|
-
};
|
|
51
|
-
// Después de la compresión, renombramos el archivo:
|
|
52
|
-
const compressedFile = await imageCompression(file, options);
|
|
53
|
-
const newFile = new File(
|
|
54
|
-
[compressedFile],
|
|
55
|
-
file.name.replace(/\.[^.]+$/, ".webp"),
|
|
56
|
-
{
|
|
57
|
-
type: file.type,
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
file = newFile;
|
|
61
|
-
*/
|
|
62
|
-
console.log("Archivo convertido:", file.name, file.type);
|
|
63
|
-
const objectUrl = URL.createObjectURL(file);
|
|
64
|
-
setPreviewSrc(objectUrl);
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
console.error("Error al convertir la imagen a WebP:", error);
|
|
68
|
-
const objectUrl = URL.createObjectURL(file);
|
|
69
|
-
setPreviewSrc(objectUrl);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else if (file && file.type.startsWith("image/")) {
|
|
73
|
-
const objectUrl = URL.createObjectURL(file);
|
|
74
|
-
setPreviewSrc(objectUrl);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
setPreviewSrc(null);
|
|
78
|
-
}
|
|
79
|
-
// Actualizamos el input para que contenga el archivo convertido
|
|
80
|
-
const dataTransfer = new DataTransfer();
|
|
81
|
-
dataTransfer.items.add(file);
|
|
82
|
-
event.target.files = dataTransfer.files;
|
|
83
|
-
// Importamos dinámicamente DirectUpload solo en el cliente
|
|
84
|
-
import("@rails/activestorage")
|
|
85
|
-
.then(({ DirectUpload }) => {
|
|
86
|
-
const uploadUrl = `${zauruBaseURL}/api/direct_uploads`;
|
|
87
|
-
setUploading(true);
|
|
88
|
-
setUploadProgress(0);
|
|
89
|
-
const directUpload = new DirectUpload(file, uploadUrl, {
|
|
90
|
-
directUploadWillStoreFileWithXHR: (xhr) => {
|
|
91
|
-
xhr.upload.addEventListener("progress", (event) => {
|
|
92
|
-
if (event.lengthComputable) {
|
|
93
|
-
const progress = Math.round((event.loaded / event.total) * 100);
|
|
94
|
-
setUploadProgress(progress);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
directUpload.create((error, blob) => {
|
|
100
|
-
setUploading(false);
|
|
101
|
-
if (error) {
|
|
102
|
-
console.error("Error al subir el archivo:", error);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
setValue(name, blob.signed_id);
|
|
106
|
-
setValue(`${name}_file_type`, blob.content_type);
|
|
107
|
-
// Input hidden para el signed_id
|
|
108
|
-
const hiddenField = document.createElement("input");
|
|
109
|
-
hiddenField.setAttribute("type", "hidden");
|
|
110
|
-
hiddenField.setAttribute("value", blob.signed_id);
|
|
111
|
-
hiddenField.setAttribute("name", name);
|
|
112
|
-
// Input hidden para el content_type
|
|
113
|
-
const typeHiddenField = document.createElement("input");
|
|
114
|
-
typeHiddenField.setAttribute("type", "hidden");
|
|
115
|
-
typeHiddenField.setAttribute("value", blob.content_type);
|
|
116
|
-
typeHiddenField.setAttribute("name", `${name}_file_type`);
|
|
117
|
-
const formElement = document.querySelector("form");
|
|
118
|
-
if (formElement) {
|
|
119
|
-
formElement.appendChild(hiddenField);
|
|
120
|
-
formElement.appendChild(typeHiddenField);
|
|
121
|
-
}
|
|
122
|
-
// Removemos el atributo "name" del input file para evitar enviar el archivo
|
|
123
|
-
if (fileInputRef.current) {
|
|
124
|
-
fileInputRef.current.removeAttribute("name");
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
})
|
|
129
|
-
.catch((err) => console.error("Error al cargar DirectUpload:", err));
|
|
202
|
+
await processFile(event.target.files[0], event);
|
|
130
203
|
}
|
|
131
204
|
onChange && onChange(event);
|
|
132
|
-
setFileDeleted(false);
|
|
133
205
|
};
|
|
134
206
|
/**
|
|
135
207
|
* Función para eliminar el archivo. Además de limpiar la vista previa,
|
|
@@ -137,7 +209,6 @@ export const FileUploadField = (props) => {
|
|
|
137
209
|
*/
|
|
138
210
|
const deleteFile = () => {
|
|
139
211
|
setPreviewSrc(null);
|
|
140
|
-
setFileDeleted(true);
|
|
141
212
|
if (fileInputRef.current) {
|
|
142
213
|
fileInputRef.current.value = "";
|
|
143
214
|
}
|
|
@@ -167,16 +238,39 @@ export const FileUploadField = (props) => {
|
|
|
167
238
|
* - Si defaultValue es string, se muestra el preview (descarga/imagen).
|
|
168
239
|
* - Si no hay defaultValue (o es File), se muestra "Sin archivo".
|
|
169
240
|
*/
|
|
170
|
-
if (
|
|
171
|
-
|
|
241
|
+
if (signature) {
|
|
242
|
+
if (readOnly) {
|
|
243
|
+
return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, children: [title && (_jsx("label", { htmlFor: name, className: "block mb-1 text-sm font-medium text-gray-700", children: title })), typeof defaultValue === "string" && defaultValue ? (renderPreview(defaultValue)) : (_jsx("div", { className: "text-sm italic text-gray-400", children: "No hay firma disponible" }))] }));
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, children: [title && (_jsxs("label", { htmlFor: name, className: `block mb-1 text-sm font-medium text-${color}-700`, children: [title, required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] })), previewSrc ? (_jsxs("div", { children: [renderPreview(previewSrc), _jsx("button", { type: "button", onClick: () => {
|
|
247
|
+
setPreviewSrc(null);
|
|
248
|
+
}, className: "ml-2 text-red-600 underline text-sm", children: "Eliminar firma" })] })) : (_jsx("div", { children: _jsx("button", { type: "button", onClick: () => setOpenSignatureModal(true), className: "px-4 py-2 bg-blue-600 text-white rounded", children: "Firmar" }) })), openSignatureModal && (_jsxs("div", { className: "fixed inset-0 z-50 flex flex-col bg-white", children: [_jsx("div", { className: "flex-grow flex items-center justify-center", children: _jsx("canvas", { ref: canvasRef, width: 400, height: 200, style: {
|
|
249
|
+
border: "1px solid #ccc",
|
|
250
|
+
backgroundColor: "transparent",
|
|
251
|
+
touchAction: "none",
|
|
252
|
+
}, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerLeave: handlePointerUp }) }), _jsxs("div", { className: "p-4 flex justify-center space-x-4", children: [_jsx("button", { type: "button", onClick: clearCanvas, className: "text-blue-600 underline text-sm", children: "Reset" }), _jsx("button", { type: "button", onClick: handleSignatureConfirm, className: "text-blue-600 underline text-sm", children: "Ok" }), _jsx("button", { type: "button", onClick: () => setOpenSignatureModal(false), className: "text-gray-600 underline text-sm", children: "Cancelar" })] })] }))] }));
|
|
253
|
+
}
|
|
172
254
|
}
|
|
173
255
|
/**
|
|
174
256
|
* 2) Modo editable (readOnly = false):
|
|
257
|
+
* - Se muestra siempre el recuadro de vista previa, ya sea con la imagen cargada o con un placeholder.
|
|
175
258
|
* - Si se ha seleccionado una imagen o existe defaultValue y no se ha eliminado,
|
|
176
|
-
* se muestra la
|
|
177
|
-
* - Si se elimina el archivo o no hay ninguno, se muestra el input para cargar uno.
|
|
259
|
+
* se muestra la imagen y un botón para eliminar el archivo.
|
|
178
260
|
*/
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
261
|
+
if (readOnly) {
|
|
262
|
+
return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, children: [title && (_jsx("label", { htmlFor: name, className: "block mb-1 text-sm font-medium text-gray-700", children: title })), typeof defaultValue === "string" && defaultValue ? (renderPreview(defaultValue)) : (_jsx("div", { className: "text-sm italic text-gray-400", children: "No hay archivo disponible" }))] }));
|
|
263
|
+
}
|
|
264
|
+
return (_jsxs("div", { className: `col-span-6 sm:col-span-3 ${className}`, children: [title && (_jsxs("label", { htmlFor: name, className: `block mb-1 text-sm font-medium text-${color}-700`, children: [title, required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] })), _jsxs("div", { className: "mb-2 flex items-center", children: [_jsx("div", { role: "button", tabIndex: 0, onClick: () => {
|
|
265
|
+
const srcToOpen = previewSrc || (typeof defaultValue === "string" && defaultValue);
|
|
266
|
+
if (srcToOpen)
|
|
267
|
+
window.open(srcToOpen, "_blank");
|
|
268
|
+
}, onKeyDown: (event) => {
|
|
269
|
+
const srcToOpen = previewSrc || (typeof defaultValue === "string" && defaultValue);
|
|
270
|
+
if (event.key === "Enter" && srcToOpen)
|
|
271
|
+
window.open(srcToOpen, "_blank");
|
|
272
|
+
}, className: "cursor-pointer border border-gray-300 h-48 w-48 flex items-center justify-center", children: previewSrc || (typeof defaultValue === "string" && defaultValue) ? (_jsx("img", { src: previewSrc ??
|
|
273
|
+
(typeof defaultValue === "string" && defaultValue
|
|
274
|
+
? defaultValue
|
|
275
|
+
: undefined), alt: name, className: "h-48 w-48", style: { objectFit: "contain" } })) : (_jsx("span", { className: "text-gray-400", children: "No image" })) }), (previewSrc || (typeof defaultValue === "string" && defaultValue)) && (_jsx("button", { type: "button", onClick: deleteFile, className: "ml-2 text-red-600 underline text-sm", children: "Eliminar archivo" }))] }), _jsxs("div", { className: "flex relative items-center", children: [_jsx("input", { type: "file", id: id ?? name, accept: fileTypes.map((ft) => `.${ft}`).join(", "), className: `block w-full rounded-md ${bgColor} ${borderColor} ${textColor} shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm`, ...(register ?? {}), ref: fileInputRef, name: name, onChange: handleInputChange }), helpText && (_jsx("div", { className: "flex items-center relative ml-3", children: _jsxs("div", { className: "relative cursor-pointer", onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), children: [_jsx(IdeaIconSVG, {}), showTooltip && (_jsx("div", { className: "absolute -left-48 top-0 mt-8 p-2 bg-white border rounded shadow text-black z-50", children: helpText }))] }) }))] }), _jsx("div", { className: "mt-2 min-h-[60px] flex items-center justify-center border border-dashed border-gray-200 rounded", children: optimizing || uploading ? (_jsxs(_Fragment, { children: [optimizing && (_jsxs("div", { className: "w-full", children: [_jsx("progress", { value: optimizationProgress, max: "100", className: "w-full" }), _jsxs("p", { className: "text-sm text-blue-600 mt-1 text-center", children: ["Optimizando imagen a webp: ", optimizationProgress, "%"] })] })), uploading && (_jsxs("div", { className: "w-full", children: [_jsx("progress", { value: uploadProgress, max: "100", className: "w-full" }), _jsxs("p", { className: "text-sm text-blue-600 mt-1 text-center", children: ["Subiendo archivo: ", uploadProgress, "%"] })] }))] })) : (_jsx("span", { className: "text-sm text-gray-500", children: "Informaci\u00F3n de progreso" })) }), error && (_jsxs("p", { className: "mt-2 text-sm text-red-600", children: [_jsx("span", { className: "font-medium", children: "\u00A1Oops!" }), " ", error.message?.toString()] })), !error && hintMessage && (_jsx("p", { className: `mt-2 italic text-sm text-${color}-500`, children: hintMessage }))] }));
|
|
182
276
|
};
|
|
@@ -6,12 +6,10 @@ export const ErrorLayout = ({ from, isRootLevel = true, error: parentError, }) =
|
|
|
6
6
|
const error = useRouteError();
|
|
7
7
|
const [showDetails, setShowDetails] = useState(!!parentError);
|
|
8
8
|
const baseError = (_jsxs("div", { className: "min-h-screen flex flex-col items-center justify-center p-4", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-5xl font-extrabold text-red-500 mb-6", children: "\u00A1Ups!" }), _jsxs("div", { className: "w-full max-w-2xl flex flex-col items-center", children: [_jsx("p", { className: "text-2xl text-gray-300 mb-8 text-center", children: isRouteErrorResponse(error)
|
|
9
|
-
? `Error
|
|
9
|
+
? `Error ${error.status}: ${error.statusText}`
|
|
10
10
|
: error instanceof Error
|
|
11
|
-
?
|
|
12
|
-
:
|
|
13
|
-
? "(*) Error lanzado desde: "
|
|
14
|
-
: "Error lanzado desde: ", from] })), parentError && (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("button", { onClick: () => setShowDetails(!showDetails), className: "text-blue-400 hover:text-blue-300 transition duration-300", children: showDetails ? "Ocultar detalles" : "Ver más detalles" }), showDetails && (_jsx("p", { className: "mt-2 text-gray-400 text-sm", children: parentError instanceof Error
|
|
11
|
+
? error.message
|
|
12
|
+
: "Ha ocurrido un error inesperado" }), from && (_jsxs("p", { className: "text-lg text-gray-400 mb-4 text-center", children: ["Error lanzado desde: ", from] })), parentError && (_jsxs("div", { className: "mb-4 text-center", children: [_jsx("button", { onClick: () => setShowDetails(!showDetails), className: "text-blue-400 hover:text-blue-300 transition duration-300", children: showDetails ? "Ocultar detalles" : "Ver más detalles" }), showDetails && (_jsx("p", { className: "mt-2 text-gray-400 text-sm", children: parentError instanceof Error
|
|
15
13
|
? parentError.message
|
|
16
14
|
: String(parentError) }))] }))] }), _jsx(Link, { to: "/", className: "bg-blue-600 text-white py-3 px-8 rounded-full text-lg font-semibold hover:bg-blue-700 transition duration-300 transform hover:scale-105", children: "Regresar al inicio" }), _jsx("div", { className: "mt-12 text-gray-500 text-center", children: _jsx("p", { children: "Si el problema persiste, por favor contacta a soporte." }) })] }));
|
|
17
15
|
if (!isRootLevel) {
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useRef } from "react";
|
|
3
3
|
import { createRoot } from "react-dom/client";
|
|
4
|
+
const ExpandableText = ({ text, threshold = 30, }) => {
|
|
5
|
+
const [expanded, setExpanded] = useState(false);
|
|
6
|
+
const toggleExpanded = (e) => {
|
|
7
|
+
e.stopPropagation();
|
|
8
|
+
setExpanded(!expanded);
|
|
9
|
+
};
|
|
10
|
+
if (text.length <= threshold) {
|
|
11
|
+
return _jsx("span", { children: text });
|
|
12
|
+
}
|
|
13
|
+
return (_jsx("span", { onClick: toggleExpanded, style: { cursor: "pointer" }, children: expanded ? (_jsxs("span", { className: "text-base font-semibold", children: [text, " ", _jsx("span", { className: "ml-1", children: "\u25B2" })] })) : (_jsxs("span", { className: "text-sm font-semibold", children: [text.substring(0, threshold), "...", " ", _jsx("span", { className: "ml-1", children: "\u25BC" })] })) }));
|
|
14
|
+
};
|
|
4
15
|
const ItemSelectionModal = ({ itemList, onClose, config, categoryViewMode = "text", }) => {
|
|
5
16
|
const defaultConfig = {
|
|
6
17
|
itemSize: {
|
|
@@ -32,7 +43,7 @@ const ItemSelectionModal = ({ itemList, onClose, config, categoryViewMode = "tex
|
|
|
32
43
|
setSelectedItem(item);
|
|
33
44
|
setQuantity(1);
|
|
34
45
|
// Si el ítem tiene precio flexible, inicializamos el customPrice con su precio actual
|
|
35
|
-
setCustomPrice(item.flexiblePrice ? item.
|
|
46
|
+
setCustomPrice(item.flexiblePrice ? item.unit_price : null);
|
|
36
47
|
// Forzar scroll a la parte superior del contenido, ya que antes se iniciaba el scroll desde donde se había quedado.
|
|
37
48
|
if (modalContentRef.current) {
|
|
38
49
|
modalContentRef.current.scrollTo({ top: 0, behavior: "smooth" });
|
|
@@ -43,13 +54,13 @@ const ItemSelectionModal = ({ itemList, onClose, config, categoryViewMode = "tex
|
|
|
43
54
|
// (5) Devolver el precio correcto
|
|
44
55
|
const finalPrice = selectedItem.flexiblePrice
|
|
45
56
|
? // si el precio es flexible, tomar lo que el usuario haya ingresado (o fallback al precio original)
|
|
46
|
-
customPrice ?? selectedItem.
|
|
57
|
+
customPrice ?? selectedItem.unit_price
|
|
47
58
|
: // si NO es flexible, solo usamos el precio que ya tenía
|
|
48
|
-
selectedItem.
|
|
59
|
+
selectedItem.unit_price;
|
|
49
60
|
onClose({
|
|
50
61
|
...selectedItem,
|
|
51
62
|
quantity,
|
|
52
|
-
|
|
63
|
+
unit_price: finalPrice,
|
|
53
64
|
});
|
|
54
65
|
}
|
|
55
66
|
};
|
|
@@ -67,7 +78,7 @@ const ItemSelectionModal = ({ itemList, onClose, config, categoryViewMode = "tex
|
|
|
67
78
|
/* ==============================
|
|
68
79
|
PASO 1: SELECCIONAR ÍTEM
|
|
69
80
|
============================== */
|
|
70
|
-
_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative mb-4", children: [_jsx("input", { type: "text", placeholder: "Buscar por nombre o categor\u00EDa...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "p-2 border rounded-lg w-full" }), searchTerm && (_jsx("button", { className: "absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-800", onClick: () => setSearchTerm(""), children: "\u00D7" }))] }), filteredList.length === 0 ? (_jsx("p", { className: "text-gray-500 text-center", children: "No se encontraron resultados." })) : (filteredList.map((category) => {
|
|
81
|
+
_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative mb-4", children: [_jsx("input", { type: "text", placeholder: "Buscar por nombre o categor\u00EDa...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "p-2 border rounded-lg w-full" }), searchTerm && (_jsx("button", { className: "absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-800", onClick: () => setSearchTerm(""), children: "\u00D7" }))] }), filteredList.length === 0 ? (_jsx("p", { className: "text-gray-500 text-center", children: "No se encontraron resultados." })) : (filteredList.map((category, index) => {
|
|
71
82
|
const isExpanded = expandedCategories[category.name];
|
|
72
83
|
// Estilos condicionales para "text" vs. "card"
|
|
73
84
|
const categoryContainerClasses = categoryViewMode === "card"
|
|
@@ -86,23 +97,23 @@ const ItemSelectionModal = ({ itemList, onClose, config, categoryViewMode = "tex
|
|
|
86
97
|
height: defaultConfig.itemSize.height,
|
|
87
98
|
}, children: [_jsx("div", { className: `p-2 rounded absolute top-0 left-0 right-0 ${isPackage
|
|
88
99
|
? "bg-yellow-300 text-black"
|
|
89
|
-
: "bg-white bg-opacity-80"}`, children: _jsx(
|
|
100
|
+
: "bg-white bg-opacity-80"}`, children: _jsx(ExpandableText, { text: item.name, threshold: 30 }) }), _jsx("div", { className: `absolute bottom-0 left-0 p-2 rounded ${isPackage
|
|
90
101
|
? "bg-yellow-300"
|
|
91
102
|
: "bg-white bg-opacity-80"}`, children: _jsxs("span", { className: "text-xs font-normal", children: ["Stock: ", item.stock] }) }), _jsx("div", { className: `absolute bottom-0 right-0 p-2 rounded ${isPackage
|
|
92
103
|
? "bg-yellow-300"
|
|
93
|
-
: "bg-white bg-opacity-80"}`, children: _jsxs("span", { className: "text-xs font-normal", children: [item.currencyPrefix, item.priceText] }) })] }, item.
|
|
94
|
-
}) }))] },
|
|
104
|
+
: "bg-white bg-opacity-80"}`, children: _jsxs("span", { className: "text-xs font-normal", children: [item.currencyPrefix, item.priceText] }) })] }, item.item_id));
|
|
105
|
+
}) }))] }, index));
|
|
95
106
|
}))] })) : (
|
|
96
107
|
/* ==============================
|
|
97
108
|
PASO 2: CONFIRMAR SELECCIÓN
|
|
98
109
|
============================== */
|
|
99
|
-
_jsxs("div", { className: "flex flex-col items-center justify-center", children: [_jsx("img", { src: selectedItem.imageUrl, alt: selectedItem.name, className: "w-40 h-40 object-cover rounded mb-4 shadow-md" }), _jsx("p", { className: "mb-2 text-xl font-bold", children: selectedItem.name }), _jsxs("p", { className: "mb-2 text-base font-semibold text-gray-700", children: ["Stock disponible:", _jsx("span", { className: "ml-1 font-normal text-gray-800", children: selectedItem.stock })] }), !selectedItem.flexiblePrice && (_jsxs("p", { className: "mb-4 text-base font-semibold text-gray-700", children: ["Precio unitario:", _jsxs("span", { className: "ml-1 font-normal text-gray-800", children: [selectedItem.currencyPrefix, selectedItem.priceText] })] })), _jsxs("div", { className: "mb-4 w-full max-w-sm flex flex-col items-center", children: [_jsx("p", { className: "text-base font-semibold text-gray-700 mb-2", children: "Seleccionar cantidad" }), _jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("button", { className: "bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400", onClick: () => setQuantity((prev) => (prev > 1 ? prev - 1 : 1)), children: "-" }), _jsx("input", { className: "w-
|
|
110
|
+
_jsxs("div", { className: "flex flex-col items-center justify-center", children: [_jsx("img", { src: selectedItem.imageUrl, alt: selectedItem.name, className: "w-40 h-40 object-cover rounded mb-4 shadow-md" }), _jsx("p", { className: "mb-2 text-xl font-bold", children: selectedItem.name }), _jsxs("p", { className: "mb-2 text-base font-semibold text-gray-700", children: ["Stock disponible:", _jsx("span", { className: "ml-1 font-normal text-gray-800", children: selectedItem.stock })] }), !selectedItem.flexiblePrice && (_jsxs("p", { className: "mb-4 text-base font-semibold text-gray-700", children: ["Precio unitario:", _jsxs("span", { className: "ml-1 font-normal text-gray-800", children: [selectedItem.currencyPrefix, selectedItem.priceText] })] })), _jsxs("div", { className: "mb-4 w-full max-w-sm flex flex-col items-center", children: [_jsx("p", { className: "text-base font-semibold text-gray-700 mb-2", children: "Seleccionar cantidad" }), _jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("button", { className: "bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400", onClick: () => setQuantity((prev) => (prev > 1 ? prev - 1 : 1)), children: "-" }), _jsx("input", { className: "w-20 text-center border rounded text-lg", type: "number", min: 1, value: quantity, onChange: (e) => {
|
|
100
111
|
const val = parseInt(e.target.value, 10);
|
|
101
112
|
setQuantity(isNaN(val) || val < 1 ? 1 : val);
|
|
102
113
|
} }), _jsx("button", { className: "bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400", onClick: () => setQuantity((prev) => prev + 1), children: "+" })] })] }), selectedItem.flexiblePrice && (_jsxs("div", { className: "mb-4 w-full max-w-sm flex flex-col items-center", children: [_jsx("p", { className: "text-base font-semibold text-gray-700 mb-2", children: "Seleccionar precio" }), _jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("button", { className: "bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400", onClick: () => setCustomPrice((prev) => {
|
|
103
114
|
const newVal = (prev ?? 0) - 1;
|
|
104
115
|
return newVal < 0 ? 0 : newVal;
|
|
105
|
-
}), children: "-" }), _jsx("input", { className: "w-
|
|
116
|
+
}), children: "-" }), _jsx("input", { className: "w-24 text-center border rounded text-lg", type: "number", min: 0, value: customPrice ?? 0, onChange: (e) => {
|
|
106
117
|
const val = parseInt(e.target.value, 10);
|
|
107
118
|
setCustomPrice(isNaN(val) || val < 0 ? 0 : val);
|
|
108
119
|
} }), _jsx("button", { className: "bg-gray-300 rounded-full w-12 h-12 flex justify-center items-center text-2xl font-bold hover:bg-gray-400", onClick: () => setCustomPrice((prev) => (prev == null ? 1 : prev + 1)), children: "+" })] })] })), _jsxs("div", { className: "flex space-x-4 mt-6", children: [_jsx("button", { className: "bg-gray-300 px-4 py-2 rounded hover:bg-gray-400", onClick: handleCancelQuantity, children: "Volver" }), _jsx("button", { className: "bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700", onClick: handleConfirmQuantity, children: "Confirmar" })] })] }))] }) }));
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
2
3
|
import { motion } from "framer-motion";
|
|
3
4
|
export const LoadingWindow = ({ loadingItems = [], description = "Por favor, espere mientras se carga la página.", }) => {
|
|
5
|
+
const [hasMounted, setHasMounted] = useState(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
setHasMounted(true);
|
|
8
|
+
}, []);
|
|
9
|
+
if (!hasMounted) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
4
12
|
return (_jsx("div", { className: "min-h-screen bg-gray-200 flex flex-col justify-center items-center", children: _jsxs(motion.div, { initial: { opacity: 0, y: -20 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.5 }, className: "text-center flex flex-col items-center", children: [_jsx("img", { src: "/logo.png", alt: "Zauru Logo", className: "mb-8 h-20" }), _jsx("h1", { className: "text-3xl font-bold text-gray-800 mb-4", children: "Cargando..." }), _jsx("p", { className: "text-gray-600 mb-4", children: description }), loadingItems && (_jsx("ul", { className: "text-left mb-4", children: loadingItems.map((item, index) => (_jsxs("li", { className: "flex items-center mb-2", children: [_jsx("svg", { className: `${item.loading ? "" : "hidden"} w-5 h-5 text-blue-500 mr-2 animate-spin loading-spinner`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }), _jsx("svg", { className: `${item.loading ? "hidden" : ""} w-5 h-5 text-green-500 mr-2 check-mark`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }), _jsx("span", { children: item.name })] }, index))) })), _jsx(motion.div, { animate: { rotate: 360 }, transition: { duration: 2, repeat: Infinity, ease: "linear" }, className: "mt-8", children: _jsx("svg", { className: "w-12 h-12 text-blue-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx(motion.path, { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15", animate: { rotate: 360 }, transition: { duration: 2, repeat: Infinity, ease: "linear" } }) }) })] }) }));
|
|
5
13
|
};
|
|
6
14
|
export default LoadingWindow;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauru-sdk/components",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.204",
|
|
4
4
|
"description": "Componentes reutilizables en las WebApps de Zauru.",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"@rails/activestorage": "^8.0.200",
|
|
36
36
|
"@reduxjs/toolkit": "^2.2.1",
|
|
37
37
|
"@remix-run/react": "^2.8.1",
|
|
38
|
-
"@zauru-sdk/common": "^2.0.
|
|
39
|
-
"@zauru-sdk/hooks": "^2.0.
|
|
38
|
+
"@zauru-sdk/common": "^2.0.204",
|
|
39
|
+
"@zauru-sdk/hooks": "^2.0.204",
|
|
40
40
|
"@zauru-sdk/icons": "^2.0.188",
|
|
41
|
-
"@zauru-sdk/types": "^2.0.
|
|
42
|
-
"@zauru-sdk/utils": "^2.0.
|
|
41
|
+
"@zauru-sdk/types": "^2.0.204",
|
|
42
|
+
"@zauru-sdk/utils": "^2.0.204",
|
|
43
43
|
"browser-image-compression": "^2.0.2",
|
|
44
44
|
"framer-motion": "^11.7.0",
|
|
45
45
|
"jsonwebtoken": "^9.0.2",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"styled-components": "^5.3.5",
|
|
53
53
|
"zod": "^3.23.8"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "1d4f8ef72286e9f7575109be154b09f53c3107f4"
|
|
56
56
|
}
|
package/src/BlockUI/BlockUI.tsx
CHANGED
|
@@ -16,12 +16,11 @@ export const BlockUI = (props: Props) => {
|
|
|
16
16
|
return (
|
|
17
17
|
<div>
|
|
18
18
|
<div className="relative">
|
|
19
|
-
<div className="absolute bg-gray-100 bg-opacity-
|
|
19
|
+
<div className="absolute bg-gray-100 bg-opacity-80 z-10 h-full w-full flex items-center justify-center">
|
|
20
20
|
<div className="flex items-center">
|
|
21
21
|
<span className="text-3xl mr-4">{loadingText}</span>
|
|
22
|
-
{/* <!-- loading icon --> */}
|
|
23
22
|
<svg
|
|
24
|
-
className="animate-spin h-
|
|
23
|
+
className="animate-spin h-36 w-36 text-gray-600"
|
|
25
24
|
xmlns="http://www.w3.org/2000/svg"
|
|
26
25
|
fill="none"
|
|
27
26
|
viewBox="0 0 24 24"
|
|
@@ -40,7 +39,6 @@ export const BlockUI = (props: Props) => {
|
|
|
40
39
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
41
40
|
></path>
|
|
42
41
|
</svg>
|
|
43
|
-
{/* <!-- end loading icon --> */}
|
|
44
42
|
</div>
|
|
45
43
|
</div>
|
|
46
44
|
{children}
|
package/src/Buttons/Button.tsx
CHANGED
|
@@ -78,8 +78,6 @@ export const Button = (props: Props) => {
|
|
|
78
78
|
|
|
79
79
|
const color: ColorInterface = COLORS[selectedColor];
|
|
80
80
|
|
|
81
|
-
const inside = children ?? title;
|
|
82
|
-
|
|
83
81
|
const errorMessage = formHasErrors
|
|
84
82
|
? Object.values(formErrors)
|
|
85
83
|
.map((error) => error?.message?.toString())
|
|
@@ -87,36 +85,34 @@ export const Button = (props: Props) => {
|
|
|
87
85
|
: "";
|
|
88
86
|
|
|
89
87
|
const buttonContent = (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
disabled
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
</button>
|
|
119
|
-
</>
|
|
88
|
+
<button
|
|
89
|
+
type={type}
|
|
90
|
+
name={"action"}
|
|
91
|
+
value={name}
|
|
92
|
+
disabled={
|
|
93
|
+
loading || disabled || (enableFormErrorsValidation && formHasErrors)
|
|
94
|
+
}
|
|
95
|
+
onClick={onClickSave}
|
|
96
|
+
className={`${
|
|
97
|
+
loading || disabled || (enableFormErrorsValidation && formHasErrors)
|
|
98
|
+
? " bg-opacity-25 "
|
|
99
|
+
: ""
|
|
100
|
+
} ${
|
|
101
|
+
loading
|
|
102
|
+
? " cursor-progress"
|
|
103
|
+
: `${
|
|
104
|
+
disabled || (enableFormErrorsValidation && formHasErrors)
|
|
105
|
+
? ""
|
|
106
|
+
: `hover:${color.bg700}`
|
|
107
|
+
}`
|
|
108
|
+
} inline-flex justify-center rounded-md border border-transparent ${
|
|
109
|
+
color.bg600
|
|
110
|
+
} py-2 px-4 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:${
|
|
111
|
+
color.ring500
|
|
112
|
+
} focus:ring-offset-2 ${className}`}
|
|
113
|
+
>
|
|
114
|
+
{loading ? children ?? loadingText : children ?? title}
|
|
115
|
+
</button>
|
|
120
116
|
);
|
|
121
117
|
|
|
122
118
|
return (
|