@rowakit/table 0.2.2 → 0.4.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 +187 -15
- package/dist/index.cjs +675 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -5
- package/dist/index.d.ts +22 -5
- package/dist/index.js +676 -13
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/src/styles/table.css +154 -1
package/README.md
CHANGED
|
@@ -12,8 +12,12 @@ RowaKit Table is a React table component designed for real-world internal applic
|
|
|
12
12
|
✅ **Escape hatch** - `col.custom()` for any rendering need
|
|
13
13
|
✅ **Action buttons** - Built-in support for row actions with confirmation
|
|
14
14
|
✅ **7 column types** - Text, Date, Boolean, Badge, Number, Actions, Custom
|
|
15
|
-
✅ **Column modifiers** - Width, align, truncate
|
|
15
|
+
✅ **Column modifiers** - Width, align, truncate, minWidth, maxWidth (v0.2.0+)
|
|
16
16
|
✅ **Server-side filters** - Type-specific filter UI with auto-generated inputs (v0.2.0+)
|
|
17
|
+
✅ **Column resizing** - Drag-to-resize handles with constraints (v0.4.0+)
|
|
18
|
+
✅ **Saved views** - Save/load table state with localStorage persistence (v0.4.0+)
|
|
19
|
+
✅ **URL state sync** - Share URLs with exact table configuration (v0.4.0+)
|
|
20
|
+
✅ **Number range filters** - Min/max filtering for numeric columns (v0.4.0+)
|
|
17
21
|
✅ **State management** - Automatic loading, error, and empty states
|
|
18
22
|
✅ **Smart fetching** - Retry on error, stale request handling
|
|
19
23
|
|
|
@@ -852,6 +856,165 @@ col.actions([
|
|
|
852
856
|
- Keyboard accessible (Tab to focus, Enter/Space to activate)
|
|
853
857
|
- Actions column is never sortable
|
|
854
858
|
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
## Advanced Features (v0.4.0+)
|
|
862
|
+
|
|
863
|
+
### Column Resizing (C-01)
|
|
864
|
+
|
|
865
|
+
Enable users to resize columns by dragging the right edge of column headers.
|
|
866
|
+
|
|
867
|
+
**Basic Usage:**
|
|
868
|
+
|
|
869
|
+
```typescript
|
|
870
|
+
<RowaKitTable
|
|
871
|
+
fetcher={fetchData}
|
|
872
|
+
columns={[
|
|
873
|
+
col.text('name', {
|
|
874
|
+
minWidth: 100, // Minimum width (default: 80)
|
|
875
|
+
maxWidth: 400 // Maximum width (optional)
|
|
876
|
+
}),
|
|
877
|
+
col.number('price', {
|
|
878
|
+
minWidth: 80
|
|
879
|
+
})
|
|
880
|
+
]}
|
|
881
|
+
enableColumnResizing={true} // Enable resize feature
|
|
882
|
+
/>
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
**Features:**
|
|
886
|
+
- **Auto-width by default** - Columns automatically size based on header text
|
|
887
|
+
- **Drag to resize** - Drag the blue handle on the right edge of column headers
|
|
888
|
+
- **Double-click to auto-fit** - Double-click the resize handle to auto-fit content width (measures visible header + cells)
|
|
889
|
+
- **Min/max constraints** - Enforced in real-time during drag
|
|
890
|
+
- **Smooth performance** - RAF throttling prevents lag during resize
|
|
891
|
+
- **Large hitbox** - 12px wide invisible zone (1px visible line) makes dragging easy
|
|
892
|
+
- **State persistence** - Widths stored in-memory (or persisted via URL sync/saved views)
|
|
893
|
+
|
|
894
|
+
**Interaction:**
|
|
895
|
+
- **Hover** - Resize handle appears as a blue vertical line
|
|
896
|
+
- **Drag** - Click and drag to resize column width
|
|
897
|
+
- **Double-click** - Auto-fits to content (max 600px by default)
|
|
898
|
+
- Text selection is disabled during drag for smooth UX
|
|
899
|
+
|
|
900
|
+
### Saved Views + URL State Sync (C-02)
|
|
901
|
+
|
|
902
|
+
Save and restore table configurations, and share URLs with exact table state.
|
|
903
|
+
|
|
904
|
+
**Basic Usage:**
|
|
905
|
+
|
|
906
|
+
```typescript
|
|
907
|
+
<RowaKitTable
|
|
908
|
+
fetcher={fetchData}
|
|
909
|
+
columns={columns}
|
|
910
|
+
syncToUrl={true} // Sync to URL query string
|
|
911
|
+
enableSavedViews={true} // Show save/load view buttons
|
|
912
|
+
/>
|
|
913
|
+
```
|
|
914
|
+
|
|
915
|
+
**Features:**
|
|
916
|
+
|
|
917
|
+
1. **URL Sync** - Automatically saves table state to URL query parameters:
|
|
918
|
+
```
|
|
919
|
+
?page=2&pageSize=20&sortField=name&sortDirection=asc&filters=...&columnWidths=...
|
|
920
|
+
```
|
|
921
|
+
- Share URLs to preserve exact table configuration
|
|
922
|
+
- State automatically restored on page load
|
|
923
|
+
- Works with browser back/forward buttons
|
|
924
|
+
|
|
925
|
+
2. **Saved Views** - Save current table state as named presets:
|
|
926
|
+
```
|
|
927
|
+
[Save View] button → Name your view → State saved to localStorage
|
|
928
|
+
[My View] button → Click to restore saved state
|
|
929
|
+
× button → Delete saved view
|
|
930
|
+
[Reset] button → Clear all state
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
**Synced State:**
|
|
934
|
+
- Page number and size
|
|
935
|
+
- Sort field and direction
|
|
936
|
+
- All active filters
|
|
937
|
+
- Column widths (if resizing enabled)
|
|
938
|
+
|
|
939
|
+
**Example:**
|
|
940
|
+
|
|
941
|
+
```typescript
|
|
942
|
+
// User filters to "active users" and resizes columns
|
|
943
|
+
// They click "Save View" and name it "Active"
|
|
944
|
+
// Later, they apply different filters
|
|
945
|
+
// They click "Active" button to instantly restore previous state
|
|
946
|
+
|
|
947
|
+
// Or they copy the URL and send it to a colleague
|
|
948
|
+
// The colleague sees the exact same filters and layout
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
### Advanced Number Range Filters (C-03)
|
|
952
|
+
|
|
953
|
+
Number columns support min/max range filtering with optional value transformation.
|
|
954
|
+
|
|
955
|
+
**Basic Range Filter:**
|
|
956
|
+
|
|
957
|
+
```typescript
|
|
958
|
+
col.number('price', {
|
|
959
|
+
label: 'Price',
|
|
960
|
+
width: 100
|
|
961
|
+
})
|
|
962
|
+
|
|
963
|
+
// UI shows two inputs: [Min] [Max]
|
|
964
|
+
// User enters: min=100, max=500
|
|
965
|
+
// Backend receives: { op: 'range', value: { from: 100, to: 500 } }
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
**With Filter Transform:**
|
|
969
|
+
|
|
970
|
+
```typescript
|
|
971
|
+
col.number('discount', {
|
|
972
|
+
label: 'Discount %',
|
|
973
|
+
// Transform percentage input to fraction for backend
|
|
974
|
+
filterTransform: (percentageInput) => {
|
|
975
|
+
// User enters "15" (15%)
|
|
976
|
+
// Backend receives "0.15" (fraction)
|
|
977
|
+
if (percentageInput > 1) {
|
|
978
|
+
return percentageInput / 100;
|
|
979
|
+
}
|
|
980
|
+
return percentageInput;
|
|
981
|
+
}
|
|
982
|
+
})
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
**Features:**
|
|
986
|
+
- Min and max inputs can be filled independently
|
|
987
|
+
- Example: "at least 50" (min only), "up to 100" (max only), or "50-100" (both)
|
|
988
|
+
- Optional `filterTransform` to adapt filter values before sending to server
|
|
989
|
+
- Useful for unit conversion, percentage ↔ decimal, etc.
|
|
990
|
+
|
|
991
|
+
**Handling Range Filters in Fetcher:**
|
|
992
|
+
|
|
993
|
+
```typescript
|
|
994
|
+
const fetchProducts: Fetcher<Product> = async (query) => {
|
|
995
|
+
let filtered = [...allProducts];
|
|
996
|
+
|
|
997
|
+
if (query.filters) {
|
|
998
|
+
for (const [field, filter] of Object.entries(query.filters)) {
|
|
999
|
+
if (filter?.op === 'range') {
|
|
1000
|
+
const { from, to } = filter.value as { from?: number; to?: number };
|
|
1001
|
+
filtered = filtered.filter(item => {
|
|
1002
|
+
const val = item[field as keyof Product];
|
|
1003
|
+
if (from !== undefined && val < from) return false;
|
|
1004
|
+
if (to !== undefined && val > to) return false;
|
|
1005
|
+
return true;
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
return {
|
|
1012
|
+
items: filtered.slice(0, query.pageSize),
|
|
1013
|
+
total: filtered.length
|
|
1014
|
+
};
|
|
1015
|
+
};
|
|
1016
|
+
```
|
|
1017
|
+
|
|
855
1018
|
## Examples
|
|
856
1019
|
|
|
857
1020
|
### Basic Table
|
|
@@ -1292,7 +1455,7 @@ Full TypeScript support. Your data model drives type checking throughout.
|
|
|
1292
1455
|
|
|
1293
1456
|
## Roadmap
|
|
1294
1457
|
|
|
1295
|
-
**Stage A - MVP
|
|
1458
|
+
**Stage A - MVP (v0.1)** ✅ Complete (2024-12-31)
|
|
1296
1459
|
- ✅ A-01: Repo scaffold
|
|
1297
1460
|
- ✅ A-02: Core types (Fetcher, ColumnDef, ActionDef)
|
|
1298
1461
|
- ✅ A-03: Column helpers (col.*)
|
|
@@ -1304,19 +1467,28 @@ Full TypeScript support. Your data model drives type checking throughout.
|
|
|
1304
1467
|
- ✅ A-09: Minimal styling tokens (CSS variables, responsive, className)
|
|
1305
1468
|
- ✅ A-10: Documentation & examples (4 complete examples, CHANGELOG, CONTRIBUTING)
|
|
1306
1469
|
|
|
1307
|
-
**Stage B - Production Ready (v0.2.2)**
|
|
1308
|
-
-
|
|
1309
|
-
-
|
|
1310
|
-
-
|
|
1311
|
-
-
|
|
1312
|
-
-
|
|
1313
|
-
-
|
|
1314
|
-
|
|
1315
|
-
**Stage C - Advanced (
|
|
1316
|
-
-
|
|
1317
|
-
-
|
|
1318
|
-
-
|
|
1319
|
-
-
|
|
1470
|
+
**Stage B - Production Ready (v0.2.0-0.2.2)** ✅ Complete (2026-01-02)
|
|
1471
|
+
- ✅ Badge column type with visual tones (neutral, success, warning, danger)
|
|
1472
|
+
- ✅ Number column type with Intl formatting (currency, percentages, decimals)
|
|
1473
|
+
- ✅ Server-side header filter UI (type-specific inputs)
|
|
1474
|
+
- ✅ Column modifiers (width, align, truncate)
|
|
1475
|
+
- ✅ Fixed numeric filter value coercion
|
|
1476
|
+
- ✅ Production hardening and comprehensive documentation
|
|
1477
|
+
|
|
1478
|
+
**Stage C - Advanced Features (v0.4.0)** ✅ Complete (2026-01-03)
|
|
1479
|
+
- ✅ C-01: Column resizing with drag handles (minWidth/maxWidth constraints)
|
|
1480
|
+
- ✅ C-02: Saved views with localStorage persistence
|
|
1481
|
+
- ✅ C-02: URL state sync (page, pageSize, sort, filters, columnWidths)
|
|
1482
|
+
- ✅ C-03: Number range filters with optional filterTransform
|
|
1483
|
+
|
|
1484
|
+
**Stage D - Polish + Correctness (v0.4.0)** ✅ Complete (2026-01-05)
|
|
1485
|
+
- ✅ D-01: Prevent accidental sort while resizing (stopPropagation, suppression window)
|
|
1486
|
+
- ✅ D-02: Pointer Events resizing (mouse, touch, pen) with pointer capture and cleanup
|
|
1487
|
+
- ✅ D-03: Column width model hardening (apply widths to th+td, fixed layout, truncation)
|
|
1488
|
+
- ✅ D-04: Saved views persistence (index, hydration, corruption-safe)
|
|
1489
|
+
- ✅ D-05: URL sync hardening (validation, debounce, backward compatible)
|
|
1490
|
+
|
|
1491
|
+
See [ROADMAP.md](./docs/ROADMAP.md) and `docs/ROWAKIT_STAGE_D_ISSUES_v3.md` for implementation details and rationale.
|
|
1320
1492
|
|
|
1321
1493
|
## Changelog
|
|
1322
1494
|
|