all-purpose-table 1.0.5 → 1.0.6
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 +99 -104
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
# All Purpose Table
|
|
1
|
+
# All Purpose Table
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Use one table component for everything in your app.
|
|
5
|
-
DEMOs coming soon.
|
|
3
|
+
A production-grade, plug-and-play React table component with TypeScript support and zero dependencies.
|
|
6
4
|
|
|
7
5
|
## ✨ Features
|
|
8
6
|
|
|
9
7
|
- 🎯 **Plug and Play** - Install and use, no configuration needed
|
|
10
|
-
- 📦 **Zero Dependencies**
|
|
11
|
-
- 🟦 **TypeScript Native**
|
|
12
|
-
- 🌑 **Dark Mode** -
|
|
8
|
+
- 📦 **Zero Dependencies** — No CSS frameworks or icon libraries required
|
|
9
|
+
- 🟦 **TypeScript Native** — Full type safety and IntelliSense support
|
|
10
|
+
- 🌑 **Dark Mode** — `prefers-color-scheme` and manual class toggling (`.dark`, `html.dark`)
|
|
13
11
|
- 📊 **Feature Rich**:
|
|
14
|
-
- Sorting
|
|
15
|
-
- Pagination
|
|
12
|
+
- Sorting per column
|
|
13
|
+
- Pagination with configurable rows per page
|
|
16
14
|
- Column visibility toggle
|
|
17
|
-
- Column resizing
|
|
15
|
+
- Column resizing (drag) with optional localStorage persistence
|
|
18
16
|
- Expandable rows
|
|
19
17
|
- Custom cell renderers
|
|
18
|
+
- Full custom row rendering
|
|
20
19
|
- Row click handlers
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Mobile responsive with auto-sizing
|
|
24
|
-
- Virtual scrolling ready
|
|
20
|
+
- Scrollable body with fixed header
|
|
21
|
+
- Mobile responsive with optional auto-sizing on header click
|
|
25
22
|
|
|
26
23
|
## 📦 Installation
|
|
27
24
|
|
|
@@ -31,41 +28,18 @@ npm install all-purpose-table
|
|
|
31
28
|
|
|
32
29
|
## ⚡ Quick Start
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```jsx
|
|
31
|
+
```tsx
|
|
37
32
|
import { Table } from "all-purpose-table";
|
|
38
33
|
|
|
39
34
|
function App() {
|
|
40
35
|
const headers = [
|
|
41
|
-
{ accessor: "id",
|
|
42
|
-
{ accessor: "name",
|
|
43
|
-
{ accessor: "email", label: "Email", isSortable: false },
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
const data = [
|
|
47
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
48
|
-
{ id: 2, name: "Jane Smith", email: "jane@example.com" },
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
return <Table manualHeaders={headers} manualRowData={data} />;
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### TypeScript
|
|
56
|
-
|
|
57
|
-
```tsx
|
|
58
|
-
import { Table, TableHeader } from "all-purpose-table";
|
|
59
|
-
|
|
60
|
-
function App() {
|
|
61
|
-
const headers: TableHeader[] = [
|
|
62
|
-
{ accessor: "id", label: "ID", isSortable: true, width: 80 },
|
|
63
|
-
{ accessor: "name", label: "Name", isSortable: true, minWidth: 150 },
|
|
36
|
+
{ accessor: "id", label: "ID", isSortable: true },
|
|
37
|
+
{ accessor: "name", label: "Name", isSortable: true },
|
|
64
38
|
{ accessor: "email", label: "Email" },
|
|
65
39
|
];
|
|
66
40
|
|
|
67
41
|
const data = [
|
|
68
|
-
{ id: 1, name: "John Doe",
|
|
42
|
+
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
69
43
|
{ id: 2, name: "Jane Smith", email: "jane@example.com" },
|
|
70
44
|
];
|
|
71
45
|
|
|
@@ -125,12 +99,13 @@ const headers: TableHeader[] = [
|
|
|
125
99
|
accessor: "status",
|
|
126
100
|
label: "Status",
|
|
127
101
|
cellRenderer: ({ value }) => (
|
|
128
|
-
<span className={`
|
|
102
|
+
<span className={`badge badge-${value.toLowerCase()}`}>{value}</span>
|
|
129
103
|
),
|
|
130
104
|
},
|
|
131
105
|
{
|
|
132
106
|
accessor: "actions",
|
|
133
107
|
label: "Actions",
|
|
108
|
+
// Cells with accessor "actions" automatically stop row-click propagation
|
|
134
109
|
cellRenderer: ({ row }) => (
|
|
135
110
|
<button onClick={() => handleEdit(row.id)}>Edit</button>
|
|
136
111
|
),
|
|
@@ -138,34 +113,69 @@ const headers: TableHeader[] = [
|
|
|
138
113
|
];
|
|
139
114
|
```
|
|
140
115
|
|
|
141
|
-
###
|
|
116
|
+
### Expandable Rows
|
|
142
117
|
|
|
143
118
|
```tsx
|
|
119
|
+
const [expandedRowId, setExpandedRowId] = useState<string | null>(null);
|
|
120
|
+
|
|
144
121
|
<Table
|
|
145
122
|
manualHeaders={headers}
|
|
146
123
|
manualRowData={data}
|
|
147
|
-
|
|
124
|
+
expandedRowId={expandedRowId}
|
|
125
|
+
onRowClick={(row) =>
|
|
126
|
+
setExpandedRowId(expandedRowId === row.id ? null : row.id)
|
|
127
|
+
}
|
|
128
|
+
renderExpandedRow={(row) => (
|
|
129
|
+
<div style={{ padding: 16 }}>
|
|
130
|
+
<p>Details for {row.name}</p>
|
|
131
|
+
</div>
|
|
132
|
+
)}
|
|
148
133
|
/>
|
|
149
134
|
```
|
|
150
135
|
|
|
151
|
-
###
|
|
136
|
+
### Full Custom Row
|
|
137
|
+
|
|
138
|
+
Set `fullRow: true` on any data object to replace that row entirely with `renderFullRow`:
|
|
152
139
|
|
|
153
140
|
```tsx
|
|
154
|
-
const
|
|
141
|
+
const data = [
|
|
142
|
+
{ id: 1, name: "John" },
|
|
143
|
+
{ id: "divider", fullRow: true }, // uses renderFullRow
|
|
144
|
+
];
|
|
155
145
|
|
|
156
146
|
<Table
|
|
157
147
|
manualHeaders={headers}
|
|
158
148
|
manualRowData={data}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
setExpandedRowId(expandedRowId === row.id ? null : row.id)
|
|
162
|
-
}
|
|
163
|
-
renderExpandedRow={(row) => (
|
|
164
|
-
<div className="row-details">
|
|
165
|
-
<p>Additional details for {row.name}</p>
|
|
166
|
-
</div>
|
|
149
|
+
renderFullRow={(row) => (
|
|
150
|
+
<div style={{ padding: "8px 16px", fontWeight: "bold" }}>Section Header</div>
|
|
167
151
|
)}
|
|
168
|
-
|
|
152
|
+
/>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Rows Per Page Selector
|
|
156
|
+
|
|
157
|
+
The footer (including the dropdown) only renders when `onRowsPerPageChange` is provided:
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
const [rowsPerPage, setRowsPerPage] = useState(20);
|
|
161
|
+
|
|
162
|
+
<Table
|
|
163
|
+
manualHeaders={headers}
|
|
164
|
+
manualRowData={data}
|
|
165
|
+
rowsPerPage={rowsPerPage}
|
|
166
|
+
rowsPerPageOptions={[10, 20, 50, 100]}
|
|
167
|
+
onRowsPerPageChange={setRowsPerPage}
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Persistent Column Widths
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
<Table
|
|
175
|
+
manualHeaders={headers}
|
|
176
|
+
manualRowData={data}
|
|
177
|
+
columnWidthsStorageKey="my-table-columns"
|
|
178
|
+
/>
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
### Column Visibility Toggle
|
|
@@ -203,80 +213,65 @@ function App() {
|
|
|
203
213
|
|
|
204
214
|
## 🎨 Styling & Customization
|
|
205
215
|
|
|
206
|
-
The table comes with built-in styles
|
|
216
|
+
The table comes with built-in styles. All CSS classes are prefixed with `apt-` to avoid conflicts.
|
|
217
|
+
|
|
218
|
+
### Dark Mode
|
|
219
|
+
|
|
220
|
+
Dark mode is toggled by adding the `dark` class to any ancestor element (e.g. `<html>` or a wrapper `<div>`):
|
|
221
|
+
|
|
222
|
+
```jsx
|
|
223
|
+
// Toggle dark mode
|
|
224
|
+
document.documentElement.classList.toggle("dark");
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
No extra configuration is needed — the component responds automatically.
|
|
207
228
|
|
|
208
229
|
### CSS Variables
|
|
209
230
|
|
|
210
|
-
|
|
231
|
+
Override CSS variables to customise colours, spacing, and more:
|
|
211
232
|
|
|
212
233
|
```css
|
|
213
234
|
:root {
|
|
214
235
|
--apt-color-primary: #1f2937;
|
|
215
236
|
--apt-color-border: #d1d5db;
|
|
216
237
|
--apt-color-bg: white;
|
|
238
|
+
--apt-color-bg-secondary: #f9fafb;
|
|
217
239
|
--apt-color-accent: #9333ea;
|
|
218
240
|
/* ... and more */
|
|
219
241
|
}
|
|
220
242
|
```
|
|
221
243
|
|
|
222
|
-
###
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
.apt-tbody {
|
|
237
|
-
/* Table body */
|
|
238
|
-
}
|
|
239
|
-
.apt-row {
|
|
240
|
-
/* Table row */
|
|
241
|
-
}
|
|
242
|
-
.apt-td {
|
|
243
|
-
/* Table cell */
|
|
244
|
-
}
|
|
245
|
-
.apt-footer {
|
|
246
|
-
/* Pagination footer */
|
|
247
|
-
}
|
|
248
|
-
```
|
|
244
|
+
### CSS Class Reference
|
|
245
|
+
|
|
246
|
+
| Class | Element |
|
|
247
|
+
|---|---|
|
|
248
|
+
| `.apt-table-container` | Outermost wrapper |
|
|
249
|
+
| `.apt-scroll-area` | Scrollable region (contains both table parts) |
|
|
250
|
+
| `.apt-thead-wrapper` | Fixed header wrapper |
|
|
251
|
+
| `.apt-tbody-wrapper` | Scrollable body wrapper |
|
|
252
|
+
| `.apt-table` | `<table>` element |
|
|
253
|
+
| `.apt-thead` | `<thead>` |
|
|
254
|
+
| `.apt-tbody` | `<tbody>` |
|
|
255
|
+
| `.apt-row` | `<tr>` |
|
|
256
|
+
| `.apt-td` | `<td>` / `<th>` |
|
|
257
|
+
| `.apt-footer` | Pagination footer |
|
|
249
258
|
|
|
250
259
|
## 🔧 Framework Compatibility
|
|
251
260
|
|
|
252
|
-
Works seamlessly with:
|
|
253
|
-
|
|
254
|
-
- ✅ Create React App
|
|
255
261
|
- ✅ Next.js (App Router & Pages Router)
|
|
256
262
|
- ✅ Vite
|
|
263
|
+
- ✅ Create React App
|
|
257
264
|
- ✅ Remix
|
|
258
265
|
- ✅ Any React 17+ project
|
|
259
266
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
The table is fully responsive and includes:
|
|
263
|
-
|
|
264
|
-
- Horizontal scrolling on small screens
|
|
265
|
-
- Optional auto-sizing columns on header click
|
|
266
|
-
- Touch-friendly column resizing
|
|
267
|
-
- Configurable mobile breakpoint
|
|
268
|
-
|
|
269
|
-
## 🌙 Themes
|
|
270
|
-
|
|
271
|
-
Dark mode is supported automatically via CSS `prefers-color-scheme`. No JavaScript required!
|
|
267
|
+
> **Note:** The component uses browser APIs (`localStorage`, `ResizeObserver`, `window`) — wrap it in a client-only boundary when using SSR frameworks like Next.js App Router.
|
|
272
268
|
|
|
273
269
|
## 🏭 Production Ready
|
|
274
270
|
|
|
275
|
-
- **Tree-shakeable**
|
|
276
|
-
- **TypeScript**
|
|
277
|
-
- **
|
|
278
|
-
- **
|
|
279
|
-
- **Performant** - Optimized for large datasets
|
|
271
|
+
- **Tree-shakeable** — Only bundle what you use
|
|
272
|
+
- **TypeScript** — Full type definitions included
|
|
273
|
+
- **Zero dependencies** — No external libraries required
|
|
274
|
+
- **Performant** — `useMemo` and derived state throughout, no unnecessary re-renders
|
|
280
275
|
|
|
281
276
|
## 📄 License
|
|
282
277
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "all-purpose-table",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "A production-grade, plug-and-play React Table component with TypeScript support",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
|
-
"module": "dist/index.
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|