@axzydev/axzy_ui_system 1.2.4 → 1.2.7

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.
@@ -68,7 +68,7 @@ export default function ITTable<T extends Record<string, unknown>>({
68
68
  comparison =
69
69
  new Date(aValue as string).getTime() -
70
70
  new Date(bValue as string).getTime();
71
- break;
71
+ break;
72
72
  case "boolean":
73
73
  comparison = aValue === bValue ? 0 : aValue ? 1 : -1;
74
74
  break;
@@ -142,48 +142,48 @@ export default function ITTable<T extends Record<string, unknown>>({
142
142
  currentValue === undefined
143
143
  ? true
144
144
  : currentValue === true
145
- ? false
146
- : undefined;
145
+ ? false
146
+ : undefined;
147
147
 
148
- const getToggleLabel = () => {
149
- if (currentValue === undefined) return "Mostrar todos";
150
- if (currentValue === true) return "Filtrar solo verdaderos";
151
- return "Filtrar solo falsos";
152
- };
148
+ const getToggleLabel = () => {
149
+ if (currentValue === undefined) return "Mostrar todos";
150
+ if (currentValue === true) return "Filtrar solo verdaderos";
151
+ return "Filtrar solo falsos";
152
+ };
153
153
 
154
- return (
155
- <button
156
- className="flex items-center justify-center cursor-pointer focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 rounded-full p-1 transition-all duration-200"
157
- onClick={() => handleFilterChange(col.key, nextValue)}
158
- aria-label={`${getToggleLabel()} para ${col.label}`}
159
- title={`${getToggleLabel()} para ${col.label}`}
160
- >
161
- <div className="relative w-10 h-5 bg-gray-300 rounded-full">
162
- <div
163
- className={clsx(
164
- "absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
165
- {
166
- "left-0.5 bg-gray-400": currentValue === undefined,
167
- "left-5 bg-slate-500": currentValue === true,
168
- "left-0.5 bg-gray-500": currentValue === false,
169
- }
170
- )}
171
- />
172
- </div>
173
- </button>
174
- );
154
+ return (
155
+ <button
156
+ className="flex items-center justify-center cursor-pointer focus:outline-none focus:ring-2 focus:ring-slate-400 focus:ring-offset-2 rounded-full p-1 transition-all duration-200"
157
+ onClick={() => handleFilterChange(col.key, nextValue)}
158
+ aria-label={`${getToggleLabel()} para ${col.label}`}
159
+ title={`${getToggleLabel()} para ${col.label}`}
160
+ >
161
+ <div className="relative w-10 h-5 bg-gray-300 rounded-full">
162
+ <div
163
+ className={clsx(
164
+ "absolute top-0.5 w-4 h-4 rounded-full transition-all duration-300 shadow-sm",
165
+ {
166
+ "left-0.5 bg-gray-400": currentValue === undefined,
167
+ "left-5 bg-slate-500": currentValue === true,
168
+ "left-0.5 bg-gray-500": currentValue === false,
169
+ }
170
+ )}
171
+ />
172
+ </div>
173
+ </button>
174
+ );
175
175
  }
176
176
 
177
- if (col.filter === "catalog" && col.catalogOptions) {
178
- if (col.catalogOptions.loading) {
179
- return (
180
- <FaSpinner
181
- className="animate-spin"
182
- aria-label="Cargando opciones"
183
- title="Cargando opciones"
184
- />
185
- );
186
- }
177
+ if (col.filter === "catalog" && col.catalogOptions) {
178
+ if (col.catalogOptions.loading) {
179
+ return (
180
+ <FaSpinner
181
+ className="animate-spin"
182
+ aria-label="Cargando opciones"
183
+ title="Cargando opciones"
184
+ />
185
+ );
186
+ }
187
187
 
188
188
  if (col.catalogOptions.error) {
189
189
  return <ITText as="span" className="text-red-500 text-xs">Error cargando</ITText>;
@@ -204,7 +204,7 @@ export default function ITTable<T extends Record<string, unknown>>({
204
204
  const value = e.target.value === "" ? undefined : e.target.value;
205
205
  handleFilterChange(col.key, value);
206
206
  }}
207
- onBlur={() => {}}
207
+ onBlur={() => { }}
208
208
  className="w-full text-xs"
209
209
  />
210
210
  );
@@ -217,7 +217,7 @@ export default function ITTable<T extends Record<string, unknown>>({
217
217
  placeholder="Buscar..."
218
218
  value={String(filters[col.key] || "")}
219
219
  onChange={(e) => handleFilterChange(col.key, e.target.value)}
220
- onBlur={() => {}}
220
+ onBlur={() => { }}
221
221
  />
222
222
  );
223
223
  };
@@ -230,22 +230,22 @@ export default function ITTable<T extends Record<string, unknown>>({
230
230
  }
231
231
 
232
232
  switch (col.type) {
233
- case "number":
234
- return (typeof value === "number") && col.currencyMX ?formatCurrencyMX(value) : value;
235
- case "boolean":
236
- return value ? (
237
- <FaCheck
238
- className="text-green-500"
239
- aria-label="Verdadero"
240
- title="Verdadero"
241
- />
242
- ) : (
243
- <FaTimes
244
- className="text-red-500"
245
- aria-label="Falso"
246
- title="Falso"
247
- />
248
- );
233
+ case "number":
234
+ return (typeof value === "number") && col.currencyMX ? formatCurrencyMX(value) : value;
235
+ case "boolean":
236
+ return value ? (
237
+ <FaCheck
238
+ className="text-green-500"
239
+ aria-label="Verdadero"
240
+ title="Verdadero"
241
+ />
242
+ ) : (
243
+ <FaTimes
244
+ className="text-red-500"
245
+ aria-label="Falso"
246
+ title="Falso"
247
+ />
248
+ );
249
249
  case "actions":
250
250
  return col.actions ? col.actions(row) : null;
251
251
  case "catalog":
@@ -261,116 +261,115 @@ export default function ITTable<T extends Record<string, unknown>>({
261
261
  }
262
262
  };
263
263
 
264
- return (
265
- <div className={clsx("space-y-4 w-full", containerClassName)}>
266
- <div className="rounded-xl shadow-sm border border-secondary-200 overflow-hidden" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
267
- {/* Header outside overflow */}
268
- {title && (
269
- <div className="px-6 py-5 border-b border-secondary-100" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
270
- <ITText as="h2" className="text-xl font-bold text-secondary-900 leading-tight">{title}</ITText>
271
- </div>
272
- )}
273
-
274
- {/* Scrollable Table */}
275
- <div className="overflow-x-auto">
276
- <table
277
- className={clsx(
278
- "min-w-max w-full text-sm text-left text-secondary-600",
279
- variantStyles[variant],
280
- sizeStyles[size]
264
+ return (
265
+ <div className={clsx("space-y-4 w-full", containerClassName)}>
266
+ <div className="rounded-xl shadow-sm overflow-hidden" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
267
+ {/* Header outside overflow */}
268
+ {title && (
269
+ <div className="px-6 py-5 border-b border-secondary-100" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
270
+ <ITText as="h2" className="text-xl font-bold text-secondary-900 leading-tight">{title}</ITText>
271
+ </div>
281
272
  )}
282
- >
283
273
 
284
- <thead>
285
- <tr className="bg-secondary-50 border-b border-secondary-200 text-xs uppercase tracking-wider font-semibold text-secondary-500">
286
- {columns.map((col) => (
287
- <th
288
- key={col.key}
289
- scope="col"
290
- className={clsx("px-4 py-4 align-top", col.className)}
291
- >
292
- <div className="flex flex-col gap-3 min-w-[150px]">
293
- {/* Column header */}
294
- <div className="flex items-center justify-between gap-2">
274
+ {/* Scrollable Table */}
275
+ <div className="overflow-x-auto">
276
+ <table
277
+ className={clsx(
278
+ "min-w-max w-full text-sm text-left text-secondary-600",
279
+ variantStyles[variant],
280
+ sizeStyles[size]
281
+ )}
282
+ >
283
+
284
+ <thead>
285
+ <tr className="bg-secondary-50 border-b border-secondary-200 text-xs uppercase tracking-wider font-semibold text-secondary-500">
286
+ {columns.map((col) => (
287
+ <th
288
+ key={col.key}
289
+ scope="col"
290
+ className={clsx("px-4 py-4 align-top", col.className)}
291
+ >
292
+ <div className="flex flex-col gap-3 min-w-[150px]">
293
+ {/* Column header */}
294
+ <div className="flex items-center justify-between gap-2">
295
295
  <ITText as="span" className="text-secondary-700 font-bold">{col.label}</ITText>
296
- {col.sortable && col.type !== "actions" && (
297
- <button
298
- onClick={() => handleSort(col.key)}
299
- className={`p-1 rounded-md transition-colors ${
300
- sortConfig?.key === col.key
301
- ? "bg-secondary-200 text-secondary-900"
302
- : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"
303
- }`}
304
- title={`Ordenar por ${col.label}`}
305
- >
306
- <MdOutlineSwapVert className="w-4 h-4" aria-hidden="true" />
307
- </button>
308
- )}
309
- </div>
310
-
311
- {/* Filter section */}
312
- <div className="w-full">
313
- {col.filter ? renderFilterInput(col) : null}
314
- </div>
315
- </div>
316
- </th>
317
- ))}
318
- </tr>
319
- </thead>
320
- <tbody className="divide-y divide-secondary-100">
321
- {currentData.length > 0 ? (
322
- currentData.map((row, rowIndex) => (
323
- <tr
324
- key={rowIndex}
325
- className="hover:bg-secondary-50/50 transition-colors duration-150 group"
326
- >
327
- {columns.map((col) => (
328
- <td
329
- key={`${rowIndex}-${col.key}`}
330
- className={clsx("px-4 py-3 align-middle", col.className)}
331
- >
332
- {col.type === "actions" ? (
333
- <div className="flex items-center justify-center gap-2">
334
- {renderCellContent(col, row) as React.ReactNode}
335
- </div>
336
- ) : (
337
- <div className="text-secondary-700 font-medium">
296
+ {col.sortable && col.type !== "actions" && (
297
+ <button
298
+ onClick={() => handleSort(col.key)}
299
+ className={`p-1 rounded-md transition-colors ${sortConfig?.key === col.key
300
+ ? "bg-secondary-200 text-secondary-900"
301
+ : "hover:bg-secondary-200 text-secondary-400 hover:text-secondary-700"
302
+ }`}
303
+ title={`Ordenar por ${col.label}`}
304
+ >
305
+ <MdOutlineSwapVert className="w-4 h-4" aria-hidden="true" />
306
+ </button>
307
+ )}
308
+ </div>
309
+
310
+ {/* Filter section */}
311
+ <div className="w-full">
312
+ {col.filter ? renderFilterInput(col) : null}
313
+ </div>
314
+ </div>
315
+ </th>
316
+ ))}
317
+ </tr>
318
+ </thead>
319
+ <tbody className="divide-y divide-secondary-100">
320
+ {currentData.length > 0 ? (
321
+ currentData.map((row, rowIndex) => (
322
+ <tr
323
+ key={rowIndex}
324
+ className="hover:bg-secondary-50/50 transition-colors duration-150 group"
325
+ >
326
+ {columns.map((col) => (
327
+ <td
328
+ key={`${rowIndex}-${col.key}`}
329
+ className={clsx("px-4 py-3 align-middle", col.className)}
330
+ >
331
+ {col.type === "actions" ? (
332
+ <div className="flex items-center justify-center gap-2">
338
333
  {renderCellContent(col, row) as React.ReactNode}
339
- </div>
340
- )}
341
- </td>
342
- ))}
334
+ </div>
335
+ ) : (
336
+ <div className="text-secondary-700 font-medium">
337
+ {renderCellContent(col, row) as React.ReactNode}
338
+ </div>
339
+ )}
340
+ </td>
341
+ ))}
342
+ </tr>
343
+ ))
344
+ ) : (
345
+ <tr>
346
+ <td colSpan={columns.length} className="px-6 py-12 text-center">
347
+ <div className="flex flex-col items-center justify-center text-secondary-400">
348
+ <ITText as="span" className="text-lg">No se encontraron resultados</ITText>
349
+ <ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
350
+ </div>
351
+ </td>
343
352
  </tr>
344
- ))
345
- ) : (
346
- <tr>
347
- <td colSpan={columns.length} className="px-6 py-12 text-center">
348
- <div className="flex flex-col items-center justify-center text-secondary-400">
349
- <ITText as="span" className="text-lg">No se encontraron resultados</ITText>
350
- <ITText as="span" className="text-sm mt-1">Intenta ajustar los filtros</ITText>
351
- </div>
352
- </td>
353
- </tr>
354
- )}
355
- </tbody>
356
- </table>
357
- </div>
353
+ )}
354
+ </tbody>
355
+ </table>
356
+ </div>
358
357
 
359
358
 
360
- {/* Pagination */}
361
- <div className="rounded-b-xl border-t border-secondary-200 px-6 py-4" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
362
- <ITPagination
363
- currentPage={currentPage}
364
- totalPages={computedTotalPages}
365
- onPageChange={goToPage}
366
- color="primary"
367
- itemsPerPageOptions={itemsPerPageOptions}
368
- itemsPerPage={itemsPerPage}
369
- onItemsPerPageChange={handleItemsPerPageChange}
370
- totalItems={filteredData.length}
371
- />
359
+ {/* Pagination */}
360
+ <div className="rounded-b-xl border-t border-secondary-200 px-6 py-4" style={{ backgroundColor: 'var(--color-table-rowBg, #ffffff)' }}>
361
+ <ITPagination
362
+ currentPage={currentPage}
363
+ totalPages={computedTotalPages}
364
+ onPageChange={goToPage}
365
+ color="primary"
366
+ itemsPerPageOptions={itemsPerPageOptions}
367
+ itemsPerPage={itemsPerPage}
368
+ onItemsPerPageChange={handleItemsPerPageChange}
369
+ totalItems={filteredData.length}
370
+ />
371
+ </div>
372
372
  </div>
373
373
  </div>
374
- </div>
375
374
  );
376
375
  }
package/src/index.css CHANGED
@@ -1,3 +1,8 @@
1
+ @import "tailwindcss";
2
+
3
+ @source "./**/*.{ts,tsx}";
4
+ @source "../.storybook/**/*.{ts,tsx}";
5
+
1
6
  @variant dark (&:is(.dark &));
2
7
 
3
8
  :root, :host {
@@ -94,6 +99,21 @@
94
99
  to { opacity: 1; transform: translateY(0); }
95
100
  }
96
101
 
102
+ .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
103
+ .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
104
+ .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
105
+ .grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
106
+ .grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
107
+ .grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
108
+ .grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
109
+ .grid-cols-8 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
110
+ .grid-cols-9 { grid-template-columns: repeat(9, minmax(0, 1fr)); }
111
+ .grid-cols-10 { grid-template-columns: repeat(10, minmax(0, 1fr)); }
112
+ .grid-cols-11 { grid-template-columns: repeat(11, minmax(0, 1fr)); }
113
+ .grid-cols-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
114
+
115
+ .col-span-full { grid-column: 1 / -1; }
116
+
97
117
  .col-span-1 { grid-column: span 1 / span 1; }
98
118
  .col-span-2 { grid-column: span 2 / span 2; }
99
119
  .col-span-3 { grid-column: span 3 / span 3; }
@@ -49,7 +49,7 @@ export const TableShowcase = () => {
49
49
  description="Base de renderizado de tablas estructuradas con soporte de alineamiento y tipado estricto."
50
50
  code={code}
51
51
  demo={
52
- <div className="w-full bg-white dark:bg-slate-900 border rounded-xl overflow-hidden shadow-sm">
52
+ <div className="w-full bg-white dark:bg-slate-900 rounded-xl overflow-hidden shadow-sm">
53
53
  <ITTable
54
54
  columns={columns}
55
55
  data={data}