@alaarab/ogrid-mcp 2.5.9 → 2.6.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.
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 12
|
|
3
|
+
title: Row Grouping
|
|
4
|
+
description: Group rows by one or more columns with collapsible group headers
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Row Grouping
|
|
9
|
+
|
|
10
|
+
Group your data by one or more columns. Each group gets a collapsible header row showing the group value and item count. Multi-level grouping nests groups inside each other.
|
|
11
|
+
|
|
12
|
+
## Basic usage
|
|
13
|
+
|
|
14
|
+
Pass a `groupBy` array with the column IDs you want to group on. Groups start collapsed -- users click the header to expand.
|
|
15
|
+
|
|
16
|
+
<Tabs groupId="framework">
|
|
17
|
+
<TabItem value="react" label="React" default>
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
|
|
21
|
+
const columns = [
|
|
22
|
+
{ columnId: 'name', name: 'Name', sortable: true },
|
|
23
|
+
{ columnId: 'department', name: 'Department', sortable: true },
|
|
24
|
+
{ columnId: 'country', name: 'Country', sortable: true },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
function App() {
|
|
28
|
+
return (
|
|
29
|
+
<OGrid
|
|
30
|
+
columns={columns}
|
|
31
|
+
data={employees}
|
|
32
|
+
getRowId={(item) => item.id}
|
|
33
|
+
groupBy={['department']}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
:::tip Switching UI libraries
|
|
40
|
+
Same props across all React packages -- just change the import:
|
|
41
|
+
|
|
42
|
+
- **Radix** (lightweight, default): `from '@alaarab/ogrid-react-radix'`
|
|
43
|
+
- **Fluent UI** (Microsoft 365 / SPFx): `from '@alaarab/ogrid-react-fluent'` - wrap in `<FluentProvider>`
|
|
44
|
+
- **Material UI** (MUI v7): `from '@alaarab/ogrid-react-material'` - wrap in `<ThemeProvider>`
|
|
45
|
+
:::
|
|
46
|
+
|
|
47
|
+
</TabItem>
|
|
48
|
+
<TabItem value="angular" label="Angular">
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
|
|
52
|
+
@Component({
|
|
53
|
+
standalone: true,
|
|
54
|
+
imports: [OGridComponent],
|
|
55
|
+
template: `<ogrid [props]="gridProps" />`
|
|
56
|
+
})
|
|
57
|
+
export class GridComponent {
|
|
58
|
+
gridProps = {
|
|
59
|
+
columns: [
|
|
60
|
+
{ columnId: 'name', name: 'Name', sortable: true },
|
|
61
|
+
{ columnId: 'department', name: 'Department', sortable: true },
|
|
62
|
+
{ columnId: 'country', name: 'Country', sortable: true },
|
|
63
|
+
] as IColumnDef<Employee>[],
|
|
64
|
+
data: employees,
|
|
65
|
+
getRowId: (item: Employee) => item.id,
|
|
66
|
+
groupBy: ['department'],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
:::tip Switching UI libraries
|
|
72
|
+
Same component API across Angular packages. Change the import:
|
|
73
|
+
|
|
74
|
+
- **Radix (CDK)**: `from '@alaarab/ogrid-angular-radix'` *(default, lightweight)*
|
|
75
|
+
- **Angular Material**: `from '@alaarab/ogrid-angular-material'`
|
|
76
|
+
- **PrimeNG**: `from '@alaarab/ogrid-angular-primeng'`
|
|
77
|
+
|
|
78
|
+
All components are standalone, no NgModule required.
|
|
79
|
+
:::
|
|
80
|
+
|
|
81
|
+
</TabItem>
|
|
82
|
+
<TabItem value="vue" label="Vue">
|
|
83
|
+
|
|
84
|
+
```vue
|
|
85
|
+
<script setup lang="ts">
|
|
86
|
+
|
|
87
|
+
const columns: IColumnDef<Employee>[] = [
|
|
88
|
+
{ columnId: 'name', name: 'Name', sortable: true },
|
|
89
|
+
{ columnId: 'department', name: 'Department', sortable: true },
|
|
90
|
+
{ columnId: 'country', name: 'Country', sortable: true },
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const gridProps = {
|
|
94
|
+
columns,
|
|
95
|
+
data: employees,
|
|
96
|
+
getRowId: (item: Employee) => item.id,
|
|
97
|
+
groupBy: ['department'],
|
|
98
|
+
};
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<template>
|
|
102
|
+
<OGrid :gridProps="gridProps" />
|
|
103
|
+
</template>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
:::tip Switching UI libraries
|
|
107
|
+
Same API across Vue packages. Change the import:
|
|
108
|
+
|
|
109
|
+
- **Radix (Headless UI)**: `from '@alaarab/ogrid-vue-radix'` *(default, lightweight)*
|
|
110
|
+
- **Vuetify**: `from '@alaarab/ogrid-vue-vuetify'` - wrap in `<v-app>` for theming
|
|
111
|
+
- **PrimeVue**: `from '@alaarab/ogrid-vue-primevue'`
|
|
112
|
+
:::
|
|
113
|
+
|
|
114
|
+
</TabItem>
|
|
115
|
+
<TabItem value="js" label="Vanilla JS">
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
|
|
119
|
+
const grid = new OGrid(document.getElementById('grid'), {
|
|
120
|
+
columns: [
|
|
121
|
+
{ columnId: 'name', name: 'Name', sortable: true },
|
|
122
|
+
{ columnId: 'department', name: 'Department', sortable: true },
|
|
123
|
+
{ columnId: 'country', name: 'Country', sortable: true },
|
|
124
|
+
],
|
|
125
|
+
data: employees,
|
|
126
|
+
getRowId: (item) => item.id,
|
|
127
|
+
groupBy: ['department'],
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
</TabItem>
|
|
132
|
+
</Tabs>
|
|
133
|
+
|
|
134
|
+
## Multi-level grouping
|
|
135
|
+
|
|
136
|
+
Pass multiple column IDs to create nested groups. The first column is the top-level group, the second is nested within it, and so on.
|
|
137
|
+
|
|
138
|
+
<Tabs groupId="framework">
|
|
139
|
+
<TabItem value="react" label="React" default>
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
<OGrid
|
|
143
|
+
columns={columns}
|
|
144
|
+
data={employees}
|
|
145
|
+
getRowId={(item) => item.id}
|
|
146
|
+
groupBy={['country', 'department']}
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
</TabItem>
|
|
151
|
+
<TabItem value="angular" label="Angular">
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
gridProps = {
|
|
155
|
+
// ...columns, data, getRowId
|
|
156
|
+
groupBy: ['country', 'department'],
|
|
157
|
+
};
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
</TabItem>
|
|
161
|
+
<TabItem value="vue" label="Vue">
|
|
162
|
+
|
|
163
|
+
```vue
|
|
164
|
+
<script setup>
|
|
165
|
+
const gridProps = {
|
|
166
|
+
// ...columns, data, getRowId
|
|
167
|
+
groupBy: ['country', 'department'],
|
|
168
|
+
};
|
|
169
|
+
</script>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
</TabItem>
|
|
173
|
+
<TabItem value="js" label="Vanilla JS">
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
const grid = new OGrid(container, {
|
|
177
|
+
// ...columns, data, getRowId
|
|
178
|
+
groupBy: ['country', 'department'],
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
</TabItem>
|
|
183
|
+
</Tabs>
|
|
184
|
+
|
|
185
|
+
## Programmatic control
|
|
186
|
+
|
|
187
|
+
You can expand, collapse, and toggle groups through the API.
|
|
188
|
+
|
|
189
|
+
<Tabs groupId="framework">
|
|
190
|
+
<TabItem value="react" label="React" default>
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
|
|
194
|
+
function App() {
|
|
195
|
+
const apiRef = useRef<IOGridApi<Employee>>(null);
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<>
|
|
199
|
+
<button onClick={() => apiRef.current?.expandAllGroups()}>
|
|
200
|
+
Expand All
|
|
201
|
+
</button>
|
|
202
|
+
<button onClick={() => apiRef.current?.collapseAllGroups()}>
|
|
203
|
+
Collapse All
|
|
204
|
+
</button>
|
|
205
|
+
<OGrid
|
|
206
|
+
ref={apiRef}
|
|
207
|
+
columns={columns}
|
|
208
|
+
data={employees}
|
|
209
|
+
getRowId={(item) => item.id}
|
|
210
|
+
groupBy={['department']}
|
|
211
|
+
/>
|
|
212
|
+
</>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
</TabItem>
|
|
218
|
+
<TabItem value="angular" label="Angular">
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
@Component({
|
|
222
|
+
standalone: true,
|
|
223
|
+
imports: [OGridComponent],
|
|
224
|
+
template: `
|
|
225
|
+
<button (click)="expandAll()">Expand All</button>
|
|
226
|
+
<button (click)="collapseAll()">Collapse All</button>
|
|
227
|
+
<ogrid [props]="gridProps" />
|
|
228
|
+
`
|
|
229
|
+
})
|
|
230
|
+
export class GridComponent {
|
|
231
|
+
// Use the OGridService or template ref to access the API
|
|
232
|
+
expandAll() { /* apiRef.expandAllGroups() */ }
|
|
233
|
+
collapseAll() { /* apiRef.collapseAllGroups() */ }
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
</TabItem>
|
|
238
|
+
<TabItem value="vue" label="Vue">
|
|
239
|
+
|
|
240
|
+
```vue
|
|
241
|
+
<script setup>
|
|
242
|
+
|
|
243
|
+
const ogridRef = ref(null);
|
|
244
|
+
|
|
245
|
+
function expandAll() {
|
|
246
|
+
ogridRef.value?.api?.expandAllGroups();
|
|
247
|
+
}
|
|
248
|
+
function collapseAll() {
|
|
249
|
+
ogridRef.value?.api?.collapseAllGroups();
|
|
250
|
+
}
|
|
251
|
+
</script>
|
|
252
|
+
|
|
253
|
+
<template>
|
|
254
|
+
<button @click="expandAll">Expand All</button>
|
|
255
|
+
<button @click="collapseAll">Collapse All</button>
|
|
256
|
+
<OGrid ref="ogridRef" :gridProps="gridProps" />
|
|
257
|
+
</template>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
</TabItem>
|
|
261
|
+
<TabItem value="js" label="Vanilla JS">
|
|
262
|
+
|
|
263
|
+
```js
|
|
264
|
+
const grid = new OGrid(container, {
|
|
265
|
+
columns,
|
|
266
|
+
data: employees,
|
|
267
|
+
getRowId: (item) => item.id,
|
|
268
|
+
groupBy: ['department'],
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Expand/collapse all
|
|
272
|
+
grid.expandAllGroups();
|
|
273
|
+
grid.collapseAllGroups();
|
|
274
|
+
|
|
275
|
+
// Toggle a specific group
|
|
276
|
+
grid.toggleGroup('department::Engineering');
|
|
277
|
+
|
|
278
|
+
// Change grouping at runtime
|
|
279
|
+
grid.setGroupBy(['country', 'department']);
|
|
280
|
+
|
|
281
|
+
// Clear grouping
|
|
282
|
+
grid.setGroupBy([]);
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
</TabItem>
|
|
286
|
+
</Tabs>
|
|
287
|
+
|
|
288
|
+
## API reference
|
|
289
|
+
|
|
290
|
+
| Prop / Method | Type | Description |
|
|
291
|
+
|---|---|---|
|
|
292
|
+
| `groupBy` | `string[]` | Column IDs to group by. Order matters for nesting. |
|
|
293
|
+
| `setGroupBy(ids)` | method | Change grouping at runtime. Resets expanded state. |
|
|
294
|
+
| `toggleGroup(key)` | method | Toggle a specific group open/closed. |
|
|
295
|
+
| `expandAllGroups()` | method | Expand every group at all nesting levels. |
|
|
296
|
+
| `collapseAllGroups()` | method | Collapse every group. |
|
|
297
|
+
|
|
298
|
+
### Group key format
|
|
299
|
+
|
|
300
|
+
Group keys follow the pattern `columnId::value`. For nested groups, keys are joined with `>`:
|
|
301
|
+
|
|
302
|
+
- Single level: `department::Engineering`
|
|
303
|
+
- Nested: `country::US>department::Engineering`
|
|
304
|
+
|
|
305
|
+
## Styling
|
|
306
|
+
|
|
307
|
+
Group header rows use the `.ogrid-group-header-row` CSS class. Override the background with the `--ogrid-bg-row-group` CSS variable:
|
|
308
|
+
|
|
309
|
+
```css
|
|
310
|
+
:root {
|
|
311
|
+
--ogrid-bg-row-group: #f0f4f8;
|
|
312
|
+
}
|
|
313
|
+
```
|