@axzydev/axzy_ui_system 1.2.9 → 1.2.12
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/README.md +6 -0
- package/dist/index.cjs +313 -242
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +142 -6
- package/dist/index.d.ts +142 -6
- package/dist/index.js +313 -242
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/snippets/axzy-ui-system.code-snippets +547 -0
- package/src/App.tsx +37 -34
- package/src/components/avatar/avatar.props.ts +12 -1
- package/src/components/avatar/avatar.stories.tsx +19 -0
- package/src/components/avatar/avatar.tsx +27 -4
- package/src/components/calendar/calendar.tsx +1 -1
- package/src/components/card/card.tsx +11 -8
- package/src/components/confirm-dialog/confirm-dialog.tsx +1 -1
- package/src/components/data-table/dataTable.props.ts +10 -0
- package/src/components/data-table/dataTable.tsx +27 -16
- package/src/components/date-picker/datePicker.tsx +1 -1
- package/src/components/dialog/dialog.tsx +3 -2
- package/src/components/divider/divider.tsx +1 -1
- package/src/components/drawer/drawer.tsx +1 -1
- package/src/components/dropfile/dropfile.props.ts +6 -0
- package/src/components/dropfile/dropfile.tsx +65 -30
- package/src/components/form-builder/fieldRenderer.tsx +3 -3
- package/src/components/input/input.tsx +7 -7
- package/src/components/layout/layout.tsx +1 -1
- package/src/components/loader/loader.tsx +1 -1
- package/src/components/navbar/navbar.tsx +10 -10
- package/src/components/pagination/pagination.tsx +11 -11
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/search-select/search-select.tsx +11 -11
- package/src/components/searchTable/components/EditableCell.tsx +1 -1
- package/src/components/searchTable/components/PaginationControls.tsx +2 -2
- package/src/components/searchTable/components/PaginationInfo.tsx +1 -1
- package/src/components/searchTable/components/SearchAndSortBar.tsx +1 -1
- package/src/components/searchTable/components/SearchInput.tsx +1 -1
- package/src/components/searchTable/components/SortButton.tsx +3 -3
- package/src/components/searchTable/components/TableHeader.tsx +1 -1
- package/src/components/searchTable/components/TableRow.tsx +4 -4
- package/src/components/searchTable/searchTable.tsx +2 -2
- package/src/components/select/select.tsx +8 -10
- package/src/components/sidebar/sidebar.tsx +29 -29
- package/src/components/slider/slider.tsx +3 -3
- package/src/components/stepper/stepper.props.ts +4 -0
- package/src/components/stepper/stepper.tsx +5 -5
- package/src/components/table/table.props.ts +21 -3
- package/src/components/table/table.tsx +27 -16
- package/src/components/tabs/tabs.tsx +4 -4
- package/src/components/textarea/textarea.tsx +3 -3
- package/src/components/theme-provider/themeProvider.props.ts +21 -3
- package/src/components/theme-provider/themeProvider.tsx +32 -32
- package/src/components/time-picker/timePicker.tsx +5 -5
- package/src/components/toast/toast.tsx +1 -1
- package/src/components/tooltip/tooltip.tsx +1 -1
- package/src/components/topbar/topbar.tsx +7 -7
- package/src/dev.css +1 -1
- package/src/hooks/useClickOutside.ts +8 -0
- package/src/hooks/useTableState.ts +5 -2
- package/src/index.css +24 -1
- package/src/showcases/HomeShowcase.tsx +95 -3
- package/src/theme/theme.ts +38 -17
- package/src/types/field.types.ts +70 -7
- package/src/utils/styles.ts +5 -5
|
@@ -3,6 +3,7 @@ import { useDropzone } from "react-dropzone";
|
|
|
3
3
|
// import pdfjsLib from "@/hooks/pdf"; // Disabled as hook is missing
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import ITText from "@/components/text/text";
|
|
6
|
+
import ITButton from "@/components/button/button";
|
|
6
7
|
import { ITDropfileProps, FileTypeEnum, UploadStatus } from "./dropfile.props";
|
|
7
8
|
export { FileTypeEnum, UploadStatus } from "./dropfile.props";
|
|
8
9
|
|
|
@@ -94,6 +95,24 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
94
95
|
case FileTypeEnum.JPEG:
|
|
95
96
|
accept[FileTypeEnum.JPEG] = [".jpeg", ".jpg"];
|
|
96
97
|
break;
|
|
98
|
+
case FileTypeEnum.MP4:
|
|
99
|
+
accept[FileTypeEnum.MP4] = [".mp4"];
|
|
100
|
+
break;
|
|
101
|
+
case FileTypeEnum.MOV:
|
|
102
|
+
accept[FileTypeEnum.MOV] = [".mov"];
|
|
103
|
+
break;
|
|
104
|
+
case FileTypeEnum.AVI:
|
|
105
|
+
accept[FileTypeEnum.AVI] = [".avi"];
|
|
106
|
+
break;
|
|
107
|
+
case FileTypeEnum.MKV:
|
|
108
|
+
accept[FileTypeEnum.MKV] = [".mkv"];
|
|
109
|
+
break;
|
|
110
|
+
case FileTypeEnum.VIDEO_3GPP:
|
|
111
|
+
accept[FileTypeEnum.VIDEO_3GPP] = [".3gp"];
|
|
112
|
+
break;
|
|
113
|
+
case FileTypeEnum.WEBM:
|
|
114
|
+
accept[FileTypeEnum.WEBM] = [".webm"];
|
|
115
|
+
break;
|
|
97
116
|
}
|
|
98
117
|
});
|
|
99
118
|
|
|
@@ -121,6 +140,14 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
121
140
|
case FileTypeEnum.JPEG:
|
|
122
141
|
if (!extensions.includes("IMAGEN")) extensions.push("IMAGEN");
|
|
123
142
|
break;
|
|
143
|
+
case FileTypeEnum.MP4:
|
|
144
|
+
case FileTypeEnum.MOV:
|
|
145
|
+
case FileTypeEnum.AVI:
|
|
146
|
+
case FileTypeEnum.MKV:
|
|
147
|
+
case FileTypeEnum.VIDEO_3GPP:
|
|
148
|
+
case FileTypeEnum.WEBM:
|
|
149
|
+
if (!extensions.includes("VIDEO")) extensions.push("VIDEO");
|
|
150
|
+
break;
|
|
124
151
|
}
|
|
125
152
|
});
|
|
126
153
|
|
|
@@ -256,8 +283,8 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
256
283
|
return (
|
|
257
284
|
<div className={clsx("w-full transition-all duration-300", containerClassName)}>
|
|
258
285
|
<div className="flex items-center justify-between mb-2">
|
|
259
|
-
<label className="block text-sm font-semibold text-
|
|
260
|
-
<ITText as="span">Subir archivo </ITText><ITText as="span" className="text-
|
|
286
|
+
<label className="block text-sm font-semibold text-secondary-700">
|
|
287
|
+
<ITText as="span">Subir archivo </ITText><ITText as="span" className="text-secondary-400 font-normal text-xs">({getFileExtensions()})</ITText>
|
|
261
288
|
</label>
|
|
262
289
|
|
|
263
290
|
{showStatusBadge && selectedFile && (
|
|
@@ -274,15 +301,15 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
274
301
|
${
|
|
275
302
|
isDragActive
|
|
276
303
|
? "border-primary-500 bg-primary-50 scale-[1.01]"
|
|
277
|
-
: "border-
|
|
304
|
+
: "border-secondary-300 bg-white hover:border-primary-400 hover:bg-secondary-50"
|
|
278
305
|
}
|
|
279
306
|
`}
|
|
280
307
|
>
|
|
281
308
|
<input {...getInputProps()} />
|
|
282
309
|
|
|
283
|
-
<div className={`mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? 'bg-primary-100' : 'bg-
|
|
310
|
+
<div className={`mb-3 p-3 rounded-full transition-colors duration-300 ${isDragActive ? 'bg-primary-100' : 'bg-secondary-100 group-hover:bg-primary-50'}`}>
|
|
284
311
|
<svg
|
|
285
|
-
className={`w-6 h-6 transition-colors duration-300 ${isDragActive ? 'text-primary-600' : 'text-
|
|
312
|
+
className={`w-6 h-6 transition-colors duration-300 ${isDragActive ? 'text-primary-600' : 'text-secondary-400 group-hover:text-primary-500'}`}
|
|
286
313
|
fill="none" viewBox="0 0 24 24" stroke="currentColor"
|
|
287
314
|
>
|
|
288
315
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
|
@@ -290,14 +317,14 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
290
317
|
</div>
|
|
291
318
|
|
|
292
319
|
<div className="text-center space-y-1">
|
|
293
|
-
<ITText as="p" className={`text-sm font-medium transition-colors duration-300 ${isDragActive ? 'text-primary-700' : 'text-
|
|
320
|
+
<ITText as="p" className={`text-sm font-medium transition-colors duration-300 ${isDragActive ? 'text-primary-700' : 'text-secondary-700'}`}>
|
|
294
321
|
{isDragActive ? "¡Suelta aquí!" : "Haz clic o arrastra"}
|
|
295
322
|
</ITText>
|
|
296
323
|
</div>
|
|
297
324
|
</div>
|
|
298
325
|
) : (
|
|
299
|
-
<div className="w-full bg-white border border-
|
|
300
|
-
<div className="flex items-center justify-between p-3 bg-
|
|
326
|
+
<div className="w-full bg-white border border-secondary-200 rounded-xl shadow-sm overflow-hidden animate-fade-in">
|
|
327
|
+
<div className="flex items-center justify-between p-3 bg-secondary-50 border-b border-secondary-100">
|
|
301
328
|
<div className="flex items-center gap-3 overflow-hidden">
|
|
302
329
|
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-primary-100 flex items-center justify-center text-primary-600">
|
|
303
330
|
{(selectedFile && fileType?.startsWith('image/')) || (!selectedFile && imagePreview) ? (
|
|
@@ -311,17 +338,17 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
311
338
|
)}
|
|
312
339
|
</div>
|
|
313
340
|
<div className="min-w-0">
|
|
314
|
-
<ITText as="p" className="text-xs font-medium text-
|
|
341
|
+
<ITText as="p" className="text-xs font-medium text-secondary-900 truncate" title={selectedFile?.name || "Imagen cargada"}>
|
|
315
342
|
{selectedFile?.name || "Imagen cargada"}
|
|
316
343
|
</ITText>
|
|
317
|
-
<ITText as="p" className="text-[10px] text-
|
|
344
|
+
<ITText as="p" className="text-[10px] text-secondary-500">
|
|
318
345
|
{selectedFile ? (selectedFile.size / 1024 / 1024).toFixed(2) + " MB" : ""}
|
|
319
346
|
</ITText>
|
|
320
347
|
</div>
|
|
321
348
|
</div>
|
|
322
349
|
</div>
|
|
323
350
|
|
|
324
|
-
<div className={clsx("relative bg-
|
|
351
|
+
<div className={clsx("relative bg-secondary-100 flex items-center justify-center", !contentClassName ? "max-h-[200px] min-h-[100px] overflow-auto" : contentClassName)}>
|
|
325
352
|
{((selectedFile && fileType?.startsWith('image/')) || (!selectedFile && imagePreview)) ? (
|
|
326
353
|
<img
|
|
327
354
|
src={imagePreview}
|
|
@@ -329,7 +356,7 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
329
356
|
className="w-full h-full object-contain max-h-[200px]"
|
|
330
357
|
/>
|
|
331
358
|
) : (
|
|
332
|
-
<div className="py-8 flex flex-col items-center text-
|
|
359
|
+
<div className="py-8 flex flex-col items-center text-secondary-400">
|
|
333
360
|
<svg className="w-10 h-10 mb-2 opacity-50" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
334
361
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
335
362
|
</svg>
|
|
@@ -338,44 +365,52 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
338
365
|
)}
|
|
339
366
|
</div>
|
|
340
367
|
|
|
341
|
-
<div className="px-3 py-2 bg-white border-t border-
|
|
368
|
+
<div className="px-3 py-2 bg-white border-t border-secondary-100 flex justify-end gap-2">
|
|
342
369
|
{!isConfirmed ? (
|
|
343
370
|
<>
|
|
344
|
-
<
|
|
371
|
+
<ITButton
|
|
345
372
|
type="button"
|
|
373
|
+
variant="outlined"
|
|
374
|
+
color="secondary"
|
|
375
|
+
size="small"
|
|
346
376
|
onClick={handleCancel}
|
|
347
|
-
className="px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
|
|
348
377
|
>
|
|
349
|
-
<ITText
|
|
350
|
-
</
|
|
351
|
-
<
|
|
378
|
+
<ITText>Cancelar</ITText>
|
|
379
|
+
</ITButton>
|
|
380
|
+
<ITButton
|
|
352
381
|
type="button"
|
|
382
|
+
variant="filled"
|
|
383
|
+
color="primary"
|
|
384
|
+
size="small"
|
|
353
385
|
onClick={handleConfirm}
|
|
354
|
-
className="px-3 py-1.5 text-xs font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 shadow-sm transition-colors flex items-center gap-1"
|
|
355
386
|
>
|
|
356
|
-
<
|
|
357
|
-
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
387
|
+
<div className="flex items-center gap-2">
|
|
388
|
+
<ITText>Confirmar</ITText>
|
|
389
|
+
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
390
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
391
|
+
</svg>
|
|
392
|
+
</div>
|
|
393
|
+
</ITButton>
|
|
361
394
|
</>
|
|
362
395
|
) : (
|
|
363
|
-
<
|
|
396
|
+
<ITButton
|
|
364
397
|
type="button"
|
|
398
|
+
variant="outlined"
|
|
399
|
+
color="danger"
|
|
400
|
+
size="small"
|
|
365
401
|
onClick={handleDelete}
|
|
366
|
-
className="px-3 py-1.5 text-xs font-medium text-danger-600 bg-danger-50 border border-danger-100 rounded-lg hover:bg-danger-100 transition-colors flex items-center gap-1"
|
|
367
402
|
>
|
|
368
403
|
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
369
404
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
370
405
|
</svg>
|
|
371
|
-
<ITText
|
|
372
|
-
</
|
|
406
|
+
<ITText>Eliminar</ITText>
|
|
407
|
+
</ITButton>
|
|
373
408
|
)}
|
|
374
409
|
</div>
|
|
375
410
|
|
|
376
411
|
{uploadStatus === UploadStatus.UPLOADING && (
|
|
377
412
|
<div className="px-4 pb-2">
|
|
378
|
-
<div className="w-full bg-
|
|
413
|
+
<div className="w-full bg-secondary-200 rounded-full h-1.5">
|
|
379
414
|
<div
|
|
380
415
|
className="bg-primary-600 h-1.5 rounded-full transition-all duration-1000 ease-out"
|
|
381
416
|
style={{
|
|
@@ -392,4 +427,4 @@ const ITDropfile: React.FC<ITDropfileProps> = ({
|
|
|
392
427
|
);
|
|
393
428
|
};
|
|
394
429
|
|
|
395
|
-
export default ITDropfile;
|
|
430
|
+
export default ITDropfile;
|
|
@@ -228,7 +228,7 @@ const ITFieldRenderer = ({
|
|
|
228
228
|
return (
|
|
229
229
|
<div className={clsx("w-full col-span-full", activeConfig.className)}>
|
|
230
230
|
{label && (
|
|
231
|
-
<ITText as="h4" className="text-lg font-semibold text-
|
|
231
|
+
<ITText as="h4" className="text-lg font-semibold text-secondary-800 mb-4">
|
|
232
232
|
{label}
|
|
233
233
|
</ITText>
|
|
234
234
|
)}
|
|
@@ -246,8 +246,8 @@ const ITFieldRenderer = ({
|
|
|
246
246
|
|
|
247
247
|
case "array":
|
|
248
248
|
return (
|
|
249
|
-
<div className="p-4 border-2 border-dashed border-
|
|
250
|
-
<ITText as="p" className="text-sm text-
|
|
249
|
+
<div className="p-4 border-2 border-dashed border-secondary-200 rounded-xl">
|
|
250
|
+
<ITText as="p" className="text-sm text-secondary-500 text-center">
|
|
251
251
|
Array Field: {label}
|
|
252
252
|
</ITText>
|
|
253
253
|
</div>
|
|
@@ -472,12 +472,12 @@ const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
|
472
472
|
type === "checkbox" && "form-checkbox rounded",
|
|
473
473
|
className,
|
|
474
474
|
{ [disabledOverlay]: disabled },
|
|
475
|
-
{ "border-
|
|
475
|
+
{ "border-danger-500": hasError }
|
|
476
476
|
)}
|
|
477
477
|
/>
|
|
478
478
|
{label && (
|
|
479
|
-
<label htmlFor={name} className="text-sm text-
|
|
480
|
-
{label} {required && <ITText as="span" className="text-
|
|
479
|
+
<label htmlFor={name} className="text-sm text-secondary-700 dark:text-slate-300 select-none">
|
|
480
|
+
{label} {required && <ITText as="span" className="text-danger-500">*</ITText>}
|
|
481
481
|
</label>
|
|
482
482
|
)}
|
|
483
483
|
</div>
|
|
@@ -493,7 +493,7 @@ const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
|
493
493
|
)}
|
|
494
494
|
>
|
|
495
495
|
{label}
|
|
496
|
-
{required && <ITText as="span" className="text-
|
|
496
|
+
{required && <ITText as="span" className="text-danger-500 ml-1">*</ITText>}
|
|
497
497
|
</label>
|
|
498
498
|
)}
|
|
499
499
|
|
|
@@ -594,7 +594,7 @@ const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
|
594
594
|
{type === "password" && (
|
|
595
595
|
<button
|
|
596
596
|
type="button"
|
|
597
|
-
className="absolute inset-y-0 right-0 flex items-center pr-3 z-10 text-
|
|
597
|
+
className="absolute inset-y-0 right-0 flex items-center pr-3 z-10 text-secondary-400 hover:text-secondary-600 focus:outline-none"
|
|
598
598
|
onClick={() => setShowPassword(!showPassword)}
|
|
599
599
|
tabIndex={-1} // Don't allow tabbing into the eye icon
|
|
600
600
|
>
|
|
@@ -627,7 +627,7 @@ const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
|
627
627
|
{/* Length hint below if needed */}
|
|
628
628
|
{showHintLength && (minLength || maxLength) && !isCheckboxOrRadio && (
|
|
629
629
|
<div className="mt-1 text-xs">
|
|
630
|
-
<ITText as="p" className="text-
|
|
630
|
+
<ITText as="p" className="text-secondary-500">
|
|
631
631
|
{currentLength}{maxLength && `/${maxLength}`}
|
|
632
632
|
</ITText>
|
|
633
633
|
</div>
|
|
@@ -636,7 +636,7 @@ const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
|
636
636
|
{/* Validation for checkbox/radio - keep below */}
|
|
637
637
|
{isCheckboxOrRadio && hasError && (
|
|
638
638
|
<div className="mt-1 text-xs">
|
|
639
|
-
<ITText as="p" className="text-
|
|
639
|
+
<ITText as="p" className="text-danger-500">{errorMessage}</ITText>
|
|
640
640
|
</div>
|
|
641
641
|
)}
|
|
642
642
|
</div>
|
|
@@ -73,7 +73,7 @@ export default function ITLayout({
|
|
|
73
73
|
{/* MOBILE SIDEBAR PANE */}
|
|
74
74
|
{mobileSidebarOpen && (
|
|
75
75
|
<div
|
|
76
|
-
className="lg:hidden fixed inset-0 z-
|
|
76
|
+
className="lg:hidden fixed inset-0 z-[40] transition-opacity duration-300 backdrop-blur-sm bg-black/40"
|
|
77
77
|
onClick={() => setMobileSidebarOpen(false)}
|
|
78
78
|
>
|
|
79
79
|
<div
|
|
@@ -94,7 +94,7 @@ export default function ITLoader({
|
|
|
94
94
|
: size === "lg"
|
|
95
95
|
? "h-2"
|
|
96
96
|
: "h-2.5"
|
|
97
|
-
} bg-
|
|
97
|
+
} bg-secondary-200 rounded-full overflow-hidden ${className}`}
|
|
98
98
|
>
|
|
99
99
|
<div
|
|
100
100
|
className={`h-full animate-progress ${colorClass}`}
|
|
@@ -80,12 +80,12 @@ export default function ITNavbar({
|
|
|
80
80
|
// Legacy behavior - original navbar implementation
|
|
81
81
|
return (
|
|
82
82
|
<div className="flex flex-col h-screen">
|
|
83
|
-
<nav className="bg-white border-b border-
|
|
83
|
+
<nav className="bg-white border-b border-secondary-200">
|
|
84
84
|
<div className="flex items-center justify-between mx-auto p-4">
|
|
85
85
|
<div className="flex items-center space-x-3 rtl:space-x-reverse">
|
|
86
86
|
{logo && <div className="h-8">{logo}</div>}
|
|
87
87
|
{logoText && (
|
|
88
|
-
<ITText as="span" className="self-center text-2xl font-semibold whitespace-nowrap text-
|
|
88
|
+
<ITText as="span" className="self-center text-2xl font-semibold whitespace-nowrap text-secondary-900">
|
|
89
89
|
{logoText}
|
|
90
90
|
</ITText>
|
|
91
91
|
)}
|
|
@@ -99,7 +99,7 @@ export default function ITNavbar({
|
|
|
99
99
|
<div className="relative">
|
|
100
100
|
<button
|
|
101
101
|
type="button"
|
|
102
|
-
className="flex text-sm bg-
|
|
102
|
+
className="flex text-sm bg-secondary-200 rounded-full md:me-0 focus:ring-4 focus:ring-secondary-300"
|
|
103
103
|
onClick={toggleUserMenu}
|
|
104
104
|
>
|
|
105
105
|
{userMenu.userImage ? (
|
|
@@ -109,20 +109,20 @@ export default function ITNavbar({
|
|
|
109
109
|
alt="user photo"
|
|
110
110
|
/>
|
|
111
111
|
) : (
|
|
112
|
-
<FaUserCircle className="w-8 h-8 text-
|
|
112
|
+
<FaUserCircle className="w-8 h-8 text-secondary-500" />
|
|
113
113
|
)}
|
|
114
114
|
</button>
|
|
115
115
|
|
|
116
116
|
{isUserMenuOpen && (
|
|
117
117
|
<div
|
|
118
118
|
ref={userMenuRef}
|
|
119
|
-
className="z-
|
|
119
|
+
className="z-[70] absolute right-0 mt-2 text-base list-none bg-white divide-y divide-secondary-100 rounded-lg shadow-sm"
|
|
120
120
|
>
|
|
121
121
|
<div className="px-4 py-3">
|
|
122
|
-
<ITText as="span" className="block text-sm text-
|
|
122
|
+
<ITText as="span" className="block text-sm text-secondary-900">
|
|
123
123
|
{userMenu.userName}
|
|
124
124
|
</ITText>
|
|
125
|
-
<ITText as="span" className="block text-sm text-
|
|
125
|
+
<ITText as="span" className="block text-sm text-secondary-500 truncate">
|
|
126
126
|
{userMenu.userEmail}
|
|
127
127
|
</ITText>
|
|
128
128
|
</div>
|
|
@@ -134,7 +134,7 @@ export default function ITNavbar({
|
|
|
134
134
|
item.onClick();
|
|
135
135
|
setIsUserMenuOpen(false);
|
|
136
136
|
}}
|
|
137
|
-
className="block px-4 py-2 text-sm text-
|
|
137
|
+
className="block px-4 py-2 text-sm text-secondary-700 hover:bg-secondary-100 w-full text-left"
|
|
138
138
|
>
|
|
139
139
|
<ITText as="span">{item.label}</ITText>
|
|
140
140
|
</button>
|
|
@@ -152,13 +152,13 @@ export default function ITNavbar({
|
|
|
152
152
|
|
|
153
153
|
<div className="flex-1 flex overflow-hidden relative">
|
|
154
154
|
{(showSidebar || showSidebarOnMobile) && (
|
|
155
|
-
<aside className="fixed inset-y-0 left-0 w-64 bg-
|
|
155
|
+
<aside className="fixed inset-y-0 left-0 w-64 bg-secondary-50 transform transition-transform duration-300 ease-in-out z-[40] shadow-lg md:static md:transform-none md:shadow-none md:border-r md:border-secondary-200">
|
|
156
156
|
<div className="h-full overflow-y-auto py-4 px-3">
|
|
157
157
|
<ul className="space-y-2 font-medium">{sidebarItems}</ul>
|
|
158
158
|
</div>
|
|
159
159
|
</aside>
|
|
160
160
|
)}
|
|
161
|
-
<main className="flex-1 bg-
|
|
161
|
+
<main className="flex-1 bg-secondary-100 overflow-y-auto">
|
|
162
162
|
{children}
|
|
163
163
|
</main>
|
|
164
164
|
</div>
|
|
@@ -146,8 +146,8 @@ export default function ITPagination({
|
|
|
146
146
|
className={clsx(
|
|
147
147
|
baseItemClass,
|
|
148
148
|
currentPage === 1
|
|
149
|
-
? "text-
|
|
150
|
-
: "text-
|
|
149
|
+
? "text-secondary-300 cursor-not-allowed"
|
|
150
|
+
: "text-secondary-500 hover:bg-secondary-100"
|
|
151
151
|
)}
|
|
152
152
|
onClick={handlePrevious}
|
|
153
153
|
aria-disabled={currentPage === 1}
|
|
@@ -162,7 +162,7 @@ export default function ITPagination({
|
|
|
162
162
|
<ITText
|
|
163
163
|
as="div"
|
|
164
164
|
key={`dots-${idx}`}
|
|
165
|
-
className="flex items-center justify-center w-8 h-8 select-none text-
|
|
165
|
+
className="flex items-center justify-center w-8 h-8 select-none text-secondary-400"
|
|
166
166
|
>
|
|
167
167
|
…
|
|
168
168
|
</ITText>
|
|
@@ -177,7 +177,7 @@ export default function ITPagination({
|
|
|
177
177
|
key={pageNumber}
|
|
178
178
|
className={clsx(
|
|
179
179
|
baseItemClass,
|
|
180
|
-
isActive ? "text-white" : "text-
|
|
180
|
+
isActive ? "text-white" : "text-secondary-600 hover:bg-secondary-100"
|
|
181
181
|
)}
|
|
182
182
|
style={{
|
|
183
183
|
backgroundColor: isActive ? resolvedBgColor : undefined,
|
|
@@ -196,8 +196,8 @@ export default function ITPagination({
|
|
|
196
196
|
className={clsx(
|
|
197
197
|
baseItemClass,
|
|
198
198
|
currentPage === totalPages
|
|
199
|
-
? "text-
|
|
200
|
-
: "text-
|
|
199
|
+
? "text-secondary-300 cursor-not-allowed"
|
|
200
|
+
: "text-secondary-500 hover:bg-secondary-100"
|
|
201
201
|
)}
|
|
202
202
|
onClick={handleNext}
|
|
203
203
|
aria-disabled={currentPage === totalPages}
|
|
@@ -214,8 +214,8 @@ export default function ITPagination({
|
|
|
214
214
|
|
|
215
215
|
return (
|
|
216
216
|
<div className={clsx("flex flex-col sm:flex-row justify-between items-center gap-4 w-full", className)}>
|
|
217
|
-
<div className="flex items-center gap-4 text-sm text-
|
|
218
|
-
<div className="flex items-center gap-2 bg-
|
|
217
|
+
<div className="flex items-center gap-4 text-sm text-secondary-500">
|
|
218
|
+
<div className="flex items-center gap-2 bg-secondary-50 px-3 py-1 rounded-lg border border-secondary-200">
|
|
219
219
|
<ITText as="span" className="text-xs font-medium">Mostrar</ITText>
|
|
220
220
|
<ITSelect
|
|
221
221
|
name="itemsPerPage"
|
|
@@ -227,16 +227,16 @@ export default function ITPagination({
|
|
|
227
227
|
onChange={(e) => onItemsPerPageChange(Number(e.target.value))}
|
|
228
228
|
onBlur={() => {}}
|
|
229
229
|
size="small"
|
|
230
|
-
className="!w-14 !h-6 !text-xs !py-0 !px-1! !border-none !bg-transparent !ring-0 focus:!ring-0 cursor-pointer font-bold text-
|
|
230
|
+
className="!w-14 !h-6 !text-xs !py-0 !px-1! !border-none !bg-transparent !ring-0 focus:!ring-0 cursor-pointer font-bold text-secondary-700"
|
|
231
231
|
placeholder=""
|
|
232
232
|
/>
|
|
233
233
|
</div>
|
|
234
234
|
|
|
235
235
|
{totalItems !== undefined && (
|
|
236
236
|
<>
|
|
237
|
-
<ITText as="span" className="text-
|
|
237
|
+
<ITText as="span" className="text-secondary-300">|</ITText>
|
|
238
238
|
<ITText as="span" className="text-xs">
|
|
239
|
-
<ITText as="span" className="font-semibold text-
|
|
239
|
+
<ITText as="span" className="font-semibold text-secondary-700">{startItem}</ITText><ITText as="span"> - </ITText><ITText as="span" className="font-semibold text-secondary-700">{endItem}</ITText><ITText as="span"> de </ITText><ITText as="span" className="font-semibold text-secondary-900">{totalItems}</ITText>
|
|
240
240
|
</ITText>
|
|
241
241
|
</>
|
|
242
242
|
)}
|
|
@@ -47,7 +47,7 @@ export default function ITPopover({
|
|
|
47
47
|
{trigger}
|
|
48
48
|
</div>
|
|
49
49
|
{open && (
|
|
50
|
-
<div className={clsx("absolute z-[
|
|
50
|
+
<div className={clsx("absolute z-[70]", positionClasses[position])}>
|
|
51
51
|
<div className="bg-white dark:bg-slate-800 rounded-xl shadow-xl border border-slate-200 dark:border-slate-700 p-3 min-w-[160px]">
|
|
52
52
|
{children}
|
|
53
53
|
</div>
|
|
@@ -148,7 +148,7 @@ export default function ITSearchSelect({
|
|
|
148
148
|
const getInputStyle = () => {
|
|
149
149
|
const style: React.CSSProperties = {
|
|
150
150
|
backgroundColor: inputTheme.backgroundColor || "#ffffff",
|
|
151
|
-
borderColor: inputTheme.borderColor || "
|
|
151
|
+
borderColor: inputTheme.borderColor || "var(--color-secondary-300)",
|
|
152
152
|
borderRadius: inputTheme.borderRadius || "0.5rem",
|
|
153
153
|
padding: inputTheme.padding || "0.5rem 0.75rem",
|
|
154
154
|
fontSize: inputTheme.fontSize || "0.875rem",
|
|
@@ -160,8 +160,8 @@ export default function ITSearchSelect({
|
|
|
160
160
|
};
|
|
161
161
|
|
|
162
162
|
if (disabled) {
|
|
163
|
-
style.backgroundColor = inputTheme.disabled?.backgroundColor || "
|
|
164
|
-
style.borderColor = inputTheme.disabled?.borderColor || "
|
|
163
|
+
style.backgroundColor = inputTheme.disabled?.backgroundColor || "var(--color-secondary-100)";
|
|
164
|
+
style.borderColor = inputTheme.disabled?.borderColor || "var(--color-secondary-200)";
|
|
165
165
|
style.opacity = 0.7;
|
|
166
166
|
style.cursor = "not-allowed";
|
|
167
167
|
}
|
|
@@ -184,12 +184,12 @@ export default function ITSearchSelect({
|
|
|
184
184
|
{label && (
|
|
185
185
|
<ITText
|
|
186
186
|
as="label"
|
|
187
|
-
className={clsx("text-sm font-medium text-
|
|
188
|
-
"text-
|
|
187
|
+
className={clsx("text-sm font-medium text-secondary-700 dark:text-slate-300", {
|
|
188
|
+
"text-danger-500": hasError,
|
|
189
189
|
})}
|
|
190
190
|
>
|
|
191
191
|
<ITText as="span">{label}</ITText>
|
|
192
|
-
{required && <ITText as="span" className="text-
|
|
192
|
+
{required && <ITText as="span" className="text-danger-500 ml-1">*</ITText>}
|
|
193
193
|
</ITText>
|
|
194
194
|
)}
|
|
195
195
|
|
|
@@ -209,7 +209,7 @@ export default function ITSearchSelect({
|
|
|
209
209
|
style={getInputStyle()}
|
|
210
210
|
autoComplete="off"
|
|
211
211
|
/>
|
|
212
|
-
<div className="absolute right-3 flex items-center gap-2 text-
|
|
212
|
+
<div className="absolute right-3 flex items-center gap-2 text-secondary-400 pointer-events-none">
|
|
213
213
|
{isLoading && <div className="animate-spin h-4 w-4 border-2 border-primary-500 border-t-transparent rounded-full" />}
|
|
214
214
|
{!isLoading && <FaSearch size={14} className={clsx({ "text-primary-500": isFocused })} />}
|
|
215
215
|
</div>
|
|
@@ -217,7 +217,7 @@ export default function ITSearchSelect({
|
|
|
217
217
|
|
|
218
218
|
{/* Dropdown Panel */}
|
|
219
219
|
{isOpen && (
|
|
220
|
-
<div className="absolute z-
|
|
220
|
+
<div className="absolute z-[70] w-full mt-1 bg-white dark:bg-slate-900 border border-secondary-200 dark:border-slate-800 rounded-lg shadow-xl overflow-hidden animate-in fade-in zoom-in duration-200 origin-top">
|
|
221
221
|
<div className="max-h-60 overflow-y-auto">
|
|
222
222
|
{filteredOptions.length > 0 ? (
|
|
223
223
|
filteredOptions.map((option) => (
|
|
@@ -229,14 +229,14 @@ export default function ITSearchSelect({
|
|
|
229
229
|
"px-4 py-2 text-sm cursor-pointer transition-colors",
|
|
230
230
|
value === option[valueField]
|
|
231
231
|
? "bg-primary-50 dark:bg-primary-950/40 text-primary-700 dark:text-primary-300 font-medium"
|
|
232
|
-
: "hover:bg-
|
|
232
|
+
: "hover:bg-secondary-50 dark:hover:bg-slate-800 text-secondary-700 dark:text-slate-300"
|
|
233
233
|
)}
|
|
234
234
|
>
|
|
235
235
|
<ITText as="span">{option[labelField]}</ITText>
|
|
236
236
|
</ITText>
|
|
237
237
|
))
|
|
238
238
|
) : (
|
|
239
|
-
<ITText as="div" className="px-4 py-6 text-sm text-center text-
|
|
239
|
+
<ITText as="div" className="px-4 py-6 text-sm text-center text-secondary-500 italic">
|
|
240
240
|
{isLoading ? "Cargando..." : noResultsMessage}
|
|
241
241
|
</ITText>
|
|
242
242
|
)}
|
|
@@ -247,7 +247,7 @@ export default function ITSearchSelect({
|
|
|
247
247
|
|
|
248
248
|
{/* Error Message */}
|
|
249
249
|
{hasError && (
|
|
250
|
-
<ITText as="p" className="text-
|
|
250
|
+
<ITText as="p" className="text-danger-500 text-xs mt-1">{errorMessage}</ITText>
|
|
251
251
|
)}
|
|
252
252
|
</div>
|
|
253
253
|
);
|
|
@@ -143,7 +143,7 @@ export default function EditableCell<T>({
|
|
|
143
143
|
return (
|
|
144
144
|
<div className="w-full">
|
|
145
145
|
{renderInput()}
|
|
146
|
-
{error && <div className="text-
|
|
146
|
+
{error && <div className="text-danger-500 text-xs mt-1"><ITText as="span">{error}</ITText></div>}
|
|
147
147
|
</div>
|
|
148
148
|
);
|
|
149
149
|
}
|
|
@@ -36,7 +36,7 @@ export default function PaginationControls({
|
|
|
36
36
|
<PaginationInfo currentCount={currentCount} totalCount={totalCount} />
|
|
37
37
|
|
|
38
38
|
<div className="flex items-center space-x-2">
|
|
39
|
-
<ITText as="span" className="text-sm text-
|
|
39
|
+
<ITText as="span" className="text-sm text-secondary-700">Mostrar:</ITText>
|
|
40
40
|
<ITSelect
|
|
41
41
|
name="itemsPerPage"
|
|
42
42
|
options={itemsPerPageOptions.map((option) => ({
|
|
@@ -65,7 +65,7 @@ export default function PaginationControls({
|
|
|
65
65
|
<FaArrowLeft aria-hidden="true" />
|
|
66
66
|
</ITButton>
|
|
67
67
|
|
|
68
|
-
<ITText as="span" className="px-4 py-2 text-sm text-
|
|
68
|
+
<ITText as="span" className="px-4 py-2 text-sm text-secondary-700" aria-live="polite">
|
|
69
69
|
Página {pageIndex} de {totalPages}
|
|
70
70
|
</ITText>
|
|
71
71
|
|
|
@@ -13,7 +13,7 @@ export default function PaginationInfo({
|
|
|
13
13
|
className = "",
|
|
14
14
|
}: PaginationInfoProps) {
|
|
15
15
|
return (
|
|
16
|
-
<ITText as="span" className={`text-sm text-
|
|
16
|
+
<ITText as="span" className={`text-sm text-secondary-700 ${className}`}>
|
|
17
17
|
Mostrando {currentCount} de {totalCount} resultados
|
|
18
18
|
</ITText>
|
|
19
19
|
);
|
|
@@ -25,7 +25,7 @@ export default function SearchAndSortBar({
|
|
|
25
25
|
searchInputPlaceholder = "Buscar en todos los campos...",
|
|
26
26
|
}: SearchAndSortBarProps) {
|
|
27
27
|
return (
|
|
28
|
-
<div className="bg-
|
|
28
|
+
<div className="bg-secondary-50 px-6 py-4 border-b border-secondary-200">
|
|
29
29
|
<div className="flex items-center gap-4">
|
|
30
30
|
<SearchInput
|
|
31
31
|
placeholder={searchInputPlaceholder}
|
|
@@ -18,7 +18,7 @@ export default function SearchInput({
|
|
|
18
18
|
return (
|
|
19
19
|
<div className={`relative flex-1 ${className}`}>
|
|
20
20
|
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
21
|
-
<FaSearch className="h-5 w-5 text-
|
|
21
|
+
<FaSearch className="h-5 w-5 text-secondary-400" />
|
|
22
22
|
</div>
|
|
23
23
|
<ITInput
|
|
24
24
|
name="global-search"
|
|
@@ -19,7 +19,7 @@ export default function SortButton({
|
|
|
19
19
|
return (
|
|
20
20
|
<button
|
|
21
21
|
onClick={onClick}
|
|
22
|
-
className={`p-3 rounded-lg bg-white border border-
|
|
22
|
+
className={`p-3 rounded-lg bg-white border border-secondary-300 hover:bg-secondary-50 transition-colors duration-200 flex items-center gap-2 min-w-[120px] ${className}`}
|
|
23
23
|
aria-label={`Ordenar tabla ${
|
|
24
24
|
sortConfig
|
|
25
25
|
? sortConfig.direction === "asc"
|
|
@@ -36,9 +36,9 @@ export default function SortButton({
|
|
|
36
36
|
<FaSortDown className="w-4 h-4 text-slate-500" />
|
|
37
37
|
)
|
|
38
38
|
) : (
|
|
39
|
-
<FaSort className="w-4 h-4 text-
|
|
39
|
+
<FaSort className="w-4 h-4 text-secondary-500" />
|
|
40
40
|
)}
|
|
41
|
-
<ITText as="span" className="text-sm font-medium text-
|
|
41
|
+
<ITText as="span" className="text-sm font-medium text-secondary-700">
|
|
42
42
|
{sortConfig
|
|
43
43
|
? sortConfig.direction === "asc"
|
|
44
44
|
? "Asc ↑"
|
|
@@ -18,7 +18,7 @@ export default function TableHeader<T>({
|
|
|
18
18
|
}: TableHeaderProps<T>) {
|
|
19
19
|
return (
|
|
20
20
|
<thead>
|
|
21
|
-
<tr className="bg-white border-b border-
|
|
21
|
+
<tr className="bg-white border-b border-secondary-200">
|
|
22
22
|
{columns.map((col) => (
|
|
23
23
|
<TableHeaderCell
|
|
24
24
|
key={col.key}
|