Skip to content

Commit 272c28d

Browse files
author
Niel Rohling
committed
add Example, documentation and do some refactorings
1 parent 957a52e commit 272c28d

File tree

4 files changed

+85
-31
lines changed

4 files changed

+85
-31
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup lang="ts">
2+
import { h } from "vue";
3+
import { OnyxDataGrid, OnyxHeadline, type ColumnConfig } from "../../../index.js";
4+
import { useExpandableRows } from "../features/all.js";
5+
6+
type TEntry = {
7+
id: number;
8+
name: string;
9+
age: number;
10+
};
11+
12+
const data: TEntry[] = [
13+
{ id: 1, name: "Alice", age: 30 },
14+
{ id: 2, name: "Charlie", age: 35 },
15+
{ id: 3, name: "Bob", age: 25 },
16+
{ id: 4, name: "Robin", age: 28 },
17+
{ id: 5, name: "John", age: 42 },
18+
];
19+
20+
const columns: ColumnConfig<TEntry>[] = [
21+
{ key: "name", label: "Name" },
22+
{ key: "age", label: "Age", type: "number" },
23+
];
24+
25+
const features = [
26+
useExpandableRows<TEntry>({
27+
detailsComponent: (row) => h(OnyxHeadline, { is: "h3" }, () => `Details for ${row.name}`),
28+
}),
29+
];
30+
</script>
31+
32+
<template>
33+
<OnyxDataGrid headline="Example headline" :columns :data :features />
34+
</template>

packages/sit-onyx/src/components/OnyxDataGrid/examples/OnyxDataGridFeatureExamples.stories.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export const Editing: Story = {
2828
...createAdvancedStoryExample("OnyxDataGrid", "EditingExample"),
2929
};
3030

31+
export const ExpandableRow: Story = {
32+
...createAdvancedStoryExample("OnyxDataGrid", "ExpandableRowExample"),
33+
};
34+
3135
export const LazyLoading: Story = {
3236
...createAdvancedStoryExample("OnyxDataGrid", "LazyLoadingExample"),
3337
};

