better-table 1.0.0

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 (41) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +5 -0
  3. package/dist/better-table.cjs.js +2 -0
  4. package/dist/better-table.cjs.js.map +1 -0
  5. package/dist/better-table.css +1 -0
  6. package/dist/better-table.es.js +1182 -0
  7. package/dist/better-table.es.js.map +1 -0
  8. package/dist/components/BetterTable/components/Table.d.ts +4 -0
  9. package/dist/components/BetterTable/components/TableActions.d.ts +8 -0
  10. package/dist/components/BetterTable/components/TableBody.d.ts +4 -0
  11. package/dist/components/BetterTable/components/TableCell.d.ts +9 -0
  12. package/dist/components/BetterTable/components/TableEmpty.d.ts +1 -0
  13. package/dist/components/BetterTable/components/TableHeader.d.ts +4 -0
  14. package/dist/components/BetterTable/components/TableHeaderCell.d.ts +7 -0
  15. package/dist/components/BetterTable/components/TableLoading.d.ts +6 -0
  16. package/dist/components/BetterTable/components/TableModal.d.ts +1 -0
  17. package/dist/components/BetterTable/components/TablePagination.d.ts +1 -0
  18. package/dist/components/BetterTable/components/TableRow.d.ts +8 -0
  19. package/dist/components/BetterTable/components/TableToolbar.d.ts +4 -0
  20. package/dist/components/BetterTable/components/index.d.ts +12 -0
  21. package/dist/components/BetterTable/context/TableContext.d.ts +68 -0
  22. package/dist/components/BetterTable/context/index.d.ts +2 -0
  23. package/dist/components/BetterTable/hooks/index.d.ts +5 -0
  24. package/dist/components/BetterTable/hooks/useTableFilter.d.ts +17 -0
  25. package/dist/components/BetterTable/hooks/useTablePagination.d.ts +23 -0
  26. package/dist/components/BetterTable/hooks/useTableSearch.d.ts +18 -0
  27. package/dist/components/BetterTable/hooks/useTableSelection.d.ts +23 -0
  28. package/dist/components/BetterTable/hooks/useTableSort.d.ts +15 -0
  29. package/dist/components/BetterTable/index.d.ts +13 -0
  30. package/dist/components/BetterTable/types.d.ts +236 -0
  31. package/dist/components/BetterTable/utils/filterData.d.ts +18 -0
  32. package/dist/components/BetterTable/utils/getValueFromPath.d.ts +7 -0
  33. package/dist/components/BetterTable/utils/index.d.ts +3 -0
  34. package/dist/components/BetterTable/utils/sortData.d.ts +9 -0
  35. package/dist/index.d.ts +19 -0
  36. package/dist/styles.cjs +2 -0
  37. package/dist/styles.cjs.map +1 -0
  38. package/dist/styles.d.ts +0 -0
  39. package/dist/styles.js +2 -0
  40. package/dist/styles.js.map +1 -0
  41. package/package.json +99 -0
