diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png new file mode 100644 index 00000000000..1626f0bfd50 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png new file mode 100644 index 00000000000..c5b56b2b0c5 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png new file mode 100644 index 00000000000..2217b20d215 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png new file mode 100644 index 00000000000..5fda52e91cc Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png new file mode 100644 index 00000000000..9e95900d542 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png new file mode 100644 index 00000000000..6ef1cabff08 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png differ diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png new file mode 100644 index 00000000000..639e1b020ab Binary files /dev/null and b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png new file mode 100644 index 00000000000..a36901faeaa Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Additional_Controls.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png new file mode 100644 index 00000000000..2684b934912 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Selector.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png new file mode 100644 index 00000000000..fe992226be5 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Column_Sorting.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png new file mode 100644 index 00000000000..31721b52a4b Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Display_Selector.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png new file mode 100644 index 00000000000..6425b7e09f7 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Full_Screen_Toggle.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png new file mode 100644 index 00000000000..24a4dd7ad71 Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Keyboard_Shortcuts.png differ diff --git a/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png new file mode 100644 index 00000000000..b05d01c489b Binary files /dev/null and b/packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_Toolbar_Controls_Render_Custom_Toolbar.png differ diff --git a/packages/eui/.storybook/test.ts b/packages/eui/.storybook/test.ts new file mode 100644 index 00000000000..0cc66d08a92 --- /dev/null +++ b/packages/eui/.storybook/test.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { queries, within, waitFor, fireEvent, expect } from '@storybook/test'; +import * as dataTestSubjQueries from '../src/test/rtl/data_test_subj_queries'; + +/** + * Custom Storybook within util with EUI query helpers + * + additional chained async/waitFor component utils + * + * @see https://storybook.js.org/docs/writing-stories/play-function#writing-stories-with-the-play-function + * @see https://testing-library.com/docs/dom-testing-library/api-within/ + */ +const customWithin = (canvasElement: HTMLElement) => { + const canvas = within( + canvasElement, + { ...queries, ...dataTestSubjQueries } + ); + + return { + ...canvas, + + /** + * 1. Loki doesn't like userEvent, only fireEvent + * 2. Storybook fires fireEvents too early (esp. on page load), so we add a waitFor + */ + waitForAndClick: async (testSubject: string) => { + await waitFor(() => + expect(canvas.getByTestSubject(testSubject)).toBeInTheDocument() + ); + await fireEvent.click(canvas.getByTestSubject(testSubject)); + }, + + waitForEuiPopoverVisible: async () => + await waitFor(() => + expect(canvasElement.querySelector('[data-popover-open]')).toBeVisible() + ), + }; +}; + +export { customWithin as within }; diff --git a/packages/eui/src/components/datagrid/controls/data_grid_toolbar.stories.tsx b/packages/eui/src/components/datagrid/controls/data_grid_toolbar.stories.tsx new file mode 100644 index 00000000000..41dda210db3 --- /dev/null +++ b/packages/eui/src/components/datagrid/controls/data_grid_toolbar.stories.tsx @@ -0,0 +1,247 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { useState } from 'react'; +import { fireEvent } from '@storybook/test'; +import type { Meta, StoryObj, ReactRenderer } from '@storybook/react'; +import type { PlayFunctionContext } from '@storybook/csf'; +import { within } from '../../../../.storybook/test'; +import { LOKI_SELECTORS } from '../../../../.storybook/loki'; + +import { EuiButtonEmpty, EuiButtonIcon } from '../../button'; +import { EuiFlexGroup, EuiFlexItem } from '../../flex'; +import { EuiToolTip } from '../../tool_tip'; + +import { EuiDataGrid } from '../data_grid'; +import { EuiDataGridProps } from '../data_grid_types'; + +const meta: Meta = { + title: 'Tabular Content/EuiDataGrid/Toolbar Controls', + component: EuiDataGrid, +}; + +export default meta; +type Story = StoryObj; + +export const AdditionalControls: Story = { + parameters: { + controls: { include: ['toolbarVisibility'] }, + }, + args: { + toolbarVisibility: { + additionalControls: { + left: { + prepend: ( + + 12 results + + ), + append: ( + + Download + + ), + }, + right: ( + <> + + + + + + + + ), + }, + }, + }, + render: (args: EuiDataGridProps) => , +}; + +export const RenderCustomToolbar: Story = { + parameters: { + controls: { include: ['renderCustomToolbar'] }, + }, + args: { + renderCustomToolbar: ({ + hasRoomForGridControls, + columnControl, + columnSortingControl, + displayControl, + fullScreenControl, + keyboardShortcutsControl, + }) => { + return ( + ({ + backgroundColor: euiTheme.colors.emptyShade, + padding: euiTheme.size.xs, + border: euiTheme.border.thin, + })} + > + + + Custom left side + + + + {hasRoomForGridControls && ( + + + {columnControl} + {columnSortingControl} + + {keyboardShortcutsControl} + + {displayControl} + {fullScreenControl} + + + )} + + ); + }, + }, + render: (args: EuiDataGridProps) => , +}; + +/** + * VRT tests only + */ + +export const ColumnSelector: Story = { + tags: ['vrt-only'], + parameters: { + loki: { chromeSelector: LOKI_SELECTORS.portal }, + }, + render: () => , // Column sorting is hidden on mobile otherwise + play: async ({ canvasElement, step }: PlayFunctionContext) => { + const canvas = within(canvasElement); + + await step('Open column selector popover', async () => { + await canvas.waitForAndClick('dataGridColumnSelectorButton'); + await canvas.waitForEuiPopoverVisible(); + }); + await step('Hide all columns', async () => { + await fireEvent.click( + canvas.getByTestSubject('dataGridColumnSelectorHideAllButton') + ); + }); + }, +}; + +export const ColumnSorting: Story = { + tags: ['vrt-only'], + parameters: { + loki: { chromeSelector: LOKI_SELECTORS.portal }, + }, + render: () => , // Column sorting is hidden on mobile otherwise + play: async ({ canvasElement, step }: PlayFunctionContext) => { + const canvas = within(canvasElement); + + await step('Open column sorting and field selection popovers', async () => { + await canvas.waitForAndClick('dataGridColumnSortingButton'); + await canvas.waitForEuiPopoverVisible(); + await canvas.waitForAndClick('dataGridColumnSortingSelectionButton'); + }); + await step('Sort descending', async () => { + await canvas.waitForAndClick( + 'dataGridColumnSortingPopoverColumnSelection-Test' + ); + await fireEvent.click( + canvas.getByTestSubject('euiDataGridColumnSorting-sortColumn-Test-desc') + ); + await canvas.waitForEuiPopoverVisible(); // Without an extra wait, the screenshot diff is flaky + }); + }, +}; + +export const KeyboardShortcuts: Story = { + tags: ['vrt-only'], + parameters: { + loki: { chromeSelector: LOKI_SELECTORS.portal }, + }, + render: () => , + play: async ({ canvasElement }: PlayFunctionContext) => { + const canvas = within(canvasElement); + await canvas.waitForAndClick('dataGridKeyboardShortcutsButton'); + }, +}; + +export const DisplaySelector: Story = { + tags: ['vrt-only'], + parameters: { + loki: { chromeSelector: LOKI_SELECTORS.portal }, + }, + render: () => , + play: async ({ canvasElement, step }: PlayFunctionContext) => { + const canvas = within(canvasElement); + + await step('Open display selector popover', async () => { + await canvas.waitForAndClick('dataGridDisplaySelectorButton'); + await canvas.waitForEuiPopoverVisible(); + }); + await step('Toggle density and row height settings', async () => { + await fireEvent.click(canvas.getByTestSubject('compact')); + await fireEvent.click(canvas.getByTestSubject('lineCount')); + }); + }, +}; + +export const FullScreenToggle: Story = { + tags: ['vrt-only'], + parameters: { + loki: { chromeSelector: LOKI_SELECTORS.portal }, + }, + render: () => , + play: async ({ canvasElement }: PlayFunctionContext) => { + const canvas = within(canvasElement); + await canvas.waitForAndClick('dataGridFullScreenButton'); + }, +}; + +const StatefulDataGrid = ( + props: Partial> +) => { + const [visibleColumns, setVisibleColumns] = useState(['Test']); + const [sortingColumns, setSortingColumns] = useState([]); + + return ( + 'Test'} + rowCount={2} + columns={[{ id: 'Test' }]} + columnVisibility={{ visibleColumns, setVisibleColumns }} + sorting={{ + columns: sortingColumns, + onSort: (sortingColumns) => { + setSortingColumns(sortingColumns); + }, + }} + inMemory={{ level: 'sorting' }} + {...props} + /> + ); +};