Skip to content

Commit

Permalink
feat(DualListSelector): new demos in demo app
Browse files Browse the repository at this point in the history
  • Loading branch information
adamviktora committed Aug 1, 2024
1 parent 30e3c03 commit 206f5b8
Show file tree
Hide file tree
Showing 5 changed files with 911 additions and 0 deletions.
15 changes: 15 additions & 0 deletions packages/react-integration/demo-app-ts/src/Demos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@ export const Demos: DemoInterface[] = [
name: 'Dropdown Demo',
componentType: Examples.DropdownDemo
},
{
id: 'dual-list-selector-basic-demo',
name: 'DualListSelector basic Demo',
componentType: Examples.DualListSelectorBasicDemo
},
{
id: 'dual-list-selector-tree-demo',
name: 'DualListSelector Tree Demo',
componentType: Examples.DualListSelectorTreeDemo
},
{
id: 'dual-list-selector-with-actions-demo',
name: 'DualListSelector with actions Demo',
componentType: Examples.DualListSelectorWithActionsDemo
},
{
id: 'dual-list-selector-deprecated-basic-demo',
name: 'DualListSelector deprecated basic Demo',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import React from 'react';
import {
DualListSelector,
DualListSelectorPane,
DualListSelectorList,
DualListSelectorListItem,
DualListSelectorControlsWrapper,
DualListSelectorControl
} from '@patternfly/react-core';
import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';

interface Option {
text: string;
selected: boolean;
isVisible: boolean;
}

export const DualListSelectorBasicDemo: React.FunctionComponent = () => {
const [availableOptions, setAvailableOptions] = React.useState<Option[]>([
{ text: 'Option 1', selected: false, isVisible: true },
{ text: 'Option 2', selected: false, isVisible: true },
{ text: 'Option 3', selected: false, isVisible: true },
{ text: 'Option 4', selected: false, isVisible: true }
]);
const [chosenOptions, setChosenOptions] = React.useState<Option[]>([]);

// callback for moving selected options between lists
const moveSelected = (fromAvailable: boolean) => {
const sourceOptions = fromAvailable ? availableOptions : chosenOptions;
const destinationOptions = fromAvailable ? chosenOptions : availableOptions;
for (let i = 0; i < sourceOptions.length; i++) {
const option = sourceOptions[i];
if (option.selected && option.isVisible) {
sourceOptions.splice(i, 1);
destinationOptions.push(option);
option.selected = false;
i--;
}
}
if (fromAvailable) {
setAvailableOptions([...sourceOptions]);
setChosenOptions([...destinationOptions]);
} else {
setChosenOptions([...sourceOptions]);
setAvailableOptions([...destinationOptions]);
}
};

// callback for moving all options between lists
const moveAll = (fromAvailable: boolean) => {
if (fromAvailable) {
setChosenOptions([...availableOptions.filter((option) => option.isVisible), ...chosenOptions]);
setAvailableOptions([...availableOptions.filter((option) => !option.isVisible)]);
} else {
setAvailableOptions([...chosenOptions.filter((option) => option.isVisible), ...availableOptions]);
setChosenOptions([...chosenOptions.filter((option) => !option.isVisible)]);
}
};

// callback when option is selected
const onOptionSelect = (
_event: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent,
index: number,
isChosen: boolean
) => {
if (isChosen) {
const newChosen = [...chosenOptions];
newChosen[index].selected = !chosenOptions[index].selected;
setChosenOptions(newChosen);
} else {
const newAvailable = [...availableOptions];
newAvailable[index].selected = !availableOptions[index].selected;
setAvailableOptions(newAvailable);
}
};

return (
<DualListSelector>
<DualListSelectorPane
title="Available options"
status={`${availableOptions.filter((option) => option.selected && option.isVisible).length} of ${
availableOptions.filter((option) => option.isVisible).length
} options selected`}
>
<DualListSelectorList>
{availableOptions.map((option, index) =>
option.isVisible ? (
<DualListSelectorListItem
key={index}
isSelected={option.selected}
id={`basic-available-option-${index}`}
onOptionSelect={(e) => onOptionSelect(e, index, false)}
>
{option.text}
</DualListSelectorListItem>
) : null
)}
</DualListSelectorList>
</DualListSelectorPane>
<DualListSelectorControlsWrapper>
<DualListSelectorControl
isDisabled={!availableOptions.some((option) => option.selected)}
onClick={() => moveSelected(true)}
aria-label="Add selected"
tooltipContent="Add selected"
tooltipProps={{ position: 'top', 'aria-live': 'off' }}
icon={<AngleRightIcon />}
/>
<DualListSelectorControl
isDisabled={availableOptions.length === 0}
onClick={() => moveAll(true)}
aria-label="Add all"
tooltipContent="Add all"
tooltipProps={{ position: 'right', 'aria-live': 'off' }}
icon={<AngleDoubleRightIcon />}
/>
<DualListSelectorControl
isDisabled={chosenOptions.length === 0}
onClick={() => moveAll(false)}
aria-label="Remove all"
tooltipContent="Remove all"
tooltipProps={{ position: 'left', 'aria-live': 'off' }}
icon={<AngleDoubleLeftIcon />}
/>
<DualListSelectorControl
onClick={() => moveSelected(false)}
isDisabled={!chosenOptions.some((option) => option.selected)}
aria-label="Remove selected"
tooltipContent="Remove selected"
tooltipProps={{ position: 'bottom', 'aria-live': 'off' }}
icon={<AngleLeftIcon />}
/>
</DualListSelectorControlsWrapper>
<DualListSelectorPane
title="Chosen options"
status={`${chosenOptions.filter((option) => option.selected && option.isVisible).length} of ${
chosenOptions.filter((option) => option.isVisible).length
} options selected`}
isChosen
>
<DualListSelectorList>
{chosenOptions.map((option, index) =>
option.isVisible ? (
<DualListSelectorListItem
key={index}
isSelected={option.selected}
id={`composable-basic-chosen-option-${index}`}
onOptionSelect={(e) => onOptionSelect(e, index, true)}
>
{option.text}
</DualListSelectorListItem>
) : null
)}
</DualListSelectorList>
</DualListSelectorPane>
</DualListSelector>
);
};
Loading

0 comments on commit 206f5b8

Please sign in to comment.