@uxf/data-grid 11.122.3 → 11.122.5

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 (2) hide show
  1. package/README.md +181 -89
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -1,48 +1,104 @@
1
- # DataGrid
1
+ # @uxf/data-grid
2
2
 
3
- > **Note:** This package contains translations. For proper functionality, you must use the `TranslationsProvider` from `@uxf/core-react/translations`. See the [core-react documentation](https://fe.uxf.dev/docs/core-react) for more information.
3
+ A schema-driven, server-side data grid: one compound `DataGrid` component with a built-in toolbar, tabs, filters, sorting, column visibility, row selection, pagination and CSV export.
4
4
 
5
- ## Installation / Upgrade
5
+ ## When to use
6
6
 
7
+ Reach for `@uxf/data-grid` when you have a paginated, filterable, server-fetched table driven by a generated schema (columns, filters, tabs). The grid owns fetching, filtering, sorting and pagination state; you provide a `schema` and a `loader`.
8
+
9
+ It is **not** a headless table primitive and not a spreadsheet — layout, toolbar and footer are opinionated. For a plain, fully custom table render the internal parts yourself (see [Custom composition](#custom-composition)) rather than reaching for a different library.
10
+
11
+ > **Note:** This package ships translations. Wrap your app in the `TranslationsProvider` from `@uxf/core-react/translations` for correct labels.
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ yarn add @uxf/data-grid
7
17
  ```
8
- yarn add @uxf/core @uxf/ui @uxf/data-grid
9
18
 
10
- // or
19
+ Peer dependencies (install if not already present):
11
20
 
12
- yarn upgrade @uxf/core@latest @uxf/ui@latest @uxf/data-grid@latest
13
21
  ```
22
+ yarn add @uxf/core @uxf/core-react @uxf/localize @uxf/styles @uxf/ui \
23
+ @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities dayjs react react-dom
24
+ ```
25
+
26
+ ### CSS
14
27
 
15
- ## CSS dependencies
28
+ Import the dependency stylesheets first, then the grid's own stylesheet last. The `@uxf/ui` component styles are published under the flattened `@uxf/ui/css/` directory (the `@uxf/ui/<component>/<file>.css` source paths do not exist in the published package).
16
29
 
17
30
  ```css
18
31
  @import url("tailwindcss/components.css");
19
- @import url("@uxf/ui/button/button.css");
20
- @import url("@uxf/ui/button-list/button-list.css");
21
- @import url("@uxf/ui/calendar/calendar.css");
22
- @import url("@uxf/ui/checkbox/checkbox.css");
23
- @import url("@uxf/ui/chip/chip.css");
24
- @import url("@uxf/ui/dialog/dialog.css");
25
- @import url("@uxf/ui/dropdown/dropdown.css");
26
- @import url("@uxf/ui/icon/icon.css");
27
- @import url("@uxf/ui/label/label.css");
28
- @import url("@uxf/ui/form-component/form-component.css");
29
- @import url("@uxf/ui/input/input-basic.css");
30
- @import url("@uxf/ui/input/input.css");
31
- @import url("@uxf/ui/_input-with-popover/input-with-popover.css");
32
- @import url("@uxf/ui/combobox/combobox.css");
33
- @import url("@uxf/ui/modal-header/modal-header.css");
34
- @import url("@uxf/ui/multi-select/multi-select.css");
35
- @import url("@uxf/ui/multi-combobox/multi-combobox.css");
36
- @import url("@uxf/ui/pagination/pagination.css");
37
- @import url("@uxf/ui/select/select.css");
38
- @import url("@uxf/ui/toggle/toggle.css");
39
- @import url("@uxf/ui/tabs/tabs.css");
40
-
41
- /* must be after component css files */
32
+ @import url("@uxf/ui/css/button.css");
33
+ @import url("@uxf/ui/css/button-list.css");
34
+ @import url("@uxf/ui/css/calendar.css");
35
+ @import url("@uxf/ui/css/checkbox.css");
36
+ @import url("@uxf/ui/css/chip.css");
37
+ @import url("@uxf/ui/css/dialog.css");
38
+ @import url("@uxf/ui/css/dropdown.css");
39
+ @import url("@uxf/ui/css/icon.css");
40
+ @import url("@uxf/ui/css/label.css");
41
+ @import url("@uxf/ui/css/form-component.css");
42
+ @import url("@uxf/ui/css/input-basic.css");
43
+ @import url("@uxf/ui/css/input.css");
44
+ @import url("@uxf/ui/css/input-with-popover.css");
45
+ @import url("@uxf/ui/css/combobox.css");
46
+ @import url("@uxf/ui/css/modal-header.css");
47
+ @import url("@uxf/ui/css/multi-select.css");
48
+ @import url("@uxf/ui/css/multi-combobox.css");
49
+ @import url("@uxf/ui/css/pagination.css");
50
+ @import url("@uxf/ui/css/select.css");
51
+ @import url("@uxf/ui/css/toggle.css");
52
+ @import url("@uxf/ui/css/tabs.css");
53
+
54
+ /* must be after the component css files */
42
55
  @import url("@uxf/data-grid/styles.css");
43
56
  ```
44
57
 
45
- ## State and actions of data-grid
58
+ ## Quick start
59
+
60
+ `useDataGridControl` owns grid state and actions; `useDataGridFetching` runs the loader whenever the request changes. Feed both into `DataGrid`.
61
+
62
+ ```tsx
63
+ "use client";
64
+
65
+ import { DataGrid } from "@uxf/data-grid";
66
+ import { useDataGridControl } from "@uxf/data-grid/use-data-grid-control";
67
+ import { useDataGridFetching } from "@uxf/data-grid/use-data-grid-fetching";
68
+ import { schema } from "@generated/data-grid/schema/example";
69
+
70
+ export function ExampleGrid() {
71
+ const { state, actions } = useDataGridControl({ schema });
72
+
73
+ const { isLoading, error, data, reload } = useDataGridFetching({ schema, state });
74
+
75
+ return (
76
+ <DataGrid
77
+ actions={actions}
78
+ data={data}
79
+ error={error}
80
+ isLoading={isLoading}
81
+ reload={reload}
82
+ schema={schema}
83
+ state={state}
84
+ />
85
+ );
86
+ }
87
+ ```
88
+
89
+ `useDataGridFetching` uses a default loader that calls the conventional grid endpoint. To fetch yourself, pass a `loader`:
90
+
91
+ ```tsx
92
+ const { ... } = useDataGridFetching({
93
+ schema,
94
+ state,
95
+ loader: (gridName, request, encodedRequest) => myFetch(gridName, request),
96
+ });
97
+ ```
98
+
99
+ ## Persisting user config
100
+
101
+ `useUserConfigLocalStorageAdapter` returns a `middleware` (persists column visibility, widths, order, etc. to `localStorage`) and a `useUserConfig` hook that restores it. Wire the middleware into `useDataGridControl` and call `useUserConfig(actions)`.
46
102
 
47
103
  ```tsx
48
104
  import { useDataGridControl } from "@uxf/data-grid/use-data-grid-control";
@@ -52,25 +108,55 @@ const { middleware, useUserConfig } = useUserConfigLocalStorageAdapter(schema);
52
108
 
53
109
  const { state, actions } = useDataGridControl({
54
110
  schema,
55
- initialState: "Request or string (base64 encoded request)",
56
- userConfig: {
111
+ middleware,
112
+ // optional base64-encoded request or a Request object to hydrate initial state
113
+ initialState: encodedRequest,
114
+ // optional default column config
115
+ initialUserConfig: {
57
116
  columns: {
58
117
  id: { isHidden: true },
59
- }
118
+ },
60
119
  },
61
- middleware,
62
- isDebug: true,
63
120
  });
64
121
 
65
122
  useUserConfig(actions);
66
123
  ```
67
124
 
68
- ## Row type
125
+ ## API
69
126
 
70
- Create a `column-types.d.ts` file in root of your project (next to tsconfig) and add the following:
71
- (be aware - it must be interface)
127
+ Only exports listed below are part of the public surface. Import paths resolve by filesystem (there is no `exports` map).
72
128
 
73
- ```tsx
129
+ ### Root export — `@uxf/data-grid`
130
+
131
+ | Name | Kind | Description |
132
+ | --- | --- | --- |
133
+ | `DataGrid` | component | The compound grid. Props: `DataGridProps<GridType>`. |
134
+ | `DataGridProps<GridType>` | type | Grid props = base props + control (`state`, `actions`) + data (`isLoading`, `error`, `data`, `reload`). |
135
+ | `InferDataGridRow<Schema>` | type | Derives the row shape from a schema via `ColumnTypes`. |
136
+ | `BaseGridType`, `Schema`, `ChangeTabFilterBehavior`, `DataGridActionCell`, … | types | Re-exported from `./types`. |
137
+ | `mergeSchemaWithConfig(schema, config)` | fn | Returns a new schema with a frontend config applied (see below). |
138
+ | `encodeFilter(request)` / `decodeFilter(string)` | fn | Base64 (de)serialize a grid request. |
139
+
140
+ ### Deep imports
141
+
142
+ | Import path | Export | Description |
143
+ | --- | --- | --- |
144
+ | `@uxf/data-grid/use-data-grid-control` | `useDataGridControl(config)` | Owns grid `state` + `actions`. Config: `{ schema, initialState?, initialUserConfig?, middleware? }`. |
145
+ | `@uxf/data-grid/use-data-grid-fetching` | `useDataGridFetching(config)` | Runs the loader on request changes. Config: `{ schema, state, loader?, isWithTabCounts? }`. Returns `{ isLoading, error, data, reload }`. |
146
+ | `@uxf/data-grid/user-config-storage-adapters/local-storage` | `useUserConfigLocalStorageAdapter(schema)`, `useClearLocalStorageUserConfig(schema)` | `localStorage` persistence of user column config. |
147
+ | `@uxf/data-grid/column-types` | `ColumnTypes` (interface) | Augment to register custom column value types. |
148
+
149
+ Notable optional `DataGrid` props: `actionCell`, `bodyCells`, `changeTabFilterBehavior`, `customActions`, `filterHandlers`, `fulltextInputPlaceholder`, `getCsvDownloadUrl`, `hasStickyHeader`, `isRowsSelectable`, `isRowSelectDisabled`, `isWithTabCounts`, `keyExtractor`, `rowAccent`, `rowClassName`, `rowHeight`, `tabsVariant`, `HiddenColumnsComponent`, `NoRowsFallback`, `SelectedRowsToolbarActions`, `isDebug`.
150
+
151
+ ## Column types
152
+
153
+ A column's `type` (from the schema) maps to a value type via the `ColumnTypes` interface, which drives `InferDataGridRow`. Built-in types:
154
+
155
+ `boolean`, `chip`, `chips`, `date`, `datetime`, `email`, `id`, `int`, `money`, `phone`, `string`, `url`, `uuid`.
156
+
157
+ Register a custom column type with module augmentation. Create a `column-types.d.ts` at the project root (next to `tsconfig.json`) — it **must** be an `interface`:
158
+
159
+ ```ts
74
160
  declare module "@uxf/data-grid/column-types" {
75
161
  export interface ColumnTypes {
76
162
  "my-custom-type": MyCustomType;
@@ -78,85 +164,91 @@ declare module "@uxf/data-grid/column-types" {
78
164
  }
79
165
  ```
80
166
 
81
- Then you can use it in your code:
167
+ Then infer the row type from a schema:
82
168
 
83
- ```tsx
169
+ ```ts
84
170
  import { InferDataGridRow } from "@uxf/data-grid";
85
171
  import { schema } from "@generated/data-grid/schema/example";
86
172
 
87
173
  type Row = InferDataGridRow<typeof schema>;
88
174
  ```
89
175
 
90
- ## Supported FilterHandlers
176
+ ## Filter handlers
177
+
178
+ Each filter is rendered by looking up `filterHandlers[filter.type]`. The grid uses `defaultFilterHandlers` unless you pass a `filterHandlers` prop. Built-in handler keys:
179
+
180
+ | `filter.type` | Renders |
181
+ | --- | --- |
182
+ | `checkbox` | Checkbox (value is sent only when checked) |
183
+ | `date` | Date range (from / to date pickers) |
184
+ | `datetime` | Datetime range |
185
+ | `entitySelect` | Single-select combobox (async entity) |
186
+ | `entityMultiSelect` | Multi-select combobox (async entity) |
187
+ | `interval` | Numeric range (min / max inputs) |
188
+ | `multiSelect` | Multi-select |
189
+ | `select` | Select |
190
+ | `string` | Text input |
191
+
192
+ Extend or override by merging into `defaultFilterHandlers` and passing the result as the `filterHandlers` prop:
91
193
 
92
- - `bool` - Select (yes / no / null)
93
- - `checkbox`, `boolean` - Checkbox (is sent only if checkbox is checked)
94
- - `date`
95
- - `datetime`
96
- - `entityMultiSelect`
97
- - `entitySelect`
98
- - `interval`
99
- - `multiSelect`
100
- - `select`
101
- - `string`, `text`
194
+ ```tsx
195
+ import { defaultFilterHandlers } from "@uxf/data-grid/filter-handler";
196
+
197
+ <DataGrid filterHandlers={{ ...defaultFilterHandlers, myType: myHandler }} {...rest} />;
198
+ ```
102
199
 
103
- ## Examples
200
+ ## Frontend config
104
201
 
105
- ### DataGrid
202
+ `mergeSchemaWithConfig` returns a new schema with per-column and per-filter overrides and `perPage` applied — useful for tweaking a generated schema without regenerating it.
106
203
 
107
204
  ```tsx
205
+ import { DataGrid } from "@uxf/data-grid";
206
+ import { mergeSchemaWithConfig } from "@uxf/data-grid";
108
207
  import { useDataGridControl } from "@uxf/data-grid/use-data-grid-control";
109
208
  import { useDataGridFetching } from "@uxf/data-grid/use-data-grid-fetching";
110
- import { useUserConfigLocalStorageAdapter } from "@uxf/data-grid/user-config-storage-adapters/local-storage";
209
+ import { schema as baseSchema } from "@generated/data-grid/schema/example";
111
210
 
112
- function BasicExample() {
113
- const { middleware, useUserConfig } = useUserConfigLocalStorageAdapter(schema);
114
- const { state, actions } = useDataGridControl({ schema, middleware });
115
-
116
- useUserConfig(actions);
211
+ const schema = mergeSchemaWithConfig(baseSchema, {
212
+ perPage: 100,
213
+ columns: {
214
+ id: { width: 100, isHidden: true },
215
+ },
216
+ filters: {
217
+ id: { placeholder: "Search by ID..." },
218
+ },
219
+ });
117
220
 
118
- const { isLoading, error, data, reload } = useDataGridFetching(loader, schema, "grid-name", state);
221
+ export function ConfiguredGrid() {
222
+ const { state, actions } = useDataGridControl({ schema });
223
+ const { isLoading, error, data, reload } = useDataGridFetching({ schema, state });
119
224
 
120
225
  return (
121
226
  <DataGrid
122
- reload={reload}
123
- state={state}
124
227
  actions={actions}
125
228
  data={data}
126
- isLoading={isLoading}
127
229
  error={error}
230
+ isLoading={isLoading}
231
+ reload={reload}
128
232
  schema={schema}
233
+ state={state}
129
234
  />
130
235
  );
131
236
  }
132
237
  ```
133
238
 
134
- ### FrontendConfig
239
+ ## Custom composition
135
240
 
136
- ```tsx
137
- import { useDataGridControl } from "@uxf/data-grid/use-data-grid-control";
138
- import { mergeSchemaWithConfig } from "@uxf/data-grid";
241
+ The `DataGrid` component is a fixed composition of internal parts. For a fully custom layout, import the parts individually and assemble them yourself, still driving them from `useDataGridControl` / `useDataGridFetching`:
139
242
 
140
- const schema = mergeSchemaWithConfig(
141
- dataGridSchema_ExampleGrid,
142
- {
143
- columns: {
144
- id: { width: 100, isHidden: true },
145
- },
146
- filters: {
147
- id: { placeholder: "Hledejte podle ID..." }
148
- },
149
- perPage: 100,
150
- }
151
- );
243
+ `@uxf/data-grid/root`, `@uxf/data-grid/toolbar`, `@uxf/data-grid/toolbar-tabs`, `@uxf/data-grid/toolbar-control`, `@uxf/data-grid/toolbar-customs`, `@uxf/data-grid/filter-list`, `@uxf/data-grid/table-v2`, `@uxf/data-grid/footer`, `@uxf/data-grid/pagination`, `@uxf/data-grid/row-counts`, `@uxf/data-grid/rows-per-page-select`, `@uxf/data-grid/selected-rows-toolbar`, `@uxf/data-grid/linear-progress`, `@uxf/data-grid/body-cell`, `@uxf/data-grid/filter-handler`.
152
244
 
153
- function Example_1(props) {
154
- const { state, actions } = useDataGridControl({
155
- schema,
156
- initialUserConfig: props.userConfig,
157
- })
245
+ See `data-grid.tsx` (the default composition) and `data-grid-custom-example.stories.tsx` in the package for a worked example.
158
246
 
159
- return <Table schema={schema}/>
160
- }
161
- ```
247
+ ## Gotchas
162
248
 
249
+ - **Client component only.** The hooks use React state, effects and `localStorage`. Render the grid in a client component (`"use client"`).
250
+ - **`TranslationsProvider` required.** Labels come from bundled translations via `@uxf/core-react/translations`.
251
+ - **CSS order matters.** Import `@uxf/data-grid/styles.css` after the `@uxf/ui/css/*` component styles.
252
+ - **`ColumnTypes` augmentation must be an `interface`**, not a `type`, or the declaration merge will not apply.
253
+ - **`initialState` is a base64-encoded request string** (or a `Request` object) — use `encodeFilter` / `decodeFilter` to (de)serialize, e.g. to persist the current view in the URL.
254
+ - **`isDebug` is a `DataGrid` prop**, not a `useDataGridControl` config option.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/data-grid",
3
- "version": "11.122.3",
3
+ "version": "11.122.5",
4
4
  "description": "UXF DataGrid",
5
5
  "homepage": "https://gitlab.com/uxf-npm/data-grid#readme",
6
6
  "main": "index.js",
@@ -43,9 +43,9 @@
43
43
  "@dnd-kit/utilities": "^3.2.2",
44
44
  "@uxf/core": "11.114.0",
45
45
  "@uxf/core-react": "11.122.2",
46
- "@uxf/localize": "11.122.2",
47
- "@uxf/styles": "11.114.0",
48
- "@uxf/ui": "11.122.3",
46
+ "@uxf/localize": "11.122.4",
47
+ "@uxf/styles": "11.122.4",
48
+ "@uxf/ui": "11.122.5",
49
49
  "dayjs": "^1.11.19",
50
50
  "react": ">=18.2.0",
51
51
  "react-dom": ">=18.2.0"
@@ -58,9 +58,9 @@
58
58
  "@types/react-dom": "18.3.7",
59
59
  "@uxf/core": "11.114.0",
60
60
  "@uxf/core-react": "11.122.2",
61
- "@uxf/localize": "11.122.2",
62
- "@uxf/styles": "11.114.0",
63
- "@uxf/ui": "11.122.3",
61
+ "@uxf/localize": "11.122.4",
62
+ "@uxf/styles": "11.122.4",
63
+ "@uxf/ui": "11.122.5",
64
64
  "dayjs": "^1.11.19",
65
65
  "react": "18.3.1",
66
66
  "react-dom": "18.3.1"