@@ -0,0 +1,236 @@
1
+ import { ReactNode, CSSProperties } from 'react';
2
+ /**
3
+ * Tipo base para los datos de la tabla
4
+ * Permite extensión con tipos específicos del usuario
5
+ */
6
+ export type TableData = Record<string, unknown>;
7
+ /**
8
+ * Configuración de columna con tipado genérico
9
+ */
10
+ export interface Column<T extends TableData = TableData> {
11
+ /** Identificador único de la columna */
12
+ id: string;
13
+ /** Key para acceder al dato (soporta dot notation: 'user.profile.name') */
14
+ accessor: keyof T | string;
15
+ /** Texto visible en el header */
16
+ header: string;
17
+ /** Tipo de dato para filtrado y renderizado */
18
+ type?: "string" | "number" | "boolean" | "date" | "custom";
19
+ /** Render personalizado de celda */
20
+ cell?: (value: unknown, row: T, rowIndex: number) => ReactNode;
21
+ /** Render personalizado de header */
22
+ headerCell?: (column: Column<T>) => ReactNode;
23
+ /** ¿Columna ordenable? */
24
+ sortable?: boolean;
25
+ /** ¿Columna filtrable? */
26
+ filterable?: boolean;
27
+ /** Ancho de columna */
28
+ width?: string | number;
29
+ /** Alineación del contenido */
30
+ align?: "left" | "center" | "right";
31
+ /** Columna oculta */
32
+ hidden?: boolean;
33
+ }
34
+ /**
35
+ * Acción de fila individual
36
+ */
37
+ export interface RowAction<T extends TableData = TableData> {
38
+ /** Identificador único */
39
+ id: string;
40
+ /** Etiqueta de la acción */
41
+ label: string;
42
+ /** Icono (string, emoji, o componente) */
43
+ icon?: ReactNode;
44
+ /** Modo de ejecución */
45
+ mode: "callback" | "modal" | "link";
46
+ /** Callback cuando mode='callback' */
47
+ onClick?: (row: T, rowIndex: number) => void;
48
+ /** Componente para modal cuando mode='modal' */
49
+ modalContent?: React.ComponentType<{
50
+ data: T;
51
+ onClose: () => void;
52
+ }>;
53
+ /** URL cuando mode='link' */
54
+ href?: string | ((row: T) => string);
55
+ /** ¿Mostrar acción condicionalmente? */
56
+ visible?: (row: T) => boolean;
57
+ /** ¿Deshabilitar acción condicionalmente? */
58
+ disabled?: (row: T) => boolean;
59
+ /** Variante visual */
60
+ variant?: "default" | "primary" | "danger" | "ghost";
61
+ }
62
+ /**
63
+ * Acción global (toolbar)
64
+ */
65
+ export interface GlobalAction<T extends TableData = TableData> {
66
+ /** Identificador único */
67
+ id: string;
68
+ /** Etiqueta del botón */
69
+ label: string;
70
+ /** Icono */
71
+ icon?: ReactNode;
72
+ /** Callback de ejecución */
73
+ onClick: (selectedRows: T[], allData: T[]) => void;
74
+ /** ¿Requiere selección de filas? */
75
+ requiresSelection?: boolean;
76
+ /** Variante visual */
77
+ variant?: "default" | "primary" | "danger";
78
+ }
79
+ /**
80
+ * Configuración de paginación
81
+ */
82
+ export interface PaginationConfig {
83
+ /** Página actual (controlado) */
84
+ page?: number;
85
+ /** Items por página */
86
+ pageSize?: number;
87
+ /** Opciones de tamaño de página */
88
+ pageSizeOptions?: number[];
89
+ /** Total de items (para paginación del servidor) */
90
+ totalItems?: number;
91
+ /** Mostrar selector de tamaño de página */
92
+ showSizeChanger?: boolean;
93
+ /** Mostrar salto a página */
94
+ showQuickJumper?: boolean;
95
+ }
96
+ /**
97
+ * Estado de ordenamiento
98
+ */
99
+ export interface SortState {
100
+ columnId: string | null;
101
+ direction: "asc" | "desc";
102
+ }
103
+ /**
104
+ * Estado de filtros
105
+ */
106
+ export interface FilterState {
107
+ [columnId: string]: string | number | boolean | null;
108
+ }
109
+ /**
110
+ * Personalización de estilos
111
+ */
112
+ export interface TableClassNames {
113
+ /** Clase CSS del contenedor */
114
+ container?: string;
115
+ /** Clase CSS de la tabla */
116
+ table?: string;
117
+ /** Clase CSS del header */
118
+ header?: string;
119
+ /** Clase CSS del body */
120
+ body?: string;
121
+ /** Clase CSS de filas */
122
+ row?: string;
123
+ /** Clase CSS de celdas */
124
+ cell?: string;
125
+ /** Clase CSS de la paginación */
126
+ pagination?: string;
127
+ /** Clase CSS del toolbar */
128
+ toolbar?: string;
129
+ }
130
+ /**
131
+ * Textos personalizables (i18n)
132
+ */
133
+ export interface TableLocale {
134
+ search?: string;
135
+ searchPlaceholder?: string;
136
+ noData?: string;
137
+ loading?: string;
138
+ page?: string;
139
+ of?: string;
140
+ items?: string;
141
+ selected?: string;
142
+ rowsPerPage?: string;
143
+ actions?: string;
144
+ sortAsc?: string;
145
+ sortDesc?: string;
146
+ filterBy?: string;
147
+ clearFilters?: string;
148
+ selectAll?: string;
149
+ deselectAll?: string;
150
+ }
151
+ /**
152
+ * Locale por defecto
153
+ */
154
+ export declare const defaultLocale: TableLocale;
155
+ /**
156
+ * Props principales del componente BetterTable
157
+ */
158
+ export interface BetterTableProps<T extends TableData = TableData> {
159
+ /** Array de datos a mostrar */
160
+ data: T[];
161
+ /** Configuración de columnas */
162
+ columns: Column<T>[];
163
+ /** Key único para identificar filas (default: 'id') */
164
+ rowKey?: keyof T | ((row: T, index: number) => string);
165
+ /** Acciones por fila */
166
+ rowActions?: RowAction<T>[];
167
+ /** Acciones globales (toolbar) */
168
+ globalActions?: GlobalAction<T>[];
169
+ /** Configuración de paginación (false para desactivar) */
170
+ pagination?: PaginationConfig | false;
171
+ /** Callback de cambio de página */
172
+ onPageChange?: (page: number, pageSize: number) => void;
173
+ /** Estado de ordenamiento (controlado) */
174
+ sort?: SortState;
175
+ /** Callback de cambio de ordenamiento */
176
+ onSortChange?: (sort: SortState) => void;
177
+ /** Estado de filtros (controlado) */
178
+ filters?: FilterState;
179
+ /** Callback de cambio de filtros */
180
+ onFilterChange?: (filters: FilterState) => void;
181
+ /** Mostrar barra de búsqueda */
182
+ searchable?: boolean;
183
+ /** Valor de búsqueda (controlado) */
184
+ searchValue?: string;
185
+ /** Callback de cambio de búsqueda */
186
+ onSearchChange?: (value: string) => void;
187
+ /** Columnas en las que buscar (default: todas) */
188
+ searchColumns?: string[];
189
+ /** Habilitar selección de filas */
190
+ selectable?: boolean;
191
+ /** Filas seleccionadas (controlado) */
192
+ selectedRows?: T[];
193
+ /** Callback de cambio de selección */
194
+ onSelectionChange?: (selectedRows: T[]) => void;
195
+ /** Modo de selección */
196
+ selectionMode?: "single" | "multiple";
197
+ /** Estado de carga */
198
+ loading?: boolean;
199
+ /** Componente de loading personalizado */
200
+ loadingComponent?: ReactNode;
201
+ /** Componente de estado vacío personalizado */
202
+ emptyComponent?: ReactNode;
203
+ /** Clases CSS personalizadas */
204
+ classNames?: TableClassNames;
205
+ /** Estilos inline personalizados */
206
+ styles?: {
207
+ container?: CSSProperties;
208
+ table?: CSSProperties;
209
+ header?: CSSProperties;
210
+ body?: CSSProperties;
211
+ row?: CSSProperties;
212
+ cell?: CSSProperties;
213
+ };
214
+ /** Textos personalizados */
215
+ locale?: TableLocale;
216
+ /** Header fijo al hacer scroll */
217
+ stickyHeader?: boolean;
218
+ /** Altura máxima (activa scroll interno) */
219
+ maxHeight?: string | number;
220
+ /** Mostrar bordes */
221
+ bordered?: boolean;
222
+ /** Filas con rayas alternas */
223
+ striped?: boolean;
224
+ /** Hover en filas */
225
+ hoverable?: boolean;
226
+ /** Tamaño de la tabla */
227
+ size?: "small" | "medium" | "large";
228
+ /** Callback al hacer click en una fila */
229
+ onRowClick?: (row: T, rowIndex: number) => void;
230
+ /** Callback al hacer doble click en una fila */
231
+ onRowDoubleClick?: (row: T, rowIndex: number) => void;
232
+ /** Descripción de la tabla para screen readers */
233
+ ariaLabel?: string;
234
+ /** ID del elemento que describe la tabla */
235
+ ariaDescribedBy?: string;
236
+ }
@@ -0,0 +1,18 @@
1
+ import { TableData, Column, FilterState } from '../types';
2
+ /**
3
+ * Filtra un array de datos basado en múltiples filtros de columna
4
+ * @param data - Array de datos a filtrar
5
+ * @param filters - Estado de filtros por columna
6
+ * @param columns - Configuración de columnas
7
+ * @returns Array filtrado (nueva referencia)
8
+ */
9
+ export declare function filterData<T extends TableData>(data: T[], filters: FilterState, columns: Column<T>[]): T[];
10
+ /**
11
+ * Realiza una búsqueda global en los datos
12
+ * @param data - Array de datos
13
+ * @param searchValue - Valor a buscar
14
+ * @param columns - Columnas en las que buscar
15
+ * @param searchColumnIds - IDs de columnas específicas (opcional)
16
+ * @returns Array filtrado
17
+ */
18
+ export declare function searchData<T extends TableData>(data: T[], searchValue: string, columns: Column<T>[], searchColumnIds?: string[]): T[];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Accede a propiedades anidadas de un objeto usando dot notation
3
+ * @param obj - Objeto del cual extraer el valor
4
+ * @param path - Ruta al valor (e.g., 'user.profile.name')
5
+ * @returns El valor encontrado o undefined
6
+ */
7
+ export declare function getValueFromPath<T = unknown>(obj: Record<string, unknown>, path: string): T | undefined;
@@ -0,0 +1,3 @@
1
+ export { getValueFromPath } from './getValueFromPath';
2
+ export { sortData } from './sortData';
3
+ export { filterData, searchData } from './filterData';
@@ -0,0 +1,9 @@
1
+ import { TableData } from '../types';
2
+ /**
3
+ * Ordena un array de datos por una columna específica
4
+ * @param data - Array de datos a ordenar
5
+ * @param columnId - ID/accessor de la columna
6
+ * @param direction - Dirección del ordenamiento
7
+ * @returns Array ordenado (nueva referencia)
8
+ */
9
+ export declare function sortData<T extends TableData>(data: T[], columnId: string, direction: "asc" | "desc"): T[];
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @juanb/better-table
3
+ * A modern, flexible, and fully typed React data table component
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ export { BetterTable } from './components/BetterTable';
8
+ export { defaultLocale } from './components/BetterTable/types';
9
+ export type { BetterTableProps, Column, RowAction, GlobalAction, PaginationConfig, SortState, FilterState, TableClassNames, TableLocale, TableData, } from './components/BetterTable/types';
10
+ export { useTableSort } from './components/BetterTable/hooks/useTableSort';
11
+ export { useTableFilter } from './components/BetterTable/hooks/useTableFilter';
12
+ export { useTablePagination } from './components/BetterTable/hooks/useTablePagination';
13
+ export { useTableSelection } from './components/BetterTable/hooks/useTableSelection';
14
+ export { useTableSearch } from './components/BetterTable/hooks/useTableSearch';
15
+ export { useTableContext, TableProvider, } from './components/BetterTable/context';
16
+ export type { TableContextValue } from './components/BetterTable/context';
17
+ export { getValueFromPath } from './components/BetterTable/utils/getValueFromPath';
18
+ export { sortData } from './components/BetterTable/utils/sortData';
19
+ export { filterData, searchData, } from './components/BetterTable/utils/filterData';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=styles.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
File without changes
package/dist/styles.js ADDED
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "better-table",
3
+ "version": "1.0.0",
4
+ "description": "A modern, flexible, and fully typed React data table component",
5
+ "author": "Juan Puca",
6
+ "license": "Apache-2.0",
7
+ "type": "module",
8
+ "main": "./dist/better-table.cjs.js",
9
+ "module": "./dist/better-table.es.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/better-table.es.js"
16
+ },
17
+ "require": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/better-table.cjs.js"
20
+ }
21
+ },
22
+ "./styles.css": "./dist/styles.css"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "sideEffects": [
30
+ "**/*.css"
31
+ ],
32
+ "keywords": [
33
+ "react",
34
+ "table",
35
+ "data-table",
36
+ "datagrid",
37
+ "typescript",
38
+ "sorting",
39
+ "filtering",
40
+ "pagination",
41
+ "selection"
42
+ ],
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/jrodrigopuca/BetterTable.git"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/jrodrigopuca/BetterTable/issues"
49
+ },
50
+ "homepage": "https://github.com/jrodrigopuca/BetterTable#readme",
51
+ "peerDependencies": {
52
+ "react": ">=18.0.0",
53
+ "react-dom": ">=18.0.0"
54
+ },
55
+ "dependencies": {
56
+ "clsx": "^2.1.1"
57
+ },
58
+ "devDependencies": {
59
+ "@testing-library/jest-dom": "^6.6.3",
60
+ "@testing-library/react": "^16.1.0",
61
+ "@testing-library/user-event": "^14.5.2",
62
+ "@types/node": "^22.10.5",
63
+ "@types/react": "^19.0.6",
64
+ "@types/react-dom": "^19.0.2",
65
+ "@vitejs/plugin-react": "^4.7.0",
66
+ "@vitest/coverage-v8": "^4.0.0",
67
+ "@vitest/ui": "^4.0.18",
68
+ "jsdom": "^27.0.1",
69
+ "react": "^19.2.4",
70
+ "react-dom": "^19.2.4",
71
+ "typescript": "^5.7.3",
72
+ "vite": "^6.0.5",
73
+ "vite-plugin-dts": "^4.5.0",
74
+ "vitest": "^4.0.18"
75
+ },
76
+ "scripts": {
77
+ "dev": "vite --config demo/vite.config.ts",
78
+ "build": "vite build",
79
+ "build:types": "tsc -p tsconfig.build.json",
80
+ "preview": "vite preview",
81
+ "test": "vitest --config vitest.config.ts",
82
+ "test:run": "vitest run --config vitest.config.ts",
83
+ "test:coverage": "vitest run --coverage --config vitest.config.ts",
84
+ "lint": "tsc --noEmit",
85
+ "prepublishOnly": "npm run build"
86
+ },
87
+ "browserslist": {
88
+ "production": [
89
+ ">0.2%",
90
+ "not dead",
91
+ "not op_mini all"
92
+ ],
93
+ "development": [
94
+ "last 1 chrome version",
95
+ "last 1 firefox version",
96
+ "last 1 safari version"
97
+ ]
98
+ }
99
+ }