@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.
Files changed (202) hide show
  1. package/dist/index.css +82 -1
  2. package/dist/index.css.map +1 -1
  3. package/package.json +2 -2
  4. package/src/App.tsx +354 -0
  5. package/src/assets/logo.png +0 -0
  6. package/src/assets/react.svg +1 -0
  7. package/src/components/alert/alert.props.ts +13 -0
  8. package/src/components/alert/alert.stories.tsx +41 -0
  9. package/src/components/alert/alert.tsx +53 -0
  10. package/src/components/avatar/avatar.props.ts +14 -0
  11. package/src/components/avatar/avatar.stories.tsx +46 -0
  12. package/src/components/avatar/avatar.tsx +53 -0
  13. package/src/components/badget/badget.props.ts +12 -0
  14. package/src/components/badget/badget.stories.tsx +76 -0
  15. package/src/components/badget/badget.tsx +61 -0
  16. package/src/components/breadcrumbs/breadcrumbs.props.ts +13 -0
  17. package/src/components/breadcrumbs/breadcrumbs.stories.tsx +21 -0
  18. package/src/components/breadcrumbs/breadcrumbs.tsx +34 -0
  19. package/src/components/button/button.props.ts +18 -0
  20. package/src/components/button/button.stories.tsx +174 -0
  21. package/src/components/button/button.tsx +117 -0
  22. package/src/components/calendar/calendar.props.ts +33 -0
  23. package/src/components/calendar/calendar.stories.tsx +91 -0
  24. package/src/components/calendar/calendar.tsx +608 -0
  25. package/src/components/calendar/index.ts +3 -0
  26. package/src/components/card/card.props.ts +13 -0
  27. package/src/components/card/card.stories.tsx +58 -0
  28. package/src/components/card/card.tsx +79 -0
  29. package/src/components/checkbox/checkbox.props.ts +11 -0
  30. package/src/components/checkbox/checkbox.stories.tsx +54 -0
  31. package/src/components/checkbox/checkbox.tsx +52 -0
  32. package/src/components/confirm-dialog/confirm-dialog.props.ts +14 -0
  33. package/src/components/confirm-dialog/confirm-dialog.stories.tsx +33 -0
  34. package/src/components/confirm-dialog/confirm-dialog.tsx +45 -0
  35. package/src/components/data-table/ITDataTable.stories.tsx +213 -0
  36. package/src/components/data-table/dataTable.props.ts +69 -0
  37. package/src/components/data-table/dataTable.tsx +313 -0
  38. package/src/components/date-picker/date-picker.props.ts +30 -0
  39. package/src/components/date-picker/date-picker.stories.tsx +90 -0
  40. package/src/components/date-picker/datePicker.tsx +307 -0
  41. package/src/components/dialog/dialog.props.ts +9 -0
  42. package/src/components/dialog/dialog.stories.tsx +80 -0
  43. package/src/components/dialog/dialog.tsx +88 -0
  44. package/src/components/divider/divider.props.ts +8 -0
  45. package/src/components/divider/divider.stories.tsx +34 -0
  46. package/src/components/divider/divider.tsx +21 -0
  47. package/src/components/drawer/drawer.props.ts +14 -0
  48. package/src/components/drawer/drawer.stories.tsx +41 -0
  49. package/src/components/drawer/drawer.tsx +53 -0
  50. package/src/components/dropfile/dropfile.stories.tsx +75 -0
  51. package/src/components/dropfile/dropfile.tsx +407 -0
  52. package/src/components/empty-state/empty-state.props.ts +9 -0
  53. package/src/components/empty-state/empty-state.stories.tsx +20 -0
  54. package/src/components/empty-state/empty-state.tsx +21 -0
  55. package/src/components/flex/flex.props.ts +22 -0
  56. package/src/components/flex/flex.stories.tsx +71 -0
  57. package/src/components/flex/flex.tsx +79 -0
  58. package/src/components/form-builder/fieldRenderer.tsx +218 -0
  59. package/src/components/form-builder/formBuilder.context.tsx +70 -0
  60. package/src/components/form-builder/formBuilder.props.ts +43 -0
  61. package/src/components/form-builder/formBuilder.stories.tsx +317 -0
  62. package/src/components/form-builder/formBuilder.tsx +186 -0
  63. package/src/components/form-builder/useFormBuilder.ts +80 -0
  64. package/src/components/form-header/form-header.props.ts +5 -0
  65. package/src/components/form-header/form-header.tsx +38 -0
  66. package/src/components/grid/grid.props.ts +17 -0
  67. package/src/components/grid/grid.stories.tsx +72 -0
  68. package/src/components/grid/grid.tsx +69 -0
  69. package/src/components/image/image.props.ts +7 -0
  70. package/src/components/image/image.tsx +38 -0
  71. package/src/components/input/input.props.ts +49 -0
  72. package/src/components/input/input.stories.tsx +115 -0
  73. package/src/components/input/input.tsx +615 -0
  74. package/src/components/layout/layout.props.ts +10 -0
  75. package/src/components/layout/layout.stories.tsx +114 -0
  76. package/src/components/layout/layout.tsx +80 -0
  77. package/src/components/loader/loader.props.ts +8 -0
  78. package/src/components/loader/loader.stories.tsx +105 -0
  79. package/src/components/loader/loader.tsx +108 -0
  80. package/src/components/navbar/navbar.props.ts +37 -0
  81. package/src/components/navbar/navbar.tsx +328 -0
  82. package/src/components/page/page.props.ts +19 -0
  83. package/src/components/page/page.stories.tsx +98 -0
  84. package/src/components/page/page.tsx +90 -0
  85. package/src/components/page-header/page-header.props.ts +11 -0
  86. package/src/components/page-header/page-header.stories.tsx +61 -0
  87. package/src/components/page-header/page-header.tsx +62 -0
  88. package/src/components/pagination/pagination.props.ts +53 -0
  89. package/src/components/pagination/pagination.stories.tsx +111 -0
  90. package/src/components/pagination/pagination.tsx +241 -0
  91. package/src/components/popover/popover.props.ts +12 -0
  92. package/src/components/popover/popover.stories.tsx +25 -0
  93. package/src/components/popover/popover.tsx +45 -0
  94. package/src/components/progress/progress.props.ts +12 -0
  95. package/src/components/progress/progress.stories.tsx +40 -0
  96. package/src/components/progress/progress.tsx +52 -0
  97. package/src/components/radio/radio.props.ts +16 -0
  98. package/src/components/radio/radio.stories.tsx +50 -0
  99. package/src/components/radio/radio.tsx +58 -0
  100. package/src/components/search-select/index.ts +2 -0
  101. package/src/components/search-select/search-select.props.ts +46 -0
  102. package/src/components/search-select/search-select.stories.tsx +129 -0
  103. package/src/components/search-select/search-select.tsx +229 -0
  104. package/src/components/searchTable/components/EditableCell.tsx +149 -0
  105. package/src/components/searchTable/components/PaginationControls.tsx +86 -0
  106. package/src/components/searchTable/components/PaginationInfo.tsx +20 -0
  107. package/src/components/searchTable/components/SearchAndSortBar.tsx +53 -0
  108. package/src/components/searchTable/components/SearchInput.tsx +33 -0
  109. package/src/components/searchTable/components/SortButton.tsx +50 -0
  110. package/src/components/searchTable/components/TableEmptyState.tsx +22 -0
  111. package/src/components/searchTable/components/TableHeader.tsx +35 -0
  112. package/src/components/searchTable/components/TableHeaderCell.tsx +43 -0
  113. package/src/components/searchTable/components/TableRow.tsx +144 -0
  114. package/src/components/searchTable/searchTable.props.ts +56 -0
  115. package/src/components/searchTable/searchTable.tsx +187 -0
  116. package/src/components/segmented-control/segmented-control.props.ts +18 -0
  117. package/src/components/segmented-control/segmented-control.stories.tsx +63 -0
  118. package/src/components/segmented-control/segmented-control.tsx +52 -0
  119. package/src/components/select/select.props.ts +25 -0
  120. package/src/components/select/select.stories.tsx +86 -0
  121. package/src/components/select/select.tsx +150 -0
  122. package/src/components/sidebar/sidebar.props.ts +28 -0
  123. package/src/components/sidebar/sidebar.stories.tsx +117 -0
  124. package/src/components/sidebar/sidebar.tsx +313 -0
  125. package/src/components/skeleton/skeleton.props.ts +12 -0
  126. package/src/components/skeleton/skeleton.stories.tsx +30 -0
  127. package/src/components/skeleton/skeleton.tsx +45 -0
  128. package/src/components/slide/slide.props.ts +45 -0
  129. package/src/components/slide/slide.stories.tsx +121 -0
  130. package/src/components/slide/slide.tsx +109 -0
  131. package/src/components/slider/slider.props.ts +10 -0
  132. package/src/components/slider/slider.stories.tsx +30 -0
  133. package/src/components/slider/slider.tsx +49 -0
  134. package/src/components/stack/stack.props.ts +19 -0
  135. package/src/components/stack/stack.stories.tsx +79 -0
  136. package/src/components/stack/stack.tsx +79 -0
  137. package/src/components/stat-card/stat-card.props.ts +13 -0
  138. package/src/components/stat-card/stat-card.stories.tsx +41 -0
  139. package/src/components/stat-card/stat-card.tsx +44 -0
  140. package/src/components/stepper/stepper.css +26 -0
  141. package/src/components/stepper/stepper.props.ts +29 -0
  142. package/src/components/stepper/stepper.stories.tsx +155 -0
  143. package/src/components/stepper/stepper.tsx +227 -0
  144. package/src/components/table/table.props.ts +43 -0
  145. package/src/components/table/table.stories.tsx +189 -0
  146. package/src/components/table/table.tsx +376 -0
  147. package/src/components/tabs/tabs.props.ts +18 -0
  148. package/src/components/tabs/tabs.stories.tsx +32 -0
  149. package/src/components/tabs/tabs.tsx +74 -0
  150. package/src/components/text/text.props.ts +9 -0
  151. package/src/components/text/text.tsx +20 -0
  152. package/src/components/textarea/textarea.props.ts +15 -0
  153. package/src/components/textarea/textarea.stories.tsx +27 -0
  154. package/src/components/textarea/textarea.tsx +55 -0
  155. package/src/components/theme-provider/themeProvider.props.ts +28 -0
  156. package/src/components/theme-provider/themeProvider.tsx +1854 -0
  157. package/src/components/time-picker/timePicker.props.ts +16 -0
  158. package/src/components/time-picker/timePicker.stories.tsx +131 -0
  159. package/src/components/time-picker/timePicker.tsx +317 -0
  160. package/src/components/toast/toast.css +32 -0
  161. package/src/components/toast/toast.props.ts +13 -0
  162. package/src/components/toast/toast.stories.tsx +138 -0
  163. package/src/components/toast/toast.tsx +87 -0
  164. package/src/components/tooltip/tooltip.props.ts +11 -0
  165. package/src/components/tooltip/tooltip.stories.tsx +20 -0
  166. package/src/components/tooltip/tooltip.tsx +55 -0
  167. package/src/components/topbar/topbar.props.ts +21 -0
  168. package/src/components/topbar/topbar.stories.tsx +80 -0
  169. package/src/components/topbar/topbar.tsx +205 -0
  170. package/src/components/triple-filter/tripleFilter.props.ts +15 -0
  171. package/src/components/triple-filter/tripleFilter.stories.tsx +32 -0
  172. package/src/components/triple-filter/tripleFilter.tsx +50 -0
  173. package/src/hooks/useClickOutside.ts +21 -0
  174. package/src/hooks/useDebouncedSearch.ts +55 -0
  175. package/src/hooks/useEditableRow.ts +157 -0
  176. package/src/hooks/useTableState.ts +122 -0
  177. package/src/index.css +168 -0
  178. package/src/index.ts +165 -0
  179. package/src/main.tsx +9 -0
  180. package/src/showcases/DataShowcases.tsx +260 -0
  181. package/src/showcases/FeedbackShowcases.tsx +268 -0
  182. package/src/showcases/FormShowcases.tsx +1159 -0
  183. package/src/showcases/HomeShowcase.tsx +324 -0
  184. package/src/showcases/LayoutPrimitivesShowcases.tsx +569 -0
  185. package/src/showcases/NavigationShowcases.tsx +193 -0
  186. package/src/showcases/PageShowcases.tsx +207 -0
  187. package/src/showcases/ShowcaseLayout.tsx +139 -0
  188. package/src/showcases/StructureShowcases.tsx +152 -0
  189. package/src/types/badget.types.ts +37 -0
  190. package/src/types/button.types.ts +16 -0
  191. package/src/types/colors.types.ts +3 -0
  192. package/src/types/field.types.ts +103 -0
  193. package/src/types/formik.types.ts +15 -0
  194. package/src/types/input.types.ts +14 -0
  195. package/src/types/loader.types.ts +9 -0
  196. package/src/types/sizes.types.ts +1 -0
  197. package/src/types/table.types.ts +15 -0
  198. package/src/types/toast.types.ts +8 -0
  199. package/src/types/yup.types.ts +11 -0
  200. package/src/utils/color.utils.ts +99 -0
  201. package/src/utils/styles.ts +120 -0
  202. 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
+ };