@dynostack/react-grid 0.2.0 → 0.3.1
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 +162 -7
- package/dist/index.cjs +463 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -3
- package/dist/index.d.ts +103 -3
- package/dist/index.js +465 -35
- package/dist/index.js.map +1 -1
- package/dist/styles.css +51 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -51,6 +51,8 @@ A single `<DataTable />` component that gives you ag-grid–level functionality
|
|
|
51
51
|
- [Selection & bulk actions](#selection--bulk-actions)
|
|
52
52
|
- [Expandable rows](#expandable-rows)
|
|
53
53
|
- [Export](#export)
|
|
54
|
+
- [View sheet](#view-sheet)
|
|
55
|
+
- [Delete confirmation](#delete-confirmation)
|
|
54
56
|
- [Custom row actions](#custom-row-actions)
|
|
55
57
|
- [Server-side data](#server-side-data)
|
|
56
58
|
- [API reference](#api-reference)
|
|
@@ -75,7 +77,28 @@ yarn add @dynostack/react-grid
|
|
|
75
77
|
|
|
76
78
|
## Tailwind setup
|
|
77
79
|
|
|
78
|
-
The component ships Tailwind class names verbatim
|
|
80
|
+
The component ships Tailwind class names verbatim, so your Tailwind build needs to know two things:
|
|
81
|
+
|
|
82
|
+
1. **Where to scan** for the class strings inside the bundle.
|
|
83
|
+
2. **Which semantic color tokens** (`bg-popover`, `bg-card`, `text-foreground`, …) exist.
|
|
84
|
+
|
|
85
|
+
The package's `styles.css` registers the tokens for you via Tailwind v4's `@theme inline`. You only need to wire scanning.
|
|
86
|
+
|
|
87
|
+
### Tailwind v4 — zero config
|
|
88
|
+
|
|
89
|
+
```css
|
|
90
|
+
/* your global stylesheet (e.g. src/index.css) */
|
|
91
|
+
@import "tailwindcss";
|
|
92
|
+
@source "../node_modules/@dynostack/react-grid/dist";
|
|
93
|
+
@import "@dynostack/react-grid/styles.css";
|
|
94
|
+
@import "@dynostack/react-grid/page.css"; /* optional: extend tokens to <body> */
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
That's the whole setup. No `tailwind.config.js`, no `@theme` block to copy-paste, no shadcn install required. Overlay surfaces (popovers, dropdowns, sheets, the row-actions menu) all render correctly out of the box.
|
|
98
|
+
|
|
99
|
+
### Tailwind v3
|
|
100
|
+
|
|
101
|
+
v3 doesn't read CSS `@theme` directives, so the semantic-color mapping has to live in your `tailwind.config.js`. The shadcn install guide for v3 covers the exact `theme.extend.colors` block you need — copy that, plus add the package's `dist` to your `content` array:
|
|
79
102
|
|
|
80
103
|
```js
|
|
81
104
|
// tailwind.config.{js,ts}
|
|
@@ -84,10 +107,28 @@ export default {
|
|
|
84
107
|
"./src/**/*.{ts,tsx}",
|
|
85
108
|
"./node_modules/@dynostack/react-grid/dist/**/*.{js,mjs,cjs}",
|
|
86
109
|
],
|
|
110
|
+
theme: {
|
|
111
|
+
extend: {
|
|
112
|
+
colors: {
|
|
113
|
+
// copy the shadcn v3 color mapping here
|
|
114
|
+
// (background, foreground, card, popover, primary, secondary,
|
|
115
|
+
// muted, accent, destructive, border, input, ring)
|
|
116
|
+
background: "hsl(var(--background))",
|
|
117
|
+
foreground: "hsl(var(--foreground))",
|
|
118
|
+
// … etc
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
87
122
|
}
|
|
88
123
|
```
|
|
89
124
|
|
|
90
|
-
|
|
125
|
+
Then import `styles.css` as usual:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import "@dynostack/react-grid/styles.css"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
> Starting a new project? **Use Tailwind v4.** The v4 path above is meaningfully simpler — the package handles token registration for you.
|
|
91
132
|
|
|
92
133
|
## Theme tokens
|
|
93
134
|
|
|
@@ -102,15 +143,22 @@ The grid is built on **shadcn/ui CSS variables**. It auto-adjusts to whatever th
|
|
|
102
143
|
| Custom theme with non-shadcn names | Pass [`theme` prop](#theming) | Per-instance override mapped to shadcn vars. |
|
|
103
144
|
| Want one grid to ignore the app theme | Pass `isolate` | Grid uses bundled defaults regardless of `:root`. |
|
|
104
145
|
|
|
105
|
-
**Why this just works.** The bundled `styles.css
|
|
146
|
+
**Why this just works.** The bundled `styles.css`:
|
|
106
147
|
|
|
107
|
-
|
|
148
|
+
1. **Registers Tailwind v4 utility tokens** via a top-level `@theme inline` block — so `bg-popover`, `text-foreground`, `border-border`, etc. resolve to your tokens without any consumer-side `@theme` block.
|
|
149
|
+
2. **Declares variable values inside the `dynostack-grid-defaults` cascade layer** — any unlayered consumer rule (which is where shadcn and most app CSS lives) automatically wins, regardless of import order. You can't accidentally overwrite your app's theme by importing the grid's stylesheet.
|
|
108
150
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
151
|
+
### Minimal install (Tailwind v4)
|
|
152
|
+
|
|
153
|
+
```css
|
|
154
|
+
/* your global stylesheet */
|
|
155
|
+
@import "tailwindcss";
|
|
156
|
+
@source "../node_modules/@dynostack/react-grid/dist";
|
|
157
|
+
@import "@dynostack/react-grid/styles.css";
|
|
112
158
|
```
|
|
113
159
|
|
|
160
|
+
See the [Tailwind setup](#tailwind-setup) section for v3.
|
|
161
|
+
|
|
114
162
|
### Optional: extend the theme to the page
|
|
115
163
|
|
|
116
164
|
By default the grid only styles itself, not the surrounding page. If you want `<body>` to use the same background/foreground as the grid:
|
|
@@ -610,6 +658,72 @@ Mark a column non-exportable via `meta.exportable: false`.
|
|
|
610
658
|
|
|
611
659
|
---
|
|
612
660
|
|
|
661
|
+
## View sheet
|
|
662
|
+
|
|
663
|
+
Click the row action "View" → a right-side `Sheet` slides in showing every visible column as a `{Label}: {value}` card. The user can switch layout density inline (Compact 1 col / Relaxed 2 col / Comfy 3 col).
|
|
664
|
+
|
|
665
|
+
Works out of the box with no props. Customize via `viewSheet`:
|
|
666
|
+
|
|
667
|
+
```tsx
|
|
668
|
+
<DataTable
|
|
669
|
+
viewSheet={{
|
|
670
|
+
side: "right", // or "left"
|
|
671
|
+
defaultDensity: "relaxed", // initial column count
|
|
672
|
+
hideDensityTabs: true, // hide the layout picker
|
|
673
|
+
fields: ["name", "email", "role"], // limit / reorder shown columns
|
|
674
|
+
renderField: ({ column, value, row }) => // override how a value renders
|
|
675
|
+
column.id === "phone" ? <a href={`tel:${value}`}>{String(value)}</a> : null,
|
|
676
|
+
renderHeader: (row) => <YourCustomHeader row={row} />,
|
|
677
|
+
labels: {
|
|
678
|
+
title: (row) => `${row.name} (${row.role})`,
|
|
679
|
+
description: (row) => `Joined ${row.joinedAt}`,
|
|
680
|
+
emptyValue: "—",
|
|
681
|
+
density: { compact: "1 col", relaxed: "2 cols", comfy: "3 cols" },
|
|
682
|
+
},
|
|
683
|
+
}}
|
|
684
|
+
onView={(row) => track("user.view", row)} // optional side-effect
|
|
685
|
+
/>
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
Disable the built-in sheet entirely:
|
|
689
|
+
|
|
690
|
+
```tsx
|
|
691
|
+
<DataTable viewSheet={false} onView={(row) => router.push(`/users/${row.id}`)} />
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
`onView` fires before the sheet opens, so you can navigate / log / fetch alongside it.
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
## Delete confirmation
|
|
699
|
+
|
|
700
|
+
Both the row-action "Delete" and the toolbar "Bulk delete" open a confirmation `AlertDialog` by default. The user must confirm before `onDelete` or `onBulkDelete` fires.
|
|
701
|
+
|
|
702
|
+
```tsx
|
|
703
|
+
<DataTable
|
|
704
|
+
onDelete={(row) => api.deleteUser(row.id)}
|
|
705
|
+
onBulkDelete={(rows) => api.bulkDelete(rows.map(r => r.id))}
|
|
706
|
+
confirmDelete={{
|
|
707
|
+
title: ({ rows, source }) =>
|
|
708
|
+
source === "bulk"
|
|
709
|
+
? `Delete ${rows.length} users?`
|
|
710
|
+
: `Delete ${rows[0].name}?`,
|
|
711
|
+
description: ({ rows }) =>
|
|
712
|
+
`${rows.length === 1 ? "This user" : "These users"} will be permanently removed. This cannot be undone.`,
|
|
713
|
+
confirmLabel: "Yes, delete",
|
|
714
|
+
cancelLabel: "Keep",
|
|
715
|
+
}}
|
|
716
|
+
/>
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
Skip the dialog (fire immediately):
|
|
720
|
+
|
|
721
|
+
```tsx
|
|
722
|
+
<DataTable confirmDelete={false} onDelete={(row) => softDelete(row)} />
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
613
727
|
## Custom row actions
|
|
614
728
|
|
|
615
729
|
```tsx
|
|
@@ -731,6 +845,10 @@ operations and only renders the returned page.
|
|
|
731
845
|
| `density` | `"compact" \| "default" \| "comfortable"` | `"default"` | Row density. |
|
|
732
846
|
| `theme` | `DataTableTheme` | inherits `:root` | Per-instance CSS-variable overrides. Accepts flat tokens **or** `{ light, dark }`. |
|
|
733
847
|
| `isolate` | `boolean` | `false` | Ignore the app's `:root` and render with bundled defaults. |
|
|
848
|
+
| `onView` | `(row: TData) => void` | — | Side-effect when "View" is clicked. Fires *before* the sheet opens. |
|
|
849
|
+
| `onDelete` | `(row: TData) => void` | — | Single-row delete handler. Fires *after* the confirm modal (or immediately if `confirmDelete={false}`). |
|
|
850
|
+
| `viewSheet` | `ViewSheetConfig<TData> \| false` | enabled | Configure or disable the built-in View sheet. |
|
|
851
|
+
| `confirmDelete` | `ConfirmDeleteConfig<TData> \| boolean` | `true` | Configure or disable the delete confirmation modal (applies to single + bulk). |
|
|
734
852
|
|
|
735
853
|
`TData` must extend `{ id: string \| number }`.
|
|
736
854
|
|
|
@@ -801,6 +919,43 @@ import {
|
|
|
801
919
|
} from "@dynostack/react-grid"
|
|
802
920
|
```
|
|
803
921
|
|
|
922
|
+
```ts
|
|
923
|
+
// View sheet types
|
|
924
|
+
type ViewSheetDensity = "compact" | "relaxed" | "comfy"
|
|
925
|
+
|
|
926
|
+
type ViewSheetConfig<TData> = {
|
|
927
|
+
side?: "right" | "left" | "top" | "bottom"
|
|
928
|
+
defaultDensity?: ViewSheetDensity
|
|
929
|
+
hideDensityTabs?: boolean
|
|
930
|
+
fields?: string[]
|
|
931
|
+
renderField?: (args: {
|
|
932
|
+
column: Column<TData, unknown>
|
|
933
|
+
value: unknown
|
|
934
|
+
row: TData
|
|
935
|
+
}) => React.ReactNode
|
|
936
|
+
renderHeader?: (row: TData) => React.ReactNode
|
|
937
|
+
labels?: {
|
|
938
|
+
title?: (row: TData) => React.ReactNode
|
|
939
|
+
description?: (row: TData) => React.ReactNode
|
|
940
|
+
emptyValue?: string
|
|
941
|
+
density?: { compact?: string; relaxed?: string; comfy?: string }
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// Confirm-delete types
|
|
946
|
+
type ConfirmDeleteContext<TData> = {
|
|
947
|
+
rows: TData[]
|
|
948
|
+
source: "single" | "bulk"
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
type ConfirmDeleteConfig<TData> = {
|
|
952
|
+
title?: (ctx: ConfirmDeleteContext<TData>) => React.ReactNode
|
|
953
|
+
description?: (ctx: ConfirmDeleteContext<TData>) => React.ReactNode
|
|
954
|
+
confirmLabel?: string
|
|
955
|
+
cancelLabel?: string
|
|
956
|
+
}
|
|
957
|
+
```
|
|
958
|
+
|
|
804
959
|
---
|
|
805
960
|
|
|
806
961
|
## Compatibility
|