@axzydev/axzy_ui_system 1.2.1 → 1.2.2
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/dist/index.css +82 -1
- package/dist/index.css.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +354 -0
- package/src/assets/logo.png +0 -0
- package/src/assets/react.svg +1 -0
- package/src/components/alert/alert.props.ts +13 -0
- package/src/components/alert/alert.stories.tsx +41 -0
- package/src/components/alert/alert.tsx +53 -0
- package/src/components/avatar/avatar.props.ts +14 -0
- package/src/components/avatar/avatar.stories.tsx +46 -0
- package/src/components/avatar/avatar.tsx +53 -0
- package/src/components/badget/badget.props.ts +12 -0
- package/src/components/badget/badget.stories.tsx +76 -0
- package/src/components/badget/badget.tsx +61 -0
- package/src/components/breadcrumbs/breadcrumbs.props.ts +13 -0
- package/src/components/breadcrumbs/breadcrumbs.stories.tsx +21 -0
- package/src/components/breadcrumbs/breadcrumbs.tsx +34 -0
- package/src/components/button/button.props.ts +18 -0
- package/src/components/button/button.stories.tsx +174 -0
- package/src/components/button/button.tsx +117 -0
- package/src/components/calendar/calendar.props.ts +33 -0
- package/src/components/calendar/calendar.stories.tsx +91 -0
- package/src/components/calendar/calendar.tsx +608 -0
- package/src/components/calendar/index.ts +3 -0
- package/src/components/card/card.props.ts +13 -0
- package/src/components/card/card.stories.tsx +58 -0
- package/src/components/card/card.tsx +79 -0
- package/src/components/checkbox/checkbox.props.ts +11 -0
- package/src/components/checkbox/checkbox.stories.tsx +54 -0
- package/src/components/checkbox/checkbox.tsx +52 -0
- package/src/components/confirm-dialog/confirm-dialog.props.ts +14 -0
- package/src/components/confirm-dialog/confirm-dialog.stories.tsx +33 -0
- package/src/components/confirm-dialog/confirm-dialog.tsx +45 -0
- package/src/components/data-table/ITDataTable.stories.tsx +213 -0
- package/src/components/data-table/dataTable.props.ts +69 -0
- package/src/components/data-table/dataTable.tsx +313 -0
- package/src/components/date-picker/date-picker.props.ts +30 -0
- package/src/components/date-picker/date-picker.stories.tsx +90 -0
- package/src/components/date-picker/datePicker.tsx +307 -0
- package/src/components/dialog/dialog.props.ts +9 -0
- package/src/components/dialog/dialog.stories.tsx +80 -0
- package/src/components/dialog/dialog.tsx +88 -0
- package/src/components/divider/divider.props.ts +8 -0
- package/src/components/divider/divider.stories.tsx +34 -0
- package/src/components/divider/divider.tsx +21 -0
- package/src/components/drawer/drawer.props.ts +14 -0
- package/src/components/drawer/drawer.stories.tsx +41 -0
- package/src/components/drawer/drawer.tsx +53 -0
- package/src/components/dropfile/dropfile.stories.tsx +75 -0
- package/src/components/dropfile/dropfile.tsx +407 -0
- package/src/components/empty-state/empty-state.props.ts +9 -0
- package/src/components/empty-state/empty-state.stories.tsx +20 -0
- package/src/components/empty-state/empty-state.tsx +21 -0
- package/src/components/flex/flex.props.ts +22 -0
- package/src/components/flex/flex.stories.tsx +71 -0
- package/src/components/flex/flex.tsx +79 -0
- package/src/components/form-builder/fieldRenderer.tsx +218 -0
- package/src/components/form-builder/formBuilder.context.tsx +70 -0
- package/src/components/form-builder/formBuilder.props.ts +43 -0
- package/src/components/form-builder/formBuilder.stories.tsx +317 -0
- package/src/components/form-builder/formBuilder.tsx +186 -0
- package/src/components/form-builder/useFormBuilder.ts +80 -0
- package/src/components/form-header/form-header.props.ts +5 -0
- package/src/components/form-header/form-header.tsx +38 -0
- package/src/components/grid/grid.props.ts +17 -0
- package/src/components/grid/grid.stories.tsx +72 -0
- package/src/components/grid/grid.tsx +69 -0
- package/src/components/image/image.props.ts +7 -0
- package/src/components/image/image.tsx +38 -0
- package/src/components/input/input.props.ts +49 -0
- package/src/components/input/input.stories.tsx +115 -0
- package/src/components/input/input.tsx +615 -0
- package/src/components/layout/layout.props.ts +10 -0
- package/src/components/layout/layout.stories.tsx +114 -0
- package/src/components/layout/layout.tsx +80 -0
- package/src/components/loader/loader.props.ts +8 -0
- package/src/components/loader/loader.stories.tsx +105 -0
- package/src/components/loader/loader.tsx +108 -0
- package/src/components/navbar/navbar.props.ts +37 -0
- package/src/components/navbar/navbar.tsx +328 -0
- package/src/components/page/page.props.ts +19 -0
- package/src/components/page/page.stories.tsx +98 -0
- package/src/components/page/page.tsx +90 -0
- package/src/components/page-header/page-header.props.ts +11 -0
- package/src/components/page-header/page-header.stories.tsx +61 -0
- package/src/components/page-header/page-header.tsx +62 -0
- package/src/components/pagination/pagination.props.ts +53 -0
- package/src/components/pagination/pagination.stories.tsx +111 -0
- package/src/components/pagination/pagination.tsx +241 -0
- package/src/components/popover/popover.props.ts +12 -0
- package/src/components/popover/popover.stories.tsx +25 -0
- package/src/components/popover/popover.tsx +45 -0
- package/src/components/progress/progress.props.ts +12 -0
- package/src/components/progress/progress.stories.tsx +40 -0
- package/src/components/progress/progress.tsx +52 -0
- package/src/components/radio/radio.props.ts +16 -0
- package/src/components/radio/radio.stories.tsx +50 -0
- package/src/components/radio/radio.tsx +58 -0
- package/src/components/search-select/index.ts +2 -0
- package/src/components/search-select/search-select.props.ts +46 -0
- package/src/components/search-select/search-select.stories.tsx +129 -0
- package/src/components/search-select/search-select.tsx +229 -0
- package/src/components/searchTable/components/EditableCell.tsx +149 -0
- package/src/components/searchTable/components/PaginationControls.tsx +86 -0
- package/src/components/searchTable/components/PaginationInfo.tsx +20 -0
- package/src/components/searchTable/components/SearchAndSortBar.tsx +53 -0
- package/src/components/searchTable/components/SearchInput.tsx +33 -0
- package/src/components/searchTable/components/SortButton.tsx +50 -0
- package/src/components/searchTable/components/TableEmptyState.tsx +22 -0
- package/src/components/searchTable/components/TableHeader.tsx +35 -0
- package/src/components/searchTable/components/TableHeaderCell.tsx +43 -0
- package/src/components/searchTable/components/TableRow.tsx +144 -0
- package/src/components/searchTable/searchTable.props.ts +56 -0
- package/src/components/searchTable/searchTable.tsx +187 -0
- package/src/components/segmented-control/segmented-control.props.ts +18 -0
- package/src/components/segmented-control/segmented-control.stories.tsx +63 -0
- package/src/components/segmented-control/segmented-control.tsx +52 -0
- package/src/components/select/select.props.ts +25 -0
- package/src/components/select/select.stories.tsx +86 -0
- package/src/components/select/select.tsx +150 -0
- package/src/components/sidebar/sidebar.props.ts +28 -0
- package/src/components/sidebar/sidebar.stories.tsx +117 -0
- package/src/components/sidebar/sidebar.tsx +313 -0
- package/src/components/skeleton/skeleton.props.ts +12 -0
- package/src/components/skeleton/skeleton.stories.tsx +30 -0
- package/src/components/skeleton/skeleton.tsx +45 -0
- package/src/components/slide/slide.props.ts +45 -0
- package/src/components/slide/slide.stories.tsx +121 -0
- package/src/components/slide/slide.tsx +109 -0
- package/src/components/slider/slider.props.ts +10 -0
- package/src/components/slider/slider.stories.tsx +30 -0
- package/src/components/slider/slider.tsx +49 -0
- package/src/components/stack/stack.props.ts +19 -0
- package/src/components/stack/stack.stories.tsx +79 -0
- package/src/components/stack/stack.tsx +79 -0
- package/src/components/stat-card/stat-card.props.ts +13 -0
- package/src/components/stat-card/stat-card.stories.tsx +41 -0
- package/src/components/stat-card/stat-card.tsx +44 -0
- package/src/components/stepper/stepper.css +26 -0
- package/src/components/stepper/stepper.props.ts +29 -0
- package/src/components/stepper/stepper.stories.tsx +155 -0
- package/src/components/stepper/stepper.tsx +227 -0
- package/src/components/table/table.props.ts +43 -0
- package/src/components/table/table.stories.tsx +189 -0
- package/src/components/table/table.tsx +376 -0
- package/src/components/tabs/tabs.props.ts +18 -0
- package/src/components/tabs/tabs.stories.tsx +32 -0
- package/src/components/tabs/tabs.tsx +74 -0
- package/src/components/text/text.props.ts +9 -0
- package/src/components/text/text.tsx +20 -0
- package/src/components/textarea/textarea.props.ts +15 -0
- package/src/components/textarea/textarea.stories.tsx +27 -0
- package/src/components/textarea/textarea.tsx +55 -0
- package/src/components/theme-provider/themeProvider.props.ts +28 -0
- package/src/components/theme-provider/themeProvider.tsx +1854 -0
- package/src/components/time-picker/timePicker.props.ts +16 -0
- package/src/components/time-picker/timePicker.stories.tsx +131 -0
- package/src/components/time-picker/timePicker.tsx +317 -0
- package/src/components/toast/toast.css +32 -0
- package/src/components/toast/toast.props.ts +13 -0
- package/src/components/toast/toast.stories.tsx +138 -0
- package/src/components/toast/toast.tsx +87 -0
- package/src/components/tooltip/tooltip.props.ts +11 -0
- package/src/components/tooltip/tooltip.stories.tsx +20 -0
- package/src/components/tooltip/tooltip.tsx +55 -0
- package/src/components/topbar/topbar.props.ts +21 -0
- package/src/components/topbar/topbar.stories.tsx +80 -0
- package/src/components/topbar/topbar.tsx +205 -0
- package/src/components/triple-filter/tripleFilter.props.ts +15 -0
- package/src/components/triple-filter/tripleFilter.stories.tsx +32 -0
- package/src/components/triple-filter/tripleFilter.tsx +50 -0
- package/src/hooks/useClickOutside.ts +21 -0
- package/src/hooks/useDebouncedSearch.ts +55 -0
- package/src/hooks/useEditableRow.ts +157 -0
- package/src/hooks/useTableState.ts +122 -0
- package/src/index.css +168 -0
- package/src/index.ts +165 -0
- package/src/main.tsx +9 -0
- package/src/showcases/DataShowcases.tsx +260 -0
- package/src/showcases/FeedbackShowcases.tsx +268 -0
- package/src/showcases/FormShowcases.tsx +1159 -0
- package/src/showcases/HomeShowcase.tsx +324 -0
- package/src/showcases/LayoutPrimitivesShowcases.tsx +569 -0
- package/src/showcases/NavigationShowcases.tsx +193 -0
- package/src/showcases/PageShowcases.tsx +207 -0
- package/src/showcases/ShowcaseLayout.tsx +139 -0
- package/src/showcases/StructureShowcases.tsx +152 -0
- package/src/types/badget.types.ts +37 -0
- package/src/types/button.types.ts +16 -0
- package/src/types/colors.types.ts +3 -0
- package/src/types/field.types.ts +103 -0
- package/src/types/formik.types.ts +15 -0
- package/src/types/input.types.ts +14 -0
- package/src/types/loader.types.ts +9 -0
- package/src/types/sizes.types.ts +1 -0
- package/src/types/table.types.ts +15 -0
- package/src/types/toast.types.ts +8 -0
- package/src/types/yup.types.ts +11 -0
- package/src/utils/color.utils.ts +99 -0
- package/src/utils/styles.ts +120 -0
- package/src/utils/table.utils.ts +10 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { ITStepperProps, Step } from "./stepper.props";
|
|
4
|
+
import { theme } from "@/theme/theme";
|
|
5
|
+
import ITButton from "../button/button";
|
|
6
|
+
import { FaChevronLeft, FaChevronRight, FaCheck } from "react-icons/fa";
|
|
7
|
+
import ITText from "@/components/text/text";
|
|
8
|
+
|
|
9
|
+
export default function ITStepper({
|
|
10
|
+
steps,
|
|
11
|
+
currentStep,
|
|
12
|
+
onFinish,
|
|
13
|
+
onStepChange,
|
|
14
|
+
allowClickToJump = true,
|
|
15
|
+
useIcons = false,
|
|
16
|
+
disableNext = false,
|
|
17
|
+
containerClassName,
|
|
18
|
+
stepClassName,
|
|
19
|
+
scrollableContent = false,
|
|
20
|
+
maxContentHeight = "400px",
|
|
21
|
+
color = "primary",
|
|
22
|
+
}: ITStepperProps) {
|
|
23
|
+
const [direction, setDirection] = useState<"next" | "prev">("next");
|
|
24
|
+
const contentRef = useRef<HTMLDivElement | null>(null);
|
|
25
|
+
const progressRef = useRef<HTMLDivElement | null>(null);
|
|
26
|
+
|
|
27
|
+
// Resolve theme color
|
|
28
|
+
const isThemeColor = color in theme.colors;
|
|
29
|
+
const resolvedColor = isThemeColor
|
|
30
|
+
? theme.colors[color as keyof typeof theme.colors][500]
|
|
31
|
+
: color;
|
|
32
|
+
|
|
33
|
+
// Effect for notifying parent of step change
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
onStepChange?.(currentStep);
|
|
36
|
+
}, [currentStep, onStepChange]);
|
|
37
|
+
|
|
38
|
+
// Effect for animation and focus management
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const pct = (currentStep / Math.max(1, steps.length - 1)) * 100;
|
|
41
|
+
|
|
42
|
+
if (progressRef.current) {
|
|
43
|
+
progressRef.current.style.width = `${pct}%`;
|
|
44
|
+
progressRef.current.style.backgroundColor = resolvedColor;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (contentRef.current) {
|
|
48
|
+
contentRef.current.classList.remove(
|
|
49
|
+
"animate-slide-in-left",
|
|
50
|
+
"animate-slide-in-right"
|
|
51
|
+
);
|
|
52
|
+
requestAnimationFrame(() => {
|
|
53
|
+
contentRef.current?.classList.add(
|
|
54
|
+
direction === "next"
|
|
55
|
+
? "animate-slide-in-right"
|
|
56
|
+
: "animate-slide-in-left"
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
contentRef.current?.focus();
|
|
62
|
+
}, [currentStep, direction, steps.length, resolvedColor]);
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
const nextStep = () => {
|
|
66
|
+
if (disableNext) return;
|
|
67
|
+
if (currentStep < steps.length - 1) {
|
|
68
|
+
setDirection("next");
|
|
69
|
+
onStepChange?.(currentStep + 1);
|
|
70
|
+
} else {
|
|
71
|
+
onFinish?.();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const prevStep = () => {
|
|
76
|
+
if (currentStep > 0) {
|
|
77
|
+
setDirection("prev");
|
|
78
|
+
onStepChange?.(currentStep - 1);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const jumpTo = (index: number) => {
|
|
83
|
+
if (!allowClickToJump) return;
|
|
84
|
+
if (index <= currentStep) {
|
|
85
|
+
setDirection(index > currentStep ? "next" : "prev");
|
|
86
|
+
onStepChange?.(index);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const renderStepContent = (
|
|
91
|
+
index: number,
|
|
92
|
+
isCompleted: boolean,
|
|
93
|
+
isActive: boolean
|
|
94
|
+
) => {
|
|
95
|
+
const step = steps[index];
|
|
96
|
+
|
|
97
|
+
if (isCompleted) {
|
|
98
|
+
return <FaCheck className="w-4 h-4" />;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (step.icon && useIcons) {
|
|
102
|
+
return (
|
|
103
|
+
<div className="flex items-center justify-center w-5 h-5">
|
|
104
|
+
{step.icon}
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return <ITText as="span" className="text-sm font-semibold">{index + 1}</ITText>;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div className={clsx("w-full max-w-5xl mx-auto px-4", containerClassName)}>
|
|
114
|
+
<div className="relative mb-8">
|
|
115
|
+
<div
|
|
116
|
+
className="absolute left-6 right-6 top-5 h-1 bg-gray-200 rounded-full z-0"
|
|
117
|
+
aria-hidden
|
|
118
|
+
/>
|
|
119
|
+
<div
|
|
120
|
+
ref={progressRef}
|
|
121
|
+
className="absolute left-6 top-5 h-1 rounded-full z-10 transition-all duration-500 ease-in-out"
|
|
122
|
+
aria-hidden
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
<div className="flex items-start justify-between space-x-2 relative z-20">
|
|
126
|
+
{steps.map((step, idx) => {
|
|
127
|
+
const isActive = idx === currentStep;
|
|
128
|
+
const isCompleted = idx < currentStep;
|
|
129
|
+
const hasIcon = step.icon && useIcons;
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<button
|
|
133
|
+
type="button"
|
|
134
|
+
key={idx}
|
|
135
|
+
onClick={() => jumpTo(idx)}
|
|
136
|
+
disabled={!allowClickToJump && idx !== currentStep}
|
|
137
|
+
aria-current={isActive ? "step" : undefined}
|
|
138
|
+
aria-label={`Paso ${idx + 1} ${step.label}`}
|
|
139
|
+
className="flex-1 group"
|
|
140
|
+
title={step.label}
|
|
141
|
+
>
|
|
142
|
+
<div className="flex flex-col items-center">
|
|
143
|
+
<div
|
|
144
|
+
className={clsx(
|
|
145
|
+
"flex items-center justify-center w-11 h-11 rounded-full border-2 transition-all duration-300 transform",
|
|
146
|
+
hasIcon && "p-2",
|
|
147
|
+
isCompleted && "bg-slate-400 border-slate-400 text-white scale-100 shadow",
|
|
148
|
+
isActive && "text-white scale-110 shadow-lg",
|
|
149
|
+
!isActive && !isCompleted && "bg-white border-gray-300 text-gray-400"
|
|
150
|
+
)}
|
|
151
|
+
style={isActive ? { backgroundColor: resolvedColor, borderColor: resolvedColor } : undefined}
|
|
152
|
+
>
|
|
153
|
+
{renderStepContent(idx, isCompleted, isActive)}
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<ITText
|
|
157
|
+
as="span"
|
|
158
|
+
className={clsx(
|
|
159
|
+
"mt-2 text-xs sm:text-sm font-medium transition-colors text-center",
|
|
160
|
+
isCompleted ? "text-slate-400" : !isActive && "text-gray-400"
|
|
161
|
+
)}
|
|
162
|
+
style={isActive ? { color: resolvedColor } : undefined}
|
|
163
|
+
>
|
|
164
|
+
{step.label}
|
|
165
|
+
</ITText>
|
|
166
|
+
</div>
|
|
167
|
+
</button>
|
|
168
|
+
);
|
|
169
|
+
})}
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
{/* --- CONTENIDO DEL STEP --- */}
|
|
174
|
+
<div
|
|
175
|
+
ref={contentRef}
|
|
176
|
+
tabIndex={-1}
|
|
177
|
+
role="region"
|
|
178
|
+
aria-labelledby={`step-${currentStep}`}
|
|
179
|
+
className={clsx(
|
|
180
|
+
stepClassName,
|
|
181
|
+
"bg-white border border-gray-100 rounded-2xl shadow-lg min-h-[280px] transition-transform duration-400 no-scrollbar p-6",
|
|
182
|
+
scrollableContent && "overflow-y-auto hide-scrollbar"
|
|
183
|
+
)}
|
|
184
|
+
style={
|
|
185
|
+
scrollableContent && maxContentHeight
|
|
186
|
+
? { maxHeight: maxContentHeight }
|
|
187
|
+
: undefined
|
|
188
|
+
}
|
|
189
|
+
>
|
|
190
|
+
{steps[currentStep].content}
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
{/* --- BOTONES DE CONTROL --- */}
|
|
194
|
+
<div className="flex justify-between items-center mt-6">
|
|
195
|
+
<ITButton
|
|
196
|
+
variant="outlined"
|
|
197
|
+
color="secondary"
|
|
198
|
+
disabled={currentStep === 0}
|
|
199
|
+
onClick={prevStep}
|
|
200
|
+
>
|
|
201
|
+
<div className="flex items-center gap-2">
|
|
202
|
+
<FaChevronLeft />
|
|
203
|
+
<ITText as="span">Atrás</ITText>
|
|
204
|
+
</div>
|
|
205
|
+
</ITButton>
|
|
206
|
+
|
|
207
|
+
<div className="flex items-center gap-3">
|
|
208
|
+
<ITText as="div" className="text-sm text-gray-500 mr-2 hidden sm:block">
|
|
209
|
+
Paso {currentStep + 1} de {steps.length}
|
|
210
|
+
</ITText>
|
|
211
|
+
|
|
212
|
+
<ITButton
|
|
213
|
+
variant="solid"
|
|
214
|
+
color={color as any}
|
|
215
|
+
disabled={disableNext}
|
|
216
|
+
onClick={nextStep}
|
|
217
|
+
>
|
|
218
|
+
<div className="flex items-center gap-2">
|
|
219
|
+
<ITText as="span">{currentStep === steps.length - 1 ? "Finalizar" : "Siguiente"}</ITText>
|
|
220
|
+
{currentStep === steps.length - 1 ? <FaCheck /> : <FaChevronRight />}
|
|
221
|
+
</div>
|
|
222
|
+
</ITButton>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TableSize, TableVariants } from "@/types/table.types";
|
|
2
|
+
|
|
3
|
+
export type ColumnType = "string" | "date" | "number" | "boolean" | "actions" | "catalog";
|
|
4
|
+
|
|
5
|
+
export interface CatalogOption {
|
|
6
|
+
id: string | number;
|
|
7
|
+
name: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Column<T = any> {
|
|
11
|
+
key: string;
|
|
12
|
+
label: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
currencyMX?: boolean;
|
|
15
|
+
actions?: (row: T) => React.ReactNode;
|
|
16
|
+
filter?: boolean | "catalog";
|
|
17
|
+
type: ColumnType;
|
|
18
|
+
sortable?: boolean;
|
|
19
|
+
render?: (row: T) => React.ReactNode;
|
|
20
|
+
editComponent?: (props: {
|
|
21
|
+
value: any;
|
|
22
|
+
onChange: (value: any) => void;
|
|
23
|
+
rowData: T;
|
|
24
|
+
}) => React.ReactNode;
|
|
25
|
+
// Nuevas propiedades para catálogo
|
|
26
|
+
catalogOptions?: {
|
|
27
|
+
data: CatalogOption[];
|
|
28
|
+
loading?: boolean;
|
|
29
|
+
error?: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ITTableProps<T> {
|
|
34
|
+
columns: Column<T>[];
|
|
35
|
+
containerClassName?: string;
|
|
36
|
+
data: T[];
|
|
37
|
+
variant?: TableVariants;
|
|
38
|
+
className?: string;
|
|
39
|
+
size?: TableSize;
|
|
40
|
+
itemsPerPageOptions?: Array<number>;
|
|
41
|
+
defaultItemsPerPage?: number;
|
|
42
|
+
title?: string;
|
|
43
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import ITTable from "./table";
|
|
3
|
+
import { Column } from "./table.props";
|
|
4
|
+
import ITBadget from "../badget/badget";
|
|
5
|
+
import ITButton from "../button/button";
|
|
6
|
+
import { FaEdit, FaTrash } from "react-icons/fa";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof ITTable> = {
|
|
10
|
+
title: "Components/Data Display/ITTable",
|
|
11
|
+
component: ITTable,
|
|
12
|
+
parameters: {
|
|
13
|
+
layout: "padded", // Tables need more space
|
|
14
|
+
},
|
|
15
|
+
tags: ["autodocs"],
|
|
16
|
+
argTypes: {
|
|
17
|
+
variant: {
|
|
18
|
+
control: "select",
|
|
19
|
+
options: ["default", "striped", "bordered"],
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
control: "select",
|
|
23
|
+
options: ["sm", "md", "lg"],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
type Story = StoryObj<typeof ITTable>;
|
|
30
|
+
|
|
31
|
+
// --- MOCK DATA & COLUMNS ---
|
|
32
|
+
|
|
33
|
+
interface User {
|
|
34
|
+
id: number;
|
|
35
|
+
name: string;
|
|
36
|
+
email: string;
|
|
37
|
+
roleId: number;
|
|
38
|
+
balance: number;
|
|
39
|
+
isActive: boolean;
|
|
40
|
+
lastLogin: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const mockRoles = [
|
|
44
|
+
{ id: 1, name: "Administrator" },
|
|
45
|
+
{ id: 2, name: "Editor" },
|
|
46
|
+
{ id: 3, name: "Viewer" },
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const generateMockData = (count: number): User[] => {
|
|
50
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
51
|
+
id: i + 1,
|
|
52
|
+
name: `User ${i + 1}`,
|
|
53
|
+
email: `user${i + 1}@example.com`,
|
|
54
|
+
roleId: (i % 3) + 1,
|
|
55
|
+
balance: Math.random() * 10000,
|
|
56
|
+
isActive: i % 4 !== 0,
|
|
57
|
+
lastLogin: new Date(Date.now() - Math.random() * 10000000000).toISOString(),
|
|
58
|
+
}));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const mockData = generateMockData(25);
|
|
62
|
+
|
|
63
|
+
const basicColumns: Column<User>[] = [
|
|
64
|
+
{ key: "id", label: "ID", type: "number" },
|
|
65
|
+
{ key: "name", label: "Name", type: "string" },
|
|
66
|
+
{ key: "email", label: "Email", type: "string" },
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const advancedColumns: Column<User>[] = [
|
|
70
|
+
{ key: "id", label: "ID", type: "number", sortable: true, filter: true },
|
|
71
|
+
{ key: "name", label: "Name", type: "string", sortable: true, filter: true },
|
|
72
|
+
{ key: "email", label: "Email", type: "string", sortable: true, filter: true },
|
|
73
|
+
{
|
|
74
|
+
key: "roleId",
|
|
75
|
+
label: "Role",
|
|
76
|
+
type: "catalog",
|
|
77
|
+
sortable: true,
|
|
78
|
+
filter: "catalog",
|
|
79
|
+
catalogOptions: { data: mockRoles }
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: "balance",
|
|
83
|
+
label: "Balance",
|
|
84
|
+
type: "number",
|
|
85
|
+
sortable: true,
|
|
86
|
+
currencyMX: true
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
key: "isActive",
|
|
90
|
+
label: "Status",
|
|
91
|
+
type: "boolean",
|
|
92
|
+
sortable: true,
|
|
93
|
+
filter: true,
|
|
94
|
+
render: (row) => (
|
|
95
|
+
<ITBadget
|
|
96
|
+
label={row.isActive ? "Active" : "Inactive"}
|
|
97
|
+
color={row.isActive ? "success" : "danger"}
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const actionsColumn: Column<User> = {
|
|
104
|
+
key: "actions",
|
|
105
|
+
label: "Actions",
|
|
106
|
+
type: "actions",
|
|
107
|
+
actions: (row) => (
|
|
108
|
+
<>
|
|
109
|
+
<ITButton size="small" variant="text" color="info" ariaLabel="Edit" onClick={() => alert(`Edit ${row.name}`)}>
|
|
110
|
+
<FaEdit />
|
|
111
|
+
</ITButton>
|
|
112
|
+
<ITButton size="small" variant="text" color="danger" ariaLabel="Delete" onClick={() => alert(`Delete ${row.name}`)}>
|
|
113
|
+
<FaTrash />
|
|
114
|
+
</ITButton>
|
|
115
|
+
</>
|
|
116
|
+
),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// --- STORIES ---
|
|
121
|
+
|
|
122
|
+
export const Default: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
columns: basicColumns,
|
|
125
|
+
data: mockData.slice(0, 5), // Just a few
|
|
126
|
+
title: "Basic Users Table",
|
|
127
|
+
} as any,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const WithPagination: Story = {
|
|
131
|
+
args: {
|
|
132
|
+
columns: basicColumns,
|
|
133
|
+
data: mockData,
|
|
134
|
+
title: "Paginated Table",
|
|
135
|
+
defaultItemsPerPage: 5,
|
|
136
|
+
itemsPerPageOptions: [5, 10, 20],
|
|
137
|
+
} as any,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const WithSortingAndFiltering: Story = {
|
|
141
|
+
args: {
|
|
142
|
+
columns: advancedColumns.map(col => ({ ...col, render: undefined })), // Remove custom render to show raw formatting
|
|
143
|
+
data: mockData,
|
|
144
|
+
title: "Data Management (Sort & Filter)",
|
|
145
|
+
} as any,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const CustomRendering: Story = {
|
|
149
|
+
args: {
|
|
150
|
+
columns: advancedColumns,
|
|
151
|
+
data: mockData,
|
|
152
|
+
title: "Custom Rendering (Badges & Catalogs)",
|
|
153
|
+
} as any,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Wrapper for interactive actions
|
|
157
|
+
const ActionsTableWrapper = (args: any) => {
|
|
158
|
+
const [data, setData] = useState(mockData.slice(0, 5));
|
|
159
|
+
|
|
160
|
+
const actions: Column<User> = {
|
|
161
|
+
key: "actions",
|
|
162
|
+
label: "Actions",
|
|
163
|
+
type: "actions",
|
|
164
|
+
actions: (row) => (
|
|
165
|
+
<>
|
|
166
|
+
<ITButton size="small" variant="text" color="danger" ariaLabel="Delete" onClick={() => setData(d => d.filter(item => item.id !== row.id))}>
|
|
167
|
+
<FaTrash />
|
|
168
|
+
</ITButton>
|
|
169
|
+
</>
|
|
170
|
+
),
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return <ITTable {...args} data={data} columns={[...basicColumns, actions]} />;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export const WithActions: Story = {
|
|
177
|
+
render: (args) => <ActionsTableWrapper {...args} />,
|
|
178
|
+
args: {
|
|
179
|
+
title: "Table with Actions",
|
|
180
|
+
} as any,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export const EmptyState: Story = {
|
|
184
|
+
args: {
|
|
185
|
+
columns: basicColumns,
|
|
186
|
+
data: [],
|
|
187
|
+
title: "No Data Available",
|
|
188
|
+
} as any,
|
|
189
|
+
};
|