Skip to content

Commit

Permalink
Init actions
Browse files Browse the repository at this point in the history
  • Loading branch information
fhlavac committed Sep 27, 2024
1 parent 8784729 commit 0775dd1
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/mod
import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter, EmptyStateHeader, EmptyStateIcon } from '@patternfly/react-core';
import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons';
import { BulkSelect } from '@patternfly/react-component-groups';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewToolbar, ResponsiveActions, ResponsiveAction } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks';
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
Expand All @@ -26,14 +26,25 @@ import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';

The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section.

Data view toolbar can contain a `pagination`, `bulkSelect` or any other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.
Data view toolbar can contain a `pagination`, `bulkSelect`, `actions` or other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component.

### Basic toolbar example

```js file="./DataViewToolbarExample.tsx"

```

# Toolbar actions
Data view toolbar can display actions using the `actions` property accepting a React node. You can make use of a predefined [responsive actions](/extensions/component-groups/responsive-actions) component from the [component groups](/extensions/component-groups/about-component-groups) extension.

### Actions configuration

### Actions example

```js file="./DataViewToolbarActionsExample.tsx"

```

## Data view table

The **data view table** component renders your columns and rows definition into a [table](/components/table) component.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { Pagination } from '@patternfly/react-core';
import { BulkSelect } from '@patternfly/react-component-groups';
import { DataViewToolbar, ResponsiveAction, ResponsiveActions } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';

export const BasicExample: React.FunctionComponent = () => (
<DataViewToolbar
bulkSelect={
<BulkSelect
selectedCount={0}
pageCount={5}
onSelect={() => null}
/>
}
actions={
<ResponsiveActions breakpoint="lg" ouiaId="example-actions">
<ResponsiveAction isPersistent variant="primary">Persistent action</ResponsiveAction>
<ResponsiveAction isPinned variant="secondary">Pinned Action</ResponsiveAction>
<ResponsiveAction>Tertiary Action</ResponsiveAction>
<ResponsiveAction>Link Action</ResponsiveAction>
</ResponsiveActions>
}
pagination={
<Pagination page={1} perPage={10} />
}
/>
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewTo

export const BasicExample: React.FunctionComponent = () => (
<DataViewToolbar
pagination={
<Pagination page={1} perPage={10} />
}
bulkSelect={
<BulkSelect
selectedCount={0}
pageCount={5}
onSelect={() => null}
/>
}
}
pagination={
<Pagination page={1} perPage={10} />
}
/>
)
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ This example uses the URL for persisting the pagination state.
Allows to select data records inside the data view and show the selection state.

### Toolbar usage
Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) from the [component groups](/extensions/component-groups/about-component-groups) extension.
Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) component from the [component groups](/extensions/component-groups/about-component-groups) extension.

### Selection state

Expand All @@ -84,4 +84,3 @@ The `useDataViewSelection` hook manages the selection state of the data view.
```js file="./SelectionExample.tsx"

```

