all-purpose-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.
- package/README.md +288 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +580 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +577 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# All Purpose Table
|
|
2
|
+
|
|
3
|
+
A production-grade, plug-and-play React table component with TypeScript support. Zero configuration required. No styling dependencies.
|
|
4
|
+
|
|
5
|
+
## ✨ Features
|
|
6
|
+
|
|
7
|
+
- 🎯 **Plug and Play** - Just install and use, no configuration needed
|
|
8
|
+
- 📦 **Zero Dependencies** - No Tailwind, no CSS frameworks required
|
|
9
|
+
- 🔷 **TypeScript Native** - Full type safety and IntelliSense support
|
|
10
|
+
- 🎨 **Dark Mode** - Automatic dark mode support via CSS
|
|
11
|
+
- 📊 **Feature Rich**:
|
|
12
|
+
- Sorting (multi-column support)
|
|
13
|
+
- Pagination
|
|
14
|
+
- Column visibility toggle
|
|
15
|
+
- Column resizing
|
|
16
|
+
- Expandable rows
|
|
17
|
+
- Custom cell renderers
|
|
18
|
+
- Row click handlers
|
|
19
|
+
- Persistent column widths (localStorage)
|
|
20
|
+
- Mobile responsive with auto-sizing
|
|
21
|
+
- Virtual scrolling ready
|
|
22
|
+
|
|
23
|
+
## 📦 Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install all-purpose-table
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 🚀 Quick Start
|
|
30
|
+
|
|
31
|
+
### JavaScript
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
import { Table } from "all-purpose-table";
|
|
35
|
+
|
|
36
|
+
function App() {
|
|
37
|
+
const headers = [
|
|
38
|
+
{ accessor: "id", label: "ID", isSortable: true },
|
|
39
|
+
{ accessor: "name", label: "Name", isSortable: true },
|
|
40
|
+
{ accessor: "email", label: "Email", isSortable: false },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const data = [
|
|
44
|
+
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
45
|
+
{ id: 2, name: "Jane Smith", email: "jane@example.com" },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
return <Table manualHeaders={headers} manualRowData={data} />;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### TypeScript
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { Table, TableHeader } from "all-purpose-table";
|
|
56
|
+
|
|
57
|
+
function App() {
|
|
58
|
+
const headers: TableHeader[] = [
|
|
59
|
+
{ accessor: "id", label: "ID", isSortable: true, width: 80 },
|
|
60
|
+
{ accessor: "name", label: "Name", isSortable: true, minWidth: 150 },
|
|
61
|
+
{ accessor: "email", label: "Email" },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const data = [
|
|
65
|
+
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
66
|
+
{ id: 2, name: "Jane Smith", email: "jane@example.com" },
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
return <Table manualHeaders={headers} manualRowData={data} />;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 📖 API Reference
|
|
74
|
+
|
|
75
|
+
### Table Props
|
|
76
|
+
|
|
77
|
+
| Prop | Type | Default | Description |
|
|
78
|
+
| ----------------------------- | -------------------- | --------------- | --------------------------------------------- |
|
|
79
|
+
| `manualHeaders` | `TableHeader[]` | **required** | Array of column definitions |
|
|
80
|
+
| `manualRowData` | `object[]` | **required** | Array of data objects |
|
|
81
|
+
| `height` | `string` | `"100%"` | Table container height |
|
|
82
|
+
| `rowHeight` | `number` | `40` | Height of each row in pixels |
|
|
83
|
+
| `rowsPerPage` | `number` | `60` | Number of rows per page |
|
|
84
|
+
| `shouldPaginate` | `boolean` | `true` | Enable/disable pagination |
|
|
85
|
+
| `initialSort` | `SortConfig` | `null` | Initial sort configuration |
|
|
86
|
+
| `rowClassName` | `(row) => string` | `undefined` | Custom row class names |
|
|
87
|
+
| `onRowClick` | `(row) => void` | `undefined` | Row click handler |
|
|
88
|
+
| `minColWidth` | `number` | `50` | Minimum column width in pixels |
|
|
89
|
+
| `columnWidthsStorageKey` | `string` | `undefined` | localStorage key for persisting column widths |
|
|
90
|
+
| `rowsPerPageOptions` | `number[]` | `[20, 50, 100]` | Options for rows per page selector |
|
|
91
|
+
| `onRowsPerPageChange` | `(value) => void` | `undefined` | Callback when rows per page changes |
|
|
92
|
+
| `expandedRowId` | `string` | `null` | ID of currently expanded row |
|
|
93
|
+
| `renderExpandedRow` | `(row) => ReactNode` | `undefined` | Render function for expanded row content |
|
|
94
|
+
| `renderFullRow` | `(row) => ReactNode` | `undefined` | Render function for custom full-width rows |
|
|
95
|
+
| `mobileAutoSizeOnHeaderClick` | `boolean` | `false` | Enable mobile auto-sizing on header click |
|
|
96
|
+
| `mobileBreakpoint` | `number` | `768` | Mobile breakpoint in pixels |
|
|
97
|
+
|
|
98
|
+
### TableHeader Interface
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
interface TableHeader {
|
|
102
|
+
accessor: string; // Key to access data in row object
|
|
103
|
+
label: string; // Display label for column
|
|
104
|
+
isSortable?: boolean; // Enable sorting for this column
|
|
105
|
+
width?: string | number; // Initial column width
|
|
106
|
+
minWidth?: string | number; // Minimum column width
|
|
107
|
+
cellRenderer?: (args: {
|
|
108
|
+
// Custom cell renderer
|
|
109
|
+
row: any;
|
|
110
|
+
value: any;
|
|
111
|
+
}) => React.ReactNode;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 🎨 Advanced Usage
|
|
116
|
+
|
|
117
|
+
### Custom Cell Renderers
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
const headers: TableHeader[] = [
|
|
121
|
+
{
|
|
122
|
+
accessor: "status",
|
|
123
|
+
label: "Status",
|
|
124
|
+
cellRenderer: ({ value }) => (
|
|
125
|
+
<span className={`status-${value.toLowerCase()}`}>{value}</span>
|
|
126
|
+
),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
accessor: "actions",
|
|
130
|
+
label: "Actions",
|
|
131
|
+
cellRenderer: ({ row }) => (
|
|
132
|
+
<button onClick={() => handleEdit(row.id)}>Edit</button>
|
|
133
|
+
),
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Persistent Column Widths
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
<Table
|
|
142
|
+
manualHeaders={headers}
|
|
143
|
+
manualRowData={data}
|
|
144
|
+
columnWidthsStorageKey="my-table-columns"
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Expandable Rows
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
const [expandedRowId, setExpandedRowId] = useState(null);
|
|
152
|
+
|
|
153
|
+
<Table
|
|
154
|
+
manualHeaders={headers}
|
|
155
|
+
manualRowData={data}
|
|
156
|
+
expandedRowId={expandedRowId}
|
|
157
|
+
onRowClick={(row) =>
|
|
158
|
+
setExpandedRowId(expandedRowId === row.id ? null : row.id)
|
|
159
|
+
}
|
|
160
|
+
renderExpandedRow={(row) => (
|
|
161
|
+
<div className="row-details">
|
|
162
|
+
<p>Additional details for {row.name}</p>
|
|
163
|
+
</div>
|
|
164
|
+
)}
|
|
165
|
+
/>;
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Column Visibility Toggle
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { Table, ColumnVisibilityToggle } from "all-purpose-table";
|
|
172
|
+
|
|
173
|
+
function App() {
|
|
174
|
+
const [visibleColumns, setVisibleColumns] = useState(["id", "name", "email"]);
|
|
175
|
+
|
|
176
|
+
const availableColumns = [
|
|
177
|
+
{ key: "id", label: "ID" },
|
|
178
|
+
{ key: "name", label: "Name" },
|
|
179
|
+
{ key: "email", label: "Email" },
|
|
180
|
+
{ key: "phone", label: "Phone" },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
const filteredHeaders = headers.filter((h) =>
|
|
184
|
+
visibleColumns.includes(h.accessor),
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<div>
|
|
189
|
+
<ColumnVisibilityToggle
|
|
190
|
+
availableColumns={availableColumns}
|
|
191
|
+
visibleColumns={visibleColumns}
|
|
192
|
+
onColumnsChange={setVisibleColumns}
|
|
193
|
+
storageKey="my-table-visible-columns"
|
|
194
|
+
/>
|
|
195
|
+
<Table manualHeaders={filteredHeaders} manualRowData={data} />
|
|
196
|
+
</div>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 🎨 Styling & Customization
|
|
202
|
+
|
|
203
|
+
The table comes with built-in styles that support both light and dark modes automatically. All CSS classes are prefixed with `apt-` to avoid conflicts.
|
|
204
|
+
|
|
205
|
+
### CSS Variables
|
|
206
|
+
|
|
207
|
+
You can customize colors by overriding CSS variables:
|
|
208
|
+
|
|
209
|
+
```css
|
|
210
|
+
:root {
|
|
211
|
+
--apt-color-primary: #1f2937;
|
|
212
|
+
--apt-color-border: #d1d5db;
|
|
213
|
+
--apt-color-bg: white;
|
|
214
|
+
--apt-color-accent: #9333ea;
|
|
215
|
+
/* ... and more */
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Custom Styling
|
|
220
|
+
|
|
221
|
+
All elements have semantic class names:
|
|
222
|
+
|
|
223
|
+
```css
|
|
224
|
+
.apt-table-container {
|
|
225
|
+
/* Main container */
|
|
226
|
+
}
|
|
227
|
+
.apt-table {
|
|
228
|
+
/* Table element */
|
|
229
|
+
}
|
|
230
|
+
.apt-thead {
|
|
231
|
+
/* Table header */
|
|
232
|
+
}
|
|
233
|
+
.apt-tbody {
|
|
234
|
+
/* Table body */
|
|
235
|
+
}
|
|
236
|
+
.apt-row {
|
|
237
|
+
/* Table row */
|
|
238
|
+
}
|
|
239
|
+
.apt-td {
|
|
240
|
+
/* Table cell */
|
|
241
|
+
}
|
|
242
|
+
.apt-footer {
|
|
243
|
+
/* Pagination footer */
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## 🔧 Framework Compatibility
|
|
248
|
+
|
|
249
|
+
Works seamlessly with:
|
|
250
|
+
|
|
251
|
+
- ✅ Create React App
|
|
252
|
+
- ✅ Next.js (App Router & Pages Router)
|
|
253
|
+
- ✅ Vite
|
|
254
|
+
- ✅ Remix
|
|
255
|
+
- ✅ Any React 17+ project
|
|
256
|
+
|
|
257
|
+
## 📱 Mobile Support
|
|
258
|
+
|
|
259
|
+
The table is fully responsive and includes:
|
|
260
|
+
|
|
261
|
+
- Horizontal scrolling on small screens
|
|
262
|
+
- Optional auto-sizing columns on header click
|
|
263
|
+
- Touch-friendly column resizing
|
|
264
|
+
- Configurable mobile breakpoint
|
|
265
|
+
|
|
266
|
+
## 🌙 Dark Mode
|
|
267
|
+
|
|
268
|
+
Dark mode is supported automatically via CSS `prefers-color-scheme`. No JavaScript required!
|
|
269
|
+
|
|
270
|
+
## 🚢 Production Ready
|
|
271
|
+
|
|
272
|
+
- **Tree-shakeable** - Only bundle what you use
|
|
273
|
+
- **TypeScript** - Full type definitions included
|
|
274
|
+
- **SSR Compatible** - Works with server-side rendering
|
|
275
|
+
- **Accessible** - Semantic HTML and ARIA attributes
|
|
276
|
+
- **Performant** - Optimized for large datasets
|
|
277
|
+
|
|
278
|
+
## 📄 License
|
|
279
|
+
|
|
280
|
+
MIT
|
|
281
|
+
|
|
282
|
+
## 🤝 Contributing
|
|
283
|
+
|
|
284
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
285
|
+
|
|
286
|
+
## 📮 Support
|
|
287
|
+
|
|
288
|
+
For issues and feature requests, please use the GitHub issues page.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
interface TableHeader {
|
|
2
|
+
accessor: string;
|
|
3
|
+
label: string;
|
|
4
|
+
isSortable?: boolean;
|
|
5
|
+
width?: string | number;
|
|
6
|
+
minWidth?: string | number;
|
|
7
|
+
cellRenderer?: (args: {
|
|
8
|
+
row: any;
|
|
9
|
+
value: any;
|
|
10
|
+
}) => React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
interface SortConfig {
|
|
13
|
+
key: string;
|
|
14
|
+
direction: "asc" | "desc";
|
|
15
|
+
}
|
|
16
|
+
interface TableProps {
|
|
17
|
+
manualHeaders: TableHeader[];
|
|
18
|
+
manualRowData: Record<string, any>[];
|
|
19
|
+
initialSort?: SortConfig | null;
|
|
20
|
+
height?: string;
|
|
21
|
+
rowHeight?: number;
|
|
22
|
+
rowsPerPage?: number;
|
|
23
|
+
shouldPaginate?: boolean;
|
|
24
|
+
rowClassName?: (row: any) => string;
|
|
25
|
+
onRowClick?: (row: any) => void;
|
|
26
|
+
minColWidth?: number;
|
|
27
|
+
mobileAutoSizeOnHeaderClick?: boolean;
|
|
28
|
+
mobileBreakpoint?: number;
|
|
29
|
+
columnWidthsStorageKey?: string;
|
|
30
|
+
rowsPerPageOptions?: number[];
|
|
31
|
+
onRowsPerPageChange?: (value: number) => void;
|
|
32
|
+
expandedRowId?: string | null;
|
|
33
|
+
renderExpandedRow?: (row: any) => React.ReactNode;
|
|
34
|
+
renderFullRow?: (row: any) => React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
declare const Table: React.FC<TableProps>;
|
|
37
|
+
|
|
38
|
+
interface ColumnDefinition {
|
|
39
|
+
key: string;
|
|
40
|
+
label: string;
|
|
41
|
+
}
|
|
42
|
+
interface ColumnVisibilityToggleProps {
|
|
43
|
+
availableColumns: ColumnDefinition[];
|
|
44
|
+
visibleColumns: string[];
|
|
45
|
+
onColumnsChange: (columns: string[]) => void;
|
|
46
|
+
storageKey?: string;
|
|
47
|
+
}
|
|
48
|
+
declare const ColumnVisibilityToggle: React.FC<ColumnVisibilityToggleProps>;
|
|
49
|
+
|
|
50
|
+
export { type ColumnDefinition, ColumnVisibilityToggle, type ColumnVisibilityToggleProps, type SortConfig, Table, type TableHeader, type TableProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
interface TableHeader {
|
|
2
|
+
accessor: string;
|
|
3
|
+
label: string;
|
|
4
|
+
isSortable?: boolean;
|
|
5
|
+
width?: string | number;
|
|
6
|
+
minWidth?: string | number;
|
|
7
|
+
cellRenderer?: (args: {
|
|
8
|
+
row: any;
|
|
9
|
+
value: any;
|
|
10
|
+
}) => React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
interface SortConfig {
|
|
13
|
+
key: string;
|
|
14
|
+
direction: "asc" | "desc";
|
|
15
|
+
}
|
|
16
|
+
interface TableProps {
|
|
17
|
+
manualHeaders: TableHeader[];
|
|
18
|
+
manualRowData: Record<string, any>[];
|
|
19
|
+
initialSort?: SortConfig | null;
|
|
20
|
+
height?: string;
|
|
21
|
+
rowHeight?: number;
|
|
22
|
+
rowsPerPage?: number;
|
|
23
|
+
shouldPaginate?: boolean;
|
|
24
|
+
rowClassName?: (row: any) => string;
|
|
25
|
+
onRowClick?: (row: any) => void;
|
|
26
|
+
minColWidth?: number;
|
|
27
|
+
mobileAutoSizeOnHeaderClick?: boolean;
|
|
28
|
+
mobileBreakpoint?: number;
|
|
29
|
+
columnWidthsStorageKey?: string;
|
|
30
|
+
rowsPerPageOptions?: number[];
|
|
31
|
+
onRowsPerPageChange?: (value: number) => void;
|
|
32
|
+
expandedRowId?: string | null;
|
|
33
|
+
renderExpandedRow?: (row: any) => React.ReactNode;
|
|
34
|
+
renderFullRow?: (row: any) => React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
declare const Table: React.FC<TableProps>;
|
|
37
|
+
|
|
38
|
+
interface ColumnDefinition {
|
|
39
|
+
key: string;
|
|
40
|
+
label: string;
|
|
41
|
+
}
|
|
42
|
+
interface ColumnVisibilityToggleProps {
|
|
43
|
+
availableColumns: ColumnDefinition[];
|
|
44
|
+
visibleColumns: string[];
|
|
45
|
+
onColumnsChange: (columns: string[]) => void;
|
|
46
|
+
storageKey?: string;
|
|
47
|
+
}
|
|
48
|
+
declare const ColumnVisibilityToggle: React.FC<ColumnVisibilityToggleProps>;
|
|
49
|
+
|
|
50
|
+
export { type ColumnDefinition, ColumnVisibilityToggle, type ColumnVisibilityToggleProps, type SortConfig, Table, type TableHeader, type TableProps };
|