diff --git a/docs/ux/datagrid.md b/docs/ux/datagrid.md index 6baf997d34..9aab8180aa 100644 --- a/docs/ux/datagrid.md +++ b/docs/ux/datagrid.md @@ -40,9 +40,8 @@ More specifically, these are any combination of the following elements. Each ele (TODO: Illustration of the fully featured header with overlayed/indicated zones) -### Zone 1: Bulk Actions, Sorting, Action(s) +### Zone 1: Sorting, Action(s) -- Bulk Actions: Actions that can be run on multiple items in the DataGrid at once. Contains a Checkbox to select/deselect all items, and requires a Checkbox on each individual item / row. - Sorting: Select to choose what to sort by, and a button to toggle sort direction - Other Actions Overflow Menu: Any actions global to the data set other than the primary action - Primary Action: The primary, i.e. most likely action for users. If users can create new items in the DataGrid, this can be done using the primary action button @@ -53,10 +52,11 @@ More specifically, these are any combination of the following elements. Each ele - Search: A SearchBox to perform a string-based search on the data and display the matching items. Make sure to manage user expectations as to what exactly will be searched, i.e. if the string entered is only matched against a single or a subset of fields, the placeholder should indicate that (e.g. "Search Description" if only descriptions can be searched) - Filter Pills: Each filter that has been configured by the user using the Filter element(s) and that is currently active is displayed here. As a last item, there is a button that allows for clearing all active filters at once. -### Zone 3: DataGrid View/State, Refresh +### Zone 3: DataGrid View/State, Bulk Actions, Refresh -- Item Count: The number of items of the set that is currently visible as a whole (not only on the current page). If filters or searches are active, the number of matching items and the total number of items in the data set is being displayed. -- Last Update, Update/Refresh: The date and time of the last refresh of the data displayed, and a button to trigger a refresh. +- Bulk Actions: Actions that can be run on multiple items in the DataGrid at once. Positioned on the left side of Zone 3. Contains a Checkbox to select/deselect all items, and a menu of available bulk actions. Requires a Checkbox on each individual item / row. Bulk action controls should be disabled until at least one item is selected. The select-all checkbox follows a tri-state model: unchecked when no items are selected, indeterminate when some are, and checked when all are. Clicking the checkbox in the unchecked or indeterminate state selects all items; clicking it in the checked state deselects all. +- Item Count: The number of items of the set that is currently visible as a whole (not only on the current page), displayed in the center. If filters or searches are active, the number of matching items and the total number of items in the data set is being displayed. +- Last Update, Update/Refresh: The date and time of the last refresh of the data displayed, and a button to trigger a refresh. Positioned on the right side of Zone 3. All of the above elements are optional in the sense that none of them will be required for any given DataGrid. However, if you find yourself in a situation where none of the above options is needed or desired, reconsider whether using a DataGrid is the right choice to display the given data. This case can occur, but it is rare. In most cases a simple list is then a more appropriate option to display the data. diff --git a/packages/ui-components/src/components/Button/Button.component.tsx b/packages/ui-components/src/components/Button/Button.component.tsx index 03338bc55f..2ee6d9a8a8 100644 --- a/packages/ui-components/src/components/Button/Button.component.tsx +++ b/packages/ui-components/src/components/Button/Button.component.tsx @@ -22,7 +22,6 @@ const btnBase = ` jn:justify-center jn:items-center jn:rounded - jn:shadow-sm jn:w-auto jn:focus:outline-hidden jn:focus-visible:ring-2 diff --git a/packages/ui-components/src/components/DataGrid/DataGridHeader.stories.tsx b/packages/ui-components/src/components/DataGrid/DataGridHeader.stories.tsx new file mode 100644 index 0000000000..f765aad21e --- /dev/null +++ b/packages/ui-components/src/components/DataGrid/DataGridHeader.stories.tsx @@ -0,0 +1,383 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react-vite" +import { DataGrid } from "./DataGrid.component" +import { DataGridRow } from "../DataGridRow" +import { DataGridCell } from "../DataGridCell" +import { DataGridHeadCell } from "../DataGridHeadCell" +import { DataGridCheckboxCell } from "../DataGridCheckboxCell" +import { DataGridToolbar } from "../DataGridToolbar" +import { Stack } from "../Stack" +import { Button } from "../Button" +import { Checkbox } from "../Checkbox" +import { Select } from "../Select" +import { SelectOption } from "../SelectOption" +import { SortButton } from "../SortButton" +import { PopupMenu, PopupMenuOptions, PopupMenuItem, PopupMenuToggle } from "../PopupMenu" +import { InputGroup } from "../InputGroup" +import { ComboBox } from "../ComboBox" +import { ComboBoxOption } from "../ComboBoxOption" +import { SearchInput } from "../SearchInput" +import { Pill } from "../Pill" +import { PortalProvider } from "../PortalProvider" + +const meta: Meta = { + title: "Components/DataGrid/DataGrid Header", + decorators: [ + (Story) => ( + + + + ), + ], + parameters: { + docs: { + description: { + component: ` +The DataGrid header is a composition pattern, not a single component. It sits above the column headers and holds everything users need to interact with and configure the dataset. + +The header is structured in up to three zones: + +- **Zone 1 — Actions:** Sorting controls, an optional overflow menu for global actions, and the primary action (e.g. "Create"). This zone has no background — it is a plain \`Stack\` with no wrapper component. +- **Zone 2 — Filters and Search:** One or more filter inputs (typically a \`Select\` + \`ComboBox\` in an \`InputGroup\`), a \`SearchInput\`, and active filter pills with a "Clear filters" button. +- **Zone 3 — DataGrid State:** Bulk actions (select-all checkbox + action menu) on the left, item count in the middle (total, or "X of Y" when filters are active), and last update timestamp with a refresh button on the right. + +Zones 2 and 3 each use their own \`DataGridToolbar\`, which provides the background, padding, and separation from the grid. + +Every zone and every element within a zone is optional. Only include what the specific DataGrid needs. If none of the above is needed, reconsider whether a DataGrid is the right pattern at all. + `, + }, + }, + }, +} + +export default meta +type Story = StoryObj + +const servers = [ + { id: "1", name: "node-prod-01", region: "eu-west-1", status: "Running", az: "AZ-1" }, + { id: "2", name: "node-prod-02", region: "eu-west-1", status: "Stopped", az: "AZ-2" }, + { id: "3", name: "node-staging-01", region: "us-east-1", status: "Running", az: "AZ-1" }, + { id: "4", name: "node-dev-01", region: "ap-south-1", status: "Error", az: "AZ-3" }, +] + +export const WithPrimaryAction: Story = { + render: () => ( + +