4 changes: 2 additions & 2 deletions packages/module/patternfly-docs/generated/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ module.exports = {
'/extensions/data-view/components/react': {
id: "Components",
title: "Components",
toc: [{"text":"Data view toolbar"},[{"text":"Basic toolbar example"}],{"text":"Data view table"},[{"text":"Rows and columns customization"},{"text":"Tree table example"},{"text":"Empty state example"}]],
examples: ["Basic toolbar example","Rows and columns customization","Tree table example","Empty state example"],
toc: [{"text":"Data view toolbar"},[{"text":"Basic toolbar example"},{"text":"Actions configuration"},{"text":"Actions example"}],{"text":"Data view table"},[{"text":"Rows and columns customization"},{"text":"Tree table example"},{"text":"Empty state example"}]],
examples: ["Basic toolbar example","Actions example","Rows and columns customization","Tree table example","Empty state example"],
section: "extensions",
subsection: "Data view",
source: "react",
Expand Down
10 changes: 7 additions & 3 deletions packages/module/src/DataViewToolbar/DataViewToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ export interface DataViewToolbarProps extends PropsWithChildren {
actions?: React.ReactNode;
}

export const DataViewToolbar: React.FC<DataViewToolbarProps> = ({ className, ouiaId = 'DataViewToolbar', bulkSelect, actions = null, pagination, children, ...props }: DataViewToolbarProps) => (
export const DataViewToolbar: React.FC<DataViewToolbarProps> = ({ className, ouiaId = 'DataViewToolbar', bulkSelect, actions, pagination, children, ...props }: DataViewToolbarProps) => (
<Toolbar ouiaId={ouiaId} className={className} {...props}>
<ToolbarContent>
{bulkSelect && (
<ToolbarItem data-ouia-component-id={`${ouiaId}-bulk-select`}>
{bulkSelect}
</ToolbarItem>
)}
{actions}
{actions && (
<ToolbarItem variant={ToolbarItemVariant['overflow-menu']}>
{actions}
</ToolbarItem>
)}
{pagination && (
<ToolbarItem variant={ToolbarItemVariant.pagination} data-ouia-component-id={`${ouiaId}-pagination`}>
{pagination}
Expand All @@ -31,7 +35,7 @@ export const DataViewToolbar: React.FC<DataViewToolbarProps> = ({ className, oui
{children}
</ToolbarContent>
</Toolbar>
);
)

export default DataViewToolbar;

20 changes: 20 additions & 0 deletions packages/module/src/DataViewToolbar/ResponsiveAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { ButtonProps } from '@patternfly/react-core';

export interface ResponsiveActionProps extends ButtonProps {
/** Determines whether the action should be displayed next to dropdown if possible */
isPinned?: boolean;
/** Determines whether the action should always be displayed as pinned */
isPersistent?: boolean;
/** Key for the action */
key?: string;
/** Action label */
children: React.ReactNode;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const ResponsiveAction: React.FC<ResponsiveActionProps> = ({ ouiaId="ResponsiveAction", isPersistent = false, isPinned = false, label, ...props }) =>
null // this component is only used declaratively - rendering ishandled by ResponsiveActions
;

export default ResponsiveAction;
87 changes: 87 additions & 0 deletions packages/module/src/DataViewToolbar/ResponsiveActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useState } from 'react';
import { Button, Dropdown, DropdownList, MenuToggle, OverflowMenu, OverflowMenuContent, OverflowMenuControl, OverflowMenuDropdownItem, OverflowMenuGroup, OverflowMenuItem, OverflowMenuProps } from '@patternfly/react-core';
import { EllipsisVIcon } from '@patternfly/react-icons';
import { ResponsiveActionProps } from './ResponsiveAction';

export interface ResponsiveActionsProps extends Omit<OverflowMenuProps, 'ref' | 'breakpoint'> {
/** Indicates breakpoint at which to switch between horizontal menu and vertical dropdown */
breakpoint?: OverflowMenuProps['breakpoint'];
/** Custom OUIA ID */
ouiaId?: string;
/** Child actions to display */
children: React.ReactNode;
}

export const ResponsiveActions: React.FC<ResponsiveActionsProps> = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }) => {
const [ isOpen, setIsOpen ] = useState(false);

// separate persistent, pinned and collapsed actions
const persistentActions: React.ReactNode[] = [];
const pinnedActions: React.ReactNode[] = [];
const dropdownItems: React.ReactNode[] = [];

React.Children.forEach(children, (child) => {
if (React.isValidElement<ResponsiveActionProps>(child)) {
const { isPersistent, isPinned, key, children, onClick, ...actionProps } = child.props;

if (isPersistent || isPinned) {
(isPersistent ? persistentActions : pinnedActions).push(
<OverflowMenuItem key={key} isPersistent={isPersistent}>
<Button onClick={onClick} {...actionProps}>
{children}
</Button>
</OverflowMenuItem>
);
}
if (!isPersistent) {
dropdownItems.push(
<OverflowMenuDropdownItem key={key} onClick={onClick} isShared={isPinned}>
{children}
</OverflowMenuDropdownItem>
);
}
}
});

return (
<OverflowMenu breakpoint={breakpoint} data-ouia-component-id={`${ouiaId}-menu`} {...props}>
<OverflowMenuContent isPersistent data-ouia-component-id={`${ouiaId}-menu-content`}>
<OverflowMenuGroup groupType="button" data-ouia-component-id={`${ouiaId}-menu-persistent-group`} isPersistent>
{persistentActions}
</OverflowMenuGroup>
<OverflowMenuGroup groupType="button" data-ouia-component-id={`${ouiaId}-menu-pinned-group`}>
{pinnedActions}
</OverflowMenuGroup>
</OverflowMenuContent>

{dropdownItems.length > 0 && (
<OverflowMenuControl hasAdditionalOptions data-ouia-component-id={`${ouiaId}-menu-control`}>
<Dropdown
ouiaId={`${ouiaId}-menu-dropdown`}
onSelect={() => setIsOpen(false)}
toggle={(toggleRef) => (
<MenuToggle
data-ouia-component-id={`${ouiaId}-menu-dropdown-toggle`}
ref={toggleRef}
aria-label="Actions overflow menu"
variant="plain"
onClick={() => setIsOpen(!isOpen)}
isExpanded={isOpen}
>
<EllipsisVIcon />
</MenuToggle>
)}
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<DropdownList data-ouia-component-id={`${ouiaId}-menu-dropdown-list`}>
{dropdownItems}
</DropdownList>
</Dropdown>
</OverflowMenuControl>
)}
</OverflowMenu>
);
};

export default ResponsiveActions;
2 changes: 2 additions & 0 deletions packages/module/src/DataViewToolbar/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { default } from './DataViewToolbar';
export * from './DataViewToolbar';
export * from './ResponsiveActions';
export * from './ResponsiveAction';

0 comments on commit 0775dd1

Please sign in to comment.