From 6dea7aad237dcbed8480c05ffb2583598b3b7eac Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 22 Jun 2022 16:09:06 -0400 Subject: [PATCH 1/5] chore(docs): create composable structure template --- .../examples/MultipleFileUpload.md | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md index 7cb7f50fa3d..00c027cc2ea 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md @@ -3,12 +3,7 @@ id: File upload - multiple section: components cssPrefix: pf-c-multiple-file-upload propComponents: - [ - 'MultipleFileUpload', - 'MultipleFileUploadMain', - 'MultipleFileUploadStatus', - 'MultipleFileUploadStatusItem', - ] + ['MultipleFileUpload', 'MultipleFileUploadMain', 'MultipleFileUploadStatus', 'MultipleFileUploadStatusItem'] beta: true --- @@ -31,6 +26,24 @@ As with singular file upload, any [props accepted by react-dropzone's Dropzone c Restricting file sizes and types in this way is for user convenience only, and it cannot prevent a malicious user from submitting anything to your server. As with any user input, your application should also validate, sanitize and/or reject restricted files on the server side. +## Composable structure and purpose + +File upload - multiple is designed in a composable manner to maximize flexibility. Each individual sub-component that makes up the file upload - multiple component has an intended structure and purpose, which are outlined below. + +```noLive + + + + + + +``` + +- **MultipleFileUpload**: Acts as a container for all other `MultipleFileUpload` components. Logic for the callback that gets called when a file is uploaded can also be passed into this sub-component. **Required**. +- **MultipleFileUploadMain**: Creates the visual upload interface, including the area to drag and drop files, an optional upload button, and descriptive instructions. **Required**. +- **MultipleFileUploadStatus**: Acts as an expandable container for all uploaded file statuses. An optional text and/or icon can also be passed into this sub-component. **Required**, but this sub-component can be conditionally rendered when at least 1 file has been attempted to be uploaded. +- **MultipleFileUploadStatusItem**: Renders a progress bar for each individual file that has been attempted to be uploaded, including the file name, file type, file size, and upload status. Each status item also has a "remove" button to remove individual items from the status list. **Required** when at least one item has been attempted to be uploaded. + ## Examples ### Basic From 48d9da744c0b71170b02f5e4dd6a16afbb82f3e4 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Thu, 7 Jul 2022 12:54:43 -0400 Subject: [PATCH 2/5] Move component descriptions to individual files --- .../components/MultipleFileUpload/MultipleFileUpload.tsx | 4 ++++ .../MultipleFileUpload/MultipleFileUploadMain.tsx | 3 +++ .../MultipleFileUpload/MultipleFileUploadStatus.tsx | 6 ++++++ .../MultipleFileUpload/MultipleFileUploadStatusItem.tsx | 5 +++++ .../MultipleFileUpload/examples/MultipleFileUpload.md | 9 ++------- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx index 618ed108880..40db5153360 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx @@ -3,6 +3,10 @@ import Dropzone, { DropzoneProps, DropFileEventHandler } from 'react-dropzone'; import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload'; import { css } from '@patternfly/react-styles'; +/** Acts as a container for all other MultipleFileUpload sub-components. + * Logic for the callback that gets called when a file is uploaded can also + * be passed into this sub-component. + */ export interface MultipleFileUploadProps extends Omit, 'value'> { /** Content rendered inside the multi upload field */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadMain.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadMain.tsx index 93aa019d75f..3a0ed196dae 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadMain.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadMain.tsx @@ -5,6 +5,9 @@ import { MultipleFileUploadTitle } from './MultipleFileUploadTitle'; import { MultipleFileUploadButton } from './MultipleFileUploadButton'; import { MultipleFileUploadInfo } from './MultipleFileUploadInfo'; +/** Creates the visual upload interface, including the area to drag and drop files, + * an optional upload button, and descriptive instructions. + */ export interface MultipleFileUploadMainProps extends React.HTMLProps { /** Class to add to outer div */ className?: string; diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatus.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatus.tsx index 6198f18a8ac..36056ae4c1b 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatus.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatus.tsx @@ -6,6 +6,12 @@ import InProgressIcon from '@patternfly/react-icons/dist/esm/icons/in-progress-i import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon'; import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; +/** Acts as an expandable container for all uploaded file statuses. + * An optional text and/or icon can also be passed into this sub-component. + * This sub-component can be conditionally rendered when at least 1 file has been + * attempted to be uploaded. + */ + export interface MultipleFileUploadStatusProps extends React.HTMLProps { /** Content rendered inside multi file upload status list */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx index 904a5f75cad..bb2acb62728 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx @@ -6,6 +6,11 @@ import { Button } from '../Button'; import FileIcon from '@patternfly/react-icons/dist/esm/icons/file-icon'; import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; +/** Renders a progress bar for each individual file that has been attempted to be uploaded, + * including the file name, file type, file size, and upload status. Each status item also + * has a "remove" button to remove individual items from the status list. + */ + export interface MultipleFileUploadStatusItemProps extends React.HTMLProps { /** Class to add to outer div */ className?: string; diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md index 00c027cc2ea..f938c357399 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md @@ -26,9 +26,9 @@ As with singular file upload, any [props accepted by react-dropzone's Dropzone c Restricting file sizes and types in this way is for user convenience only, and it cannot prevent a malicious user from submitting anything to your server. As with any user input, your application should also validate, sanitize and/or reject restricted files on the server side. -## Composable structure and purpose +## Composable structure -File upload - multiple is designed in a composable manner to maximize flexibility. Each individual sub-component that makes up the file upload - multiple component has an intended structure and purpose, which are outlined below. +File upload - multiple is designed in a composable manner to make customization easier. The standard sub-component relationships are arranged as follows: ```noLive @@ -39,11 +39,6 @@ File upload - multiple is designed in a composable manner to maximize flexibilit ``` -- **MultipleFileUpload**: Acts as a container for all other `MultipleFileUpload` components. Logic for the callback that gets called when a file is uploaded can also be passed into this sub-component. **Required**. -- **MultipleFileUploadMain**: Creates the visual upload interface, including the area to drag and drop files, an optional upload button, and descriptive instructions. **Required**. -- **MultipleFileUploadStatus**: Acts as an expandable container for all uploaded file statuses. An optional text and/or icon can also be passed into this sub-component. **Required**, but this sub-component can be conditionally rendered when at least 1 file has been attempted to be uploaded. -- **MultipleFileUploadStatusItem**: Renders a progress bar for each individual file that has been attempted to be uploaded, including the file name, file type, file size, and upload status. Each status item also has a "remove" button to remove individual items from the status list. **Required** when at least one item has been attempted to be uploaded. - ## Examples ### Basic From 7df67a6b3c4f1faefbca064fb068968d21f91377 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Fri, 8 Jul 2022 10:03:40 -0400 Subject: [PATCH 3/5] Add composable structure info to dual list selector --- .../DualListSelector/DualListSelector.tsx | 4 ++++ .../DualListSelectorControl.tsx | 4 ++++ .../DualListSelectorControlsWrapper.tsx | 2 ++ .../DualListSelector/DualListSelectorList.tsx | 2 ++ .../DualListSelectorListItem.tsx | 4 ++++ .../DualListSelector/DualListSelectorPane.tsx | 5 +++++ .../examples/DualListSelector.md | 19 +++++++++++++------ 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/react-core/src/components/DualListSelector/DualListSelector.tsx b/packages/react-core/src/components/DualListSelector/DualListSelector.tsx index 5667d486c4b..2da6c7ecfd5 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelector.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelector.tsx @@ -20,6 +20,10 @@ import { DualListSelectorControlsWrapper } from './DualListSelectorControlsWrapp import { DualListSelectorControl } from './DualListSelectorControl'; import { DualListSelectorContext } from './DualListSelectorContext'; +/** Acts as a container for all other DualListSelector sub-components when using a + * composable dual list selector. + */ + export interface DualListSelectorProps { /** Additional classes applied to the dual list selector. */ className?: string; diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorControl.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorControl.tsx index 924e745948f..e7976afd2a5 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorControl.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorControl.tsx @@ -3,6 +3,10 @@ import { css } from '@patternfly/react-styles'; import { Button, ButtonVariant } from '../Button'; import { Tooltip } from '../Tooltip'; +/** Renders an individual control button for moving selected options between each + * dual list selector pane. + */ + export interface DualListSelectorControlProps extends Omit, 'onClick'> { /** Content to be rendered in the dual list selector control. */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorControlsWrapper.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorControlsWrapper.tsx index 15591bfab74..fbaaca50e36 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorControlsWrapper.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorControlsWrapper.tsx @@ -3,6 +3,8 @@ import styles from '@patternfly/react-styles/css/components/DualListSelector/dua import { css } from '@patternfly/react-styles'; import { handleArrows } from '../../helpers'; +/** Acts as the container for the DualListSelectorControl sub-components. */ + export interface DualListSelectorControlsWrapperProps extends React.HTMLProps { /** Anything that can be rendered inside of the wrapper. */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorList.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorList.tsx index 883dd853fb8..cc0224eef1f 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorList.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorList.tsx @@ -4,6 +4,8 @@ import { DualListSelectorListItem } from './DualListSelectorListItem'; import * as React from 'react'; import { DualListSelectorListContext } from './DualListSelectorContext'; +/** Acts as the container for DualListSelectorListItem sub-components. */ + export interface DualListSelectorListProps extends React.HTMLProps { /** Content rendered inside the dual list selector list */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorListItem.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorListItem.tsx index a14bbadac13..9b32725c9c3 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorListItem.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorListItem.tsx @@ -6,6 +6,10 @@ import GripVerticalIcon from '@patternfly/react-icons/dist/esm/icons/grip-vertic import { Button, ButtonVariant } from '../Button'; import { DualListSelectorListContext } from './DualListSelectorContext'; +/** Creates an individual option that can be selected and moved between the + * dual list selector panes. This is contained within the DualListSelectorList sub-component. + */ + export interface DualListSelectorListItemProps extends React.HTMLProps { /** Content rendered inside the dual list selector. */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorPane.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorPane.tsx index 47b90442e19..97bb8e1efd5 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorPane.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorPane.tsx @@ -8,6 +8,11 @@ import { DualListSelectorListWrapper } from './DualListSelectorListWrapper'; import { DualListSelectorContext, DualListSelectorPaneContext } from './DualListSelectorContext'; import { DualListSelectorList } from './DualListSelectorList'; +/** Acts as the container for a list of options that are either available or chosen, + * depending on the pane type (available or chosen). A search input and other actions, + * such as sorting, can also be passed into this sub-component. + */ + export interface DualListSelectorPaneProps { /** Additional classes applied to the dual list selector pane. */ className?: string; diff --git a/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md b/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md index 20986021bad..80e0125f0e1 100644 --- a/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md +++ b/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md @@ -6,10 +6,15 @@ propComponents: [ 'DualListSelector', 'DualListSelectorPane', - 'DualListSelectorControl', + 'DualListSelectorList', + 'DualListSelectorListItem', 'DualListSelectorControlsWrapper', +<<<<<<< HEAD 'DualListSelectorList', 'DualListSelectorListItem', +======= + 'DualListSelectorControl', +>>>>>>> 64a9949c7 (Add composable structure info to dual list selector) 'DualListSelectorTree', 'DualListSelectorTreeItemData', ] @@ -49,9 +54,9 @@ import PficonSortCommonAscIcon from '@patternfly/react-icons/dist/esm/icons/pfic ```ts file="./DualListSelectorTreeExample.tsx" ``` -### Composable dual list selector +## Composable structure -For more flexibility, a dual list selector can be built using sub components. When doing so, the intended component relationships are arranged as follows: +The dual list selector can also be built in a composable manner to make customization easier. The standard sub-component relationships are arranged as follows: ```noLive @@ -62,7 +67,7 @@ For more flexibility, a dual list selector can be built using sub components. Wh - /* The standard Dual list selector has 4 controls */ + /* A standard Dual list selector has 4 controls */ @@ -73,10 +78,12 @@ For more flexibility, a dual list selector can be built using sub components. Wh ``` +### Composable dual list selector + ```ts file="./DualListSelectorComposable.tsx" ``` -### Composable dual list selector with drag and drop +### Composable with drag and drop This example only allows reordering the contents of the "chosen" pane with drag and drop. To make a pane able to be reordered: @@ -95,7 +102,7 @@ Note: Keyboard accessibility and screen reader accessibility for the `DragDrop` ```ts file="DualListSelectorComposableDragDrop.tsx" ``` -### Composable dual list selector with tree +### Composable with tree ```ts file="DualListSelectorComposableTree.tsx" ``` From 48c16a81dc98248f3bd0e0d38adf1a1c254cb115 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Fri, 8 Jul 2022 10:29:10 -0400 Subject: [PATCH 4/5] Add description to tree sub-component --- .../src/components/DualListSelector/DualListSelectorTree.tsx | 4 ++++ .../components/DualListSelector/examples/DualListSelector.md | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/react-core/src/components/DualListSelector/DualListSelectorTree.tsx b/packages/react-core/src/components/DualListSelector/DualListSelectorTree.tsx index 4df8c18d72c..5809ca4ef0c 100644 --- a/packages/react-core/src/components/DualListSelector/DualListSelectorTree.tsx +++ b/packages/react-core/src/components/DualListSelector/DualListSelectorTree.tsx @@ -35,6 +35,10 @@ export interface DualListSelectorTreeItemData { isDisabled?: boolean; } +/** Used in place of the DualListSelectorListItem sub-component when building a + * composable dual list selector with a tree. + */ + export interface DualListSelectorTreeProps extends Omit, 'data'> { /** Data of the tree view */ data: DualListSelectorTreeItemData[] | (() => DualListSelectorTreeItemData[]); diff --git a/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md b/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md index 80e0125f0e1..f7e3deb1f6e 100644 --- a/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md +++ b/packages/react-core/src/components/DualListSelector/examples/DualListSelector.md @@ -9,12 +9,7 @@ propComponents: 'DualListSelectorList', 'DualListSelectorListItem', 'DualListSelectorControlsWrapper', -<<<<<<< HEAD - 'DualListSelectorList', - 'DualListSelectorListItem', -======= 'DualListSelectorControl', ->>>>>>> 64a9949c7 (Add composable structure info to dual list selector) 'DualListSelectorTree', 'DualListSelectorTreeItemData', ] From 96d7a23abfea103e569ebc084467df2670b3275a Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Mon, 11 Jul 2022 10:38:10 -0400 Subject: [PATCH 5/5] Verbiage changes to sub-component descriptions --- .../components/MultipleFileUpload/MultipleFileUpload.tsx | 7 ++++--- .../MultipleFileUpload/MultipleFileUploadStatusItem.tsx | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx index 40db5153360..d8386343677 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUpload.tsx @@ -3,10 +3,11 @@ import Dropzone, { DropzoneProps, DropFileEventHandler } from 'react-dropzone'; import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload'; import { css } from '@patternfly/react-styles'; -/** Acts as a container for all other MultipleFileUpload sub-components. - * Logic for the callback that gets called when a file is uploaded can also - * be passed into this sub-component. +/** Acts as a container for all other MultipleFileUpload sub-components. This sub-component + * also provides the functionality for file uploads, and access to the uploaded files via + * a callback. */ + export interface MultipleFileUploadProps extends Omit, 'value'> { /** Content rendered inside the multi upload field */ children?: React.ReactNode; diff --git a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx index bb2acb62728..d06871ffd97 100644 --- a/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx @@ -6,9 +6,9 @@ import { Button } from '../Button'; import FileIcon from '@patternfly/react-icons/dist/esm/icons/file-icon'; import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; -/** Renders a progress bar for each individual file that has been attempted to be uploaded, - * including the file name, file type, file size, and upload status. Each status item also - * has a "remove" button to remove individual items from the status list. +/** Automatically reads an uploaded file to render a visual representation of it, including + * its name, size, and read status. This sub-component also allows custom reading of files + * via various callbacks which will override the automatic reading behavior. */ export interface MultipleFileUploadStatusItemProps extends React.HTMLProps {