From 0eb800a620d9a8de199e3caed73a5a480c3dd69a Mon Sep 17 00:00:00 2001 From: Alexander Melo Date: Mon, 1 May 2023 11:49:32 -0400 Subject: [PATCH] feat(Datagrid): adds FilterPanel stories (#2942) * feat(web-terminal): adds reduced motion * feat(web-terminal): adds terminal wrapper component * chore: merge main * feat(datagrid): starting to move story files * feat(datagrid): adds new stories to filter panel * chore: removed usused and comment --- .../components/Datagrid/Datagrid.stories.js | 246 +--- ...Filtering.stories.js => Flyout.stories.js} | 162 +-- .../Extensions/Filtering/Panel.stories.js | 1182 +++++++++++++++++ 3 files changed, 1248 insertions(+), 342 deletions(-) rename packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/{Filtering.stories.js => Flyout.stories.js} (72%) create mode 100644 packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Panel.stories.js diff --git a/packages/cloud-cognitive/src/components/Datagrid/Datagrid.stories.js b/packages/cloud-cognitive/src/components/Datagrid/Datagrid.stories.js index 1209d9d18e..f742688706 100644 --- a/packages/cloud-cognitive/src/components/Datagrid/Datagrid.stories.js +++ b/packages/cloud-cognitive/src/components/Datagrid/Datagrid.stories.js @@ -1,6 +1,6 @@ /* eslint-disable react-hooks/exhaustive-deps */ /** - * Copyright IBM Corp. 2022, 2022 + * Copyright IBM Corp. 2022, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -25,10 +25,8 @@ import { useSelectRows, useSortableColumns, useStickyColumn, - useFiltering, getAutoSizedColumnWidth, } from '.'; -import { StatusIcon } from '../StatusIcon'; import mdx from './Datagrid.mdx'; import { SelectAllWithToggle } from './Datagrid.stories/index'; import { DatagridActions } from './utils/DatagridActions'; @@ -446,248 +444,6 @@ export const SelectItemsInAllPages = () => { }; SelectItemsInAllPages.story = SelectAllWithToggle; -export const FilterPanel = () => { - const headers = [ - { - Header: 'First Name', - accessor: 'firstName', - }, - { - Header: 'Last Name', - accessor: 'lastName', - }, - { - Header: 'Age', - accessor: 'age', - }, - { - Header: 'Visits', - accessor: 'visits', - filter: 'number', - }, - { - Header: 'Status', - accessor: 'status', - }, - // Shows the date filter example - { - Header: 'Joined', - accessor: 'joined', - filter: 'date', - Cell: ({ cell: { value } }) => {value.toLocaleDateString()}, - }, - // Shows the checkbox filter example - { - Header: 'Password strength', - accessor: 'passwordStrength', - width: 200, - filter: 'checkbox', - Cell: ({ cell: { value } }) => { - const iconProps = { - size: 'sm', - theme: 'light', - kind: value, - iconDescription: value, - }; - - return ( - - - {iconProps.iconDescription} - - ); - }, - }, - // Shows the checkbox filter example - { - Header: 'Role', - accessor: 'role', - }, - ]; - - const columns = React.useMemo(() => headers, []); - const [data] = useState(makeData(50)); - const [isPanelOpen, setIsPanelOpen] = useState(false); - - const sections = [ - { - categoryTitle: 'Category title', - hasAccordion: true, - filters: [ - { - filterLabel: 'Joined', - filter: { - type: 'date', - column: 'joined', - props: { - DatePicker: { - datePickerType: 'range', - }, - DatePickerInput: { - start: { - id: 'date-picker-input-id-start', - placeholder: 'mm/dd/yyyy', - labelText: 'Joined start date', - }, - end: { - id: 'date-picker-input-id-end', - placeholder: 'mm/dd/yyyy', - labelText: 'Joined end date', - }, - }, - }, - }, - }, - { - filterLabel: 'Status', - filter: { - type: 'dropdown', - column: 'status', - props: { - Dropdown: { - id: 'marital-status-dropdown', - ariaLabel: 'Marital status dropdown', - items: ['relationship', 'complicated', 'single'], - label: 'Marital status', - titleText: 'Marital status', - }, - }, - }, - }, - ], - }, - { - categoryTitle: 'Category title', - filters: [ - { - filterLabel: 'Role', - filter: { - type: 'radio', - column: 'role', - props: { - FormGroup: { - legendText: 'Role', - }, - RadioButtonGroup: { - orientation: 'vertical', - legend: 'Role legend', - name: 'role-radio-button-group', - }, - RadioButton: [ - { - id: 'developer', - labelText: 'Developer', - value: 'developer', - }, - { - id: 'designer', - labelText: 'Designer', - value: 'designer', - }, - { - id: 'researcher', - labelText: 'Researcher', - value: 'researcher', - }, - ], - }, - }, - }, - { - filterLabel: 'Visits', - filter: { - type: 'number', - column: 'visits', - props: { - NumberInput: { - min: 0, - id: 'visits-number-input', - invalidText: 'A valid value is required', - label: 'Visits', - placeholder: 'Type a number amount of visits', - }, - }, - }, - }, - { - filterLabel: 'Password strength', - filter: { - type: 'checkbox', - column: 'passwordStrength', - props: { - FormGroup: { - legendText: 'Password strength', - }, - Checkbox: [ - { - id: 'normal', - labelText: 'Normal', - value: 'normal', - }, - { - id: 'minor-warning', - labelText: 'Minor warning', - value: 'minor-warning', - }, - { - id: 'critical', - labelText: 'Critical', - value: 'critical', - }, - ], - }, - }, - }, - ], - }, - ]; - - const datagridState = useDatagrid( - { - filterProps: { - variation: 'panel', - updateMethod: 'batch', - primaryActionLabel: 'Apply', - secondaryActionLabel: 'Cancel', - panelIconDescription: `${isPanelOpen ? 'Close' : 'Open'} filters`, - closeIconDescription: 'Close panel', - sections, - onPanelOpen: (open) => { - setIsPanelOpen(open); - action('onPanelOpen'); - }, - onPanelClose: (open) => { - setIsPanelOpen(open); - action('onPanelClose'); - }, - panelTitle: 'Filter', - }, - columns, - data, - emptyStateTitle: 'No filters match', - emptyStateDescription: - 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', - DatagridActions, - DatagridBatchActions, - batchActions: true, - toolbarBatchActions: getBatchActions(), - }, - useFiltering - ); - - return ( - - - - ); -}; - const DatagridBatchActions = (datagridState) => { const { selectedFlatRows, toggleAllRowsSelected } = datagridState; const totalSelected = selectedFlatRows && selectedFlatRows.length; diff --git a/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Filtering.stories.js b/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Flyout.stories.js similarity index 72% rename from packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Filtering.stories.js rename to packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Flyout.stories.js index 43e2dc9935..e50a9c2bbe 100644 --- a/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Filtering.stories.js +++ b/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Flyout.stories.js @@ -1,6 +1,6 @@ /* eslint-disable react-hooks/exhaustive-deps */ /** - * Copyright IBM Corp. 2022, 2022 + * Copyright IBM Corp. 2022, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -22,7 +22,7 @@ import { DatagridActions } from '../../utils/DatagridActions'; import { StatusIcon } from '../../../StatusIcon'; export default { - title: `${getStoryTitle(Datagrid.displayName)}/Extensions/Filtering`, + title: `${getStoryTitle(Datagrid.displayName)}/Extensions/Filtering/Flyout`, component: Datagrid, parameters: { styles, @@ -30,38 +30,6 @@ export default { }, }; -const initialFilters = [ - { - id: 'passwordStrength', - type: 'checkbox', - value: [ - { - id: 'normal', - labelText: 'Normal', - value: 'normal', - selected: true, - }, - { - id: 'minor-warning', - labelText: 'Minor warning', - value: 'minor-warning', - selected: false, - }, - { - id: 'critical', - labelText: 'Critical', - value: 'critical', - selected: false, - }, - ], - }, - { - id: 'role', - type: 'radio', - value: 'developer', - }, -]; - const getBatchActions = () => { return [ { @@ -189,6 +157,7 @@ const FilteringUsage = ({ defaultGridProps }) => { { columns, data, + initialState, DatagridActions, batchActions: true, toolbarBatchActions: getBatchActions(), @@ -198,7 +167,6 @@ const FilteringUsage = ({ defaultGridProps }) => { useDenseHeader, emptyStateTitle, emptyStateDescription, - initialState, }, useFiltering ); @@ -317,8 +285,8 @@ const filters = [ }, ]; -export const FilteringUsageStory = prepareStory(FilteringTemplateWrapper, { - storyName: 'Filter flyout - batch', +export const FlyoutBatch = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter flyout with batch update', argTypes: { gridTitle: ARG_TYPES.gridTitle, gridDescription: ARG_TYPES.gridDescription, @@ -345,67 +313,67 @@ export const FilteringUsageStory = prepareStory(FilteringTemplateWrapper, { }, }); -export const FilteringInstantUsageStory = prepareStory( - FilteringTemplateWrapper, - { - storyName: 'Filter flyout - instant', - argTypes: { - gridTitle: ARG_TYPES.gridTitle, - gridDescription: ARG_TYPES.gridDescription, - useDenseHeader: ARG_TYPES.useDenseHeader, - filterProps: ARG_TYPES.filterProps, - }, - args: { - gridTitle: 'Data table title', - gridDescription: 'Additional information if needed', - useDenseHeader: false, - emptyStateTitle: 'No filters match', - emptyStateDescription: - 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', - filterProps: { - variation: 'flyout', - updateMethod: 'instant', - primaryActionLabel: 'Apply', - secondaryActionLabel: 'Cancel', - flyoutIconDescription: 'Open filters', - onFlyoutOpen: action('onFlyoutOpen'), - onFlyoutClose: action('onFlyoutClose'), - filters, - }, +export const FlyoutInstant = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter flyout with instant update', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'flyout', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + flyoutIconDescription: 'Open filters', + onFlyoutOpen: action('onFlyoutOpen'), + onFlyoutClose: action('onFlyoutClose'), + filters, }, - } -); + }, +}); -export const FilteringInitialFiltersUsageStory = prepareStory( - FilteringTemplateWrapper, - { - storyName: 'Filter flyout - with initial filters', - argTypes: { - gridTitle: ARG_TYPES.gridTitle, - gridDescription: ARG_TYPES.gridDescription, - useDenseHeader: ARG_TYPES.useDenseHeader, - filterProps: ARG_TYPES.filterProps, +export const FlyoutWithInitialFilters = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter flyout with initial filters', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + initialState: { + filters: [ + { + id: 'role', + type: 'radio', + value: 'developer', + }, + ], }, - args: { - initialState: { - filters: initialFilters, - }, - gridTitle: 'Data table title', - gridDescription: 'Additional information if needed', - useDenseHeader: false, - emptyStateTitle: 'No filters match', - emptyStateDescription: - 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', - filterProps: { - variation: 'flyout', - updateMethod: 'instant', - primaryActionLabel: 'Apply', - secondaryActionLabel: 'Cancel', - flyoutIconDescription: 'Open filters', - onFlyoutOpen: action('onFlyoutOpen'), - onFlyoutClose: action('onFlyoutClose'), - filters, - }, + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'flyout', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + flyoutIconDescription: 'Open filters', + onFlyoutOpen: action('onFlyoutOpen'), + onFlyoutClose: action('onFlyoutClose'), + filters, }, - } -); + }, +}); diff --git a/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Panel.stories.js b/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Panel.stories.js new file mode 100644 index 0000000000..e6d5da1a65 --- /dev/null +++ b/packages/cloud-cognitive/src/components/Datagrid/Extensions/Filtering/Panel.stories.js @@ -0,0 +1,1182 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +/** + * Copyright IBM Corp. 2022, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { useState } from 'react'; +import { Add16 } from '@carbon/icons-react'; +import { action } from '@storybook/addon-actions'; +import { + getStoryTitle, + prepareStory, +} from '../../../../global/js/utils/story-helper'; +import { Datagrid, useDatagrid, useFiltering } from '../../index'; +import styles from '../../_storybook-styles.scss'; +import mdx from '../../Datagrid.mdx'; +import { makeData } from '../../utils/makeData'; +import { ARG_TYPES } from '../../utils/getArgTypes'; +import { DatagridActions } from '../../utils/DatagridActions'; +import { StatusIcon } from '../../../StatusIcon'; + +export default { + title: `${getStoryTitle(Datagrid.displayName)}/Extensions/Filtering/Panel`, + component: Datagrid, + parameters: { + styles, + docs: { page: mdx }, + }, +}; + +const getBatchActions = () => { + return [ + { + label: 'Duplicate', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + }, + { + label: 'Add', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + }, + { + label: 'Select all', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + type: 'select_all', + }, + { + label: 'Publish to catalog', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + }, + { + label: 'Download', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + }, + { + label: 'Delete', + renderIcon: Add16, + onClick: action('Clicked batch action button'), + hasDivider: true, + kind: 'danger', + }, + ]; +}; + +const FilteringUsage = ({ defaultGridProps }) => { + const { + gridDescription, + gridTitle, + useDenseHeader, + filterProps, + emptyStateTitle, + emptyStateDescription, + initialState, + data: initialData, + } = defaultGridProps; + + const headers = [ + { + Header: 'Row Index', + accessor: (row, i) => i, + sticky: 'left', + id: 'rowIndex', // id is required when accessor is a function. + }, + { + Header: 'First Name', + accessor: 'firstName', + }, + { + Header: 'Last Name', + accessor: 'lastName', + }, + { + Header: 'Age', + accessor: 'age', + width: 50, + }, + { + Header: 'Visits', + accessor: 'visits', + filter: 'number', + width: 60, + }, + { + Header: 'Status', + accessor: 'status', + }, + // Shows the date filter example + { + Header: 'Joined', + accessor: 'joined', + filter: 'date', + Cell: ({ cell: { value } }) => {value.toLocaleDateString()}, + }, + // Shows the checkbox filter example + { + Header: 'Password strength', + accessor: 'passwordStrength', + filter: 'checkbox', + Cell: ({ cell: { value } }) => { + const iconProps = { + size: 'sm', + theme: 'light', + kind: value, + iconDescription: value, + }; + + return ( + + + {iconProps.iconDescription} + + ); + }, + }, + // Shows the checkbox filter example + { + Header: 'Role', + accessor: 'role', + }, + ]; + + const columns = React.useMemo(() => headers, []); + const [data] = useState(initialData ?? makeData(20)); + + const datagridState = useDatagrid( + { + columns, + data, + initialState, + DatagridActions, + batchActions: true, + toolbarBatchActions: getBatchActions(), + filterProps, + gridTitle, + gridDescription, + useDenseHeader, + emptyStateTitle, + emptyStateDescription, + }, + useFiltering + ); + + return ; +}; + +const FilteringTemplateWrapper = ({ ...args }) => { + return ; +}; + +export const PanelBatch = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel with batch update', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'panel', + updateMethod: 'batch', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +}); + +export const PanelInstant = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel with instant update', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'panel', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +}); + +export const PanelWithInitialFilters = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel with initial filters', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + initialState: { + filters: [ + { + id: 'role', + type: 'radio', + value: 'developer', + }, + { + id: 'passwordStrength', + type: 'checkbox', + value: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + selected: false, + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + selected: true, + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + selected: false, + }, + ], + }, + ], + }, + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'panel', + updateMethod: 'batch', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +}); + +export const PanelOnlyAccordions = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel only accordions', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'panel', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +}); + +export const PanelNoAccordions = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel no accordions', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No filters match', + emptyStateDescription: + 'Data was not found with the current filters applied. Change filters or clear filters to see other results.', + filterProps: { + variation: 'panel', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: false, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + hasAccordion: false, + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +}); + +export const PanelNoData = prepareStory(FilteringTemplateWrapper, { + storyName: 'Filter panel no data (disabled)', + argTypes: { + gridTitle: ARG_TYPES.gridTitle, + gridDescription: ARG_TYPES.gridDescription, + useDenseHeader: ARG_TYPES.useDenseHeader, + filterProps: ARG_TYPES.filterProps, + }, + args: { + data: [], + gridTitle: 'Data table title', + gridDescription: 'Additional information if needed', + useDenseHeader: false, + emptyStateTitle: 'No data', + emptyStateDescription: 'There is no data to show 🤠', + filterProps: { + variation: 'panel', + updateMethod: 'instant', + primaryActionLabel: 'Apply', + secondaryActionLabel: 'Cancel', + panelIconDescription: `Open filters`, + closeIconDescription: 'Close panel', + sections: [ + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Joined', + filter: { + type: 'date', + column: 'joined', + props: { + DatePicker: { + datePickerType: 'range', + }, + DatePickerInput: { + start: { + id: 'date-picker-input-id-start', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined start date', + }, + end: { + id: 'date-picker-input-id-end', + placeholder: 'mm/dd/yyyy', + labelText: 'Joined end date', + }, + }, + }, + }, + }, + { + filterLabel: 'Status', + filter: { + type: 'dropdown', + column: 'status', + props: { + Dropdown: { + id: 'marital-status-dropdown', + ariaLabel: 'Marital status dropdown', + items: ['relationship', 'complicated', 'single'], + label: 'Marital status', + titleText: 'Marital status', + }, + }, + }, + }, + ], + }, + { + categoryTitle: 'Category title', + hasAccordion: true, + filters: [ + { + filterLabel: 'Role', + filter: { + type: 'radio', + column: 'role', + props: { + FormGroup: { + legendText: 'Role', + }, + RadioButtonGroup: { + orientation: 'vertical', + legend: 'Role legend', + name: 'role-radio-button-group', + }, + RadioButton: [ + { + id: 'developer', + labelText: 'Developer', + value: 'developer', + }, + { + id: 'designer', + labelText: 'Designer', + value: 'designer', + }, + { + id: 'researcher', + labelText: 'Researcher', + value: 'researcher', + }, + ], + }, + }, + }, + { + filterLabel: 'Visits', + filter: { + type: 'number', + column: 'visits', + props: { + NumberInput: { + min: 0, + id: 'visits-number-input', + invalidText: 'A valid value is required', + label: 'Visits', + placeholder: 'Type a number amount of visits', + }, + }, + }, + }, + { + filterLabel: 'Password strength', + filter: { + type: 'checkbox', + column: 'passwordStrength', + props: { + FormGroup: { + legendText: 'Password strength', + }, + Checkbox: [ + { + id: 'normal', + labelText: 'Normal', + value: 'normal', + }, + { + id: 'minor-warning', + labelText: 'Minor warning', + value: 'minor-warning', + }, + { + id: 'critical', + labelText: 'Critical', + value: 'critical', + }, + ], + }, + }, + }, + ], + }, + ], + onPanelOpen: action('onPanelOpen'), + onPanelClose: action('onPanelClose'), + panelTitle: 'Filter', + }, + }, +});