From be22b0070e2375e6f486f88bf6a96b417c6c35d1 Mon Sep 17 00:00:00 2001 From: Maja Zarkova <60856270+MajaZarkova@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:22:00 +0200 Subject: [PATCH] feat(OnyxDataGrid): implement OnyxDataGrid column action (#2259) Relates to #1939 DataGridFeature type is extended to support listItems which are rendered as a flyout right next to the header ## Checklist - [x] The added / edited code has been documented with [JSDoc](https://jsdoc.app/about-getting-started) - [x] All changes are documented in the documentation app (folder `apps/docs`) - [x] A changeset is added with `npx changeset add` if your changes should be released as npm package (because they affect the library usage) --- .changeset/thin-toys-collect.md | 5 ++ .../OnyxDataGrid/OnyxDataGrid.stories.ts | 52 +++++++++++++++++++ .../components/OnyxDataGrid/features/index.ts | 46 ++++++++++++++-- packages/sit-onyx/src/i18n/locales/de-DE.json | 4 +- packages/sit-onyx/src/i18n/locales/en-US.json | 4 +- 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 .changeset/thin-toys-collect.md diff --git a/.changeset/thin-toys-collect.md b/.changeset/thin-toys-collect.md new file mode 100644 index 0000000000..b30d66a21d --- /dev/null +++ b/.changeset/thin-toys-collect.md @@ -0,0 +1,5 @@ +--- +"sit-onyx": minor +--- + +feat(OnyxDataGrid): DataGridFeature type is extended to support listItems which are rendered as a flyout right next to the header diff --git a/packages/sit-onyx/src/components/OnyxDataGrid/OnyxDataGrid.stories.ts b/packages/sit-onyx/src/components/OnyxDataGrid/OnyxDataGrid.stories.ts index cd908a60e9..2f1a79e1f6 100644 --- a/packages/sit-onyx/src/components/OnyxDataGrid/OnyxDataGrid.stories.ts +++ b/packages/sit-onyx/src/components/OnyxDataGrid/OnyxDataGrid.stories.ts @@ -1,4 +1,8 @@ +import sort from "@sit-onyx/icons/sort.svg?raw"; import type { Meta, StoryObj } from "@storybook/vue3"; +import { h } from "vue"; +import OnyxIconButton from "../OnyxIconButton/OnyxIconButton.vue"; +import OnyxListItem from "../OnyxListItem/OnyxListItem.vue"; import OnyxDataGrid from "./OnyxDataGrid.vue"; /** @@ -23,3 +27,51 @@ export const Default = { ], }, } satisfies Story; + +export const MoreActions = { + args: { + columns: ["name", "age", "birthday"], + features: [ + { + name: Symbol("More actions"), + watch: [], + header: { + actions: (column) => + column === "name" + ? [ + { + iconComponent: h(OnyxIconButton, { + label: "Sort options", + icon: sort, + color: "neutral", + }), + listItems: [ + h(OnyxListItem, () => "No sorting"), + h(OnyxListItem, () => "Random sort"), + ], + }, + { + iconComponent: h(OnyxIconButton, { + label: "Sort options", + icon: sort, + color: "neutral", + }), + listItems: [ + h(OnyxListItem, () => "Sort ascending"), + h(OnyxListItem, () => "Sort descending"), + ], + }, + ] + : [], + }, + }, + ], + data: [ + { id: 1, name: "Alice", age: 30, birthday: new Date("1990-01-01") }, + { id: 2, name: "Charlie", age: 35, birthday: new Date("1998-02-11") }, + { id: 3, name: "Bob", age: 25, birthday: new Date("1995-06-15") }, + { id: 4, name: "John", age: 28, birthday: new Date("2003-04-10") }, + { id: 5, name: "Charlotte", age: 28, birthday: new Date("2000-11-08") }, + ], + }, +} satisfies Story; diff --git a/packages/sit-onyx/src/components/OnyxDataGrid/features/index.ts b/packages/sit-onyx/src/components/OnyxDataGrid/features/index.ts index 7689d24f89..a8485ce5c8 100644 --- a/packages/sit-onyx/src/components/OnyxDataGrid/features/index.ts +++ b/packages/sit-onyx/src/components/OnyxDataGrid/features/index.ts @@ -1,4 +1,10 @@ -import { h, type Component, type WatchSource } from "vue"; +import moreHorizontal from "@sit-onyx/icons/more-horizontal.svg?raw"; +import { h, type Component, type ComponentInstance, type WatchSource } from "vue"; +import type { ComponentSlots } from "vue-component-type-helpers"; +import { injectI18n } from "../../../i18n"; +import OnyxIconButton from "../../OnyxIconButton/OnyxIconButton.vue"; +import OnyxListItem from "../../OnyxListItem/OnyxListItem.vue"; +import OnyxFlyoutMenu from "../../OnyxNavBar/modules/OnyxFlyoutMenu/OnyxFlyoutMenu.vue"; import type { DataGridRendererColumn, DataGridRendererRow } from "../OnyxDataGridRenderer/types"; import type { DataGridEntry, DataGridMetadata } from "../types"; import HeaderCell from "./HeaderCell.vue"; @@ -32,7 +38,7 @@ export type DataGridFeature { iconComponent: Component; - listComponent?: never; + listItems?: ComponentInstance[]; }[]; }; }; @@ -117,13 +123,45 @@ export const useDataGridFeatures = < .filter((actions) => !!actions); return columns.map((column) => { - const iconActions = headerActions + const actions = headerActions.flatMap((actionFactory) => actionFactory(column)); + + if (actions.length > 1) { + const { t } = injectI18n(); + const listItems = headerActions + .flatMap((actionFactory) => actionFactory(column)) + .map(({ listItems }) => listItems); + + const flyoutMenu = h( + OnyxFlyoutMenu, + { + label: t.value("navigation.moreActionsFlyout", { column: column as string }), + }, + { + button: ({ trigger }) => + h(OnyxIconButton, { + label: t.value("navigation.moreActionsTrigger"), + color: "neutral", + icon: moreHorizontal, + ...trigger, + }), + options: () => listItems, + } satisfies ComponentSlots, + ); + + return { + key: column, + component: () => h(HeaderCell, { label: String(column) }, { actions: () => flyoutMenu }), + props: {}, + }; + } + + const iconComponent = headerActions .flatMap((actionFactory) => actionFactory(column)) .map(({ iconComponent }) => iconComponent); return { key: column, - component: () => h(HeaderCell, { label: String(column) }, { actions: iconActions }), + component: () => h(HeaderCell, { label: String(column) }, { actions: () => iconComponent }), props: {}, }; }); diff --git a/packages/sit-onyx/src/i18n/locales/de-DE.json b/packages/sit-onyx/src/i18n/locales/de-DE.json index ac6322b904..e84b2ba371 100644 --- a/packages/sit-onyx/src/i18n/locales/de-DE.json +++ b/packages/sit-onyx/src/i18n/locales/de-DE.json @@ -90,7 +90,9 @@ "userMenuLabel": "Benutzeroptionen", "toggleBurgerMenu": "Burger-Menü umschalten", "toggleContextMenu": "Kontext-Menü umschalten", - "navigationHeadline": "Navigation" + "navigationHeadline": "Navigation", + "moreActionsFlyout": "Wähle eine Aktion für die Spalte \"{column}\"", + "moreActionsTrigger": "Spaltenaktionen umschalten" }, "tooltip": { "neutral": "Info-Tooltip Sichtbarkeit umschalten", diff --git a/packages/sit-onyx/src/i18n/locales/en-US.json b/packages/sit-onyx/src/i18n/locales/en-US.json index dba97a7a74..d3eaad2fbe 100644 --- a/packages/sit-onyx/src/i18n/locales/en-US.json +++ b/packages/sit-onyx/src/i18n/locales/en-US.json @@ -99,7 +99,9 @@ "userMenuLabel": "User options", "toggleBurgerMenu": "Toggle burger menu", "toggleContextMenu": "Toggle context menu", - "navigationHeadline": "Navigation" + "navigationHeadline": "Navigation", + "moreActionsFlyout": "Choose an action for the column \"{column}\"", + "moreActionsTrigger": "Toggle column actions" }, "tooltip": { "neutral": "Toggle info tooltip",