packages/sit-onyx/src/components/OnyxDataGrid/features/expandableRows/expandableRows.ts

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { iconChevronDown, iconChevronUp } from "@sit-onyx/icons";
2-
import OnyxSystemButton from "src/components/OnyxSystemButton/OnyxSystemButton.vue";
3-
import { DataGridFeatures } from "src/index.js";
4-
import { h, ref, type Ref } from "vue";
2+
import { h, ref } from "vue";
3+
import { DataGridFeatures } from "../../../../index.js";
4+
import OnyxSystemButton from "../../../OnyxSystemButton/OnyxSystemButton.vue";
55
import { DataGridRowOptionsSymbol, type DataGridEntry } from "../../types.js";
66
import { createFeature, type DataGridFeature, type InternalColumnConfig } from "../index.js";
77
import type { UseExpandableRowsOptions } from "./types.js";
@@ -16,22 +16,28 @@ export const useExpandableRows = <TEntry extends DataGridEntry>(
1616
options: UseExpandableRowsOptions<TEntry>,
1717
) =>
1818
createFeature(() => {
19-
const expandedRows = ref<TEntry["id"][]>([]) as Ref<TEntry["id"][]>;
20-
const baseCols = ref<Readonly<InternalColumnConfig<TEntry>[]>>([]);
21-
const expandCol = {
22-
key: EXPAND_BUTTON_COLUMN,
23-
label: "",
24-
type: { name: EXPAND_BUTTON_RENDERER },
25-
width: "min-content",
19+
const columnConfig = ref<Readonly<InternalColumnConfig<TEntry>[]>>([]);
20+
21+
const expandedRows = ref<Set<PropertyKey>>(new Set());
22+
const toggleExpanded = (id: PropertyKey) => {
23+
if (expandedRows.value.has(id)) {
24+
expandedRows.value.delete(id);
25+
} else {
26+
expandedRows.value.add(id);
27+
}
2628
};
2729

30+
/**
31+
* Adds the detail row for expandedd columns
32+
*/
2833
const mapRow = (row: TEntry) => {
29-
if (!expandedRows.value.includes(row.id))
34+
if (!expandedRows.value.has(row.id))
3035
return [
36+
// don't change anything
3137
{
3238
...row,
3339
[DataGridRowOptionsSymbol]: {
34-
columns: baseCols.value,
40+
columns: columnConfig.value,
3541
},
3642
},
3743
];
@@ -40,16 +46,18 @@ export const useExpandableRows = <TEntry extends DataGridEntry>(
4046
{
4147
...row,
4248
[DataGridRowOptionsSymbol]: {
43-
columns: baseCols.value,
49+
columns: columnConfig.value,
4450
},
4551
},
52+
// add hidden row to keep striped pattern
4653
{
4754
[DataGridRowOptionsSymbol]: {
4855
trAttributes: {
4956
style: { display: "none" },
5057
},
5158
},
5259
},
60+
// add row for details
5361
{
5462
...row,
5563
id: row.id,
@@ -62,12 +70,21 @@ export const useExpandableRows = <TEntry extends DataGridEntry>(
6270

6371
return {
6472
name: EXPANDABLE_ROWS_FEATURE,
65-
watch: [expandedRows, baseCols],
73+
watch: [expandedRows, columnConfig],
6674
modifyColumns: {
6775
func: (cols) => {
68-
const config = [...cols, expandCol] as InternalColumnConfig<TEntry>[];
69-
baseCols.value = config;
76+
const config = [
77+
{
78+
key: EXPAND_BUTTON_COLUMN,
79+
label: "",
80+
type: { name: EXPAND_BUTTON_RENDERER },
81+
width: "min-content",
82+
},
83+
...cols,
84+
] as InternalColumnConfig<TEntry>[];
7085

86+
// Store the column configuration with column for expand button for later reference
87+
columnConfig.value = config;
7188
return config;
7289
},
7390
},
@@ -80,29 +97,22 @@ export const useExpandableRows = <TEntry extends DataGridEntry>(
8097
typeRenderer: {
8198
[EXPAND_BUTTON_RENDERER]: DataGridFeatures.createTypeRenderer<object, TEntry>({
8299
cell: {
83-
component: ({ row }) => {
84-
const isExpanded = expandedRows.value.includes(row.id);
85-
86-
return h(OnyxSystemButton, {
87-
icon: isExpanded ? iconChevronUp : iconChevronDown,
100+
component: ({ row }) =>
101+
h(OnyxSystemButton, {
102+
icon: expandedRows.value.has(row.id) ? iconChevronUp : iconChevronDown,
88103
label: "",
89104
onClick: () => {
90-
if (isExpanded) {
91-
expandedRows.value = expandedRows.value.filter((id) => id !== row.id);
92-
} else {
93-
expandedRows.value = [...expandedRows.value, row.id];
94-
}
105+
toggleExpanded(row.id);
95106
},
96-
});
97-
},
107+
}),
98108
},
99109
}),
100110
[DETAILS_RENDERER]: DataGridFeatures.createTypeRenderer<object, TEntry>({
101111
cell: {
102112
tdAttributes: {
103113
colspan: 99,
104114
},
105-
component: ({ row }) => options.renderDetails(row),
115+
component: ({ row }) => options.detailsComponent(row),
106116
},
107117
}),
108118
},
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
import type { h } from "vue";
1+
import type { Component } from "vue";
22

3+
/**
4+
* Options for rendering detail content for expanded rows.
5+
*/
36
export type UseExpandableRowsOptions<TEntry> = {
4-
renderDetails: (row: TEntry) => ReturnType<typeof h>;
7+
/**
8+
* Function to render the detail content.
9+
*/
10+
detailsComponent: (row: TEntry) => Component;
511
};

0 commit comments

Comments
 (0)