Skip to content

Commit

Permalink
MultiSelect storybook updates (#14711)
Browse files Browse the repository at this point in the history
* chore(MultiSelect): add  documentation for sortItems and compareItems

* chore(multiselect): update the storybook contents

* fix: rename private APIs in stories.js

* fix: it is possible that isRequired is required for sort and compare
  • Loading branch information
cknabe authored Sep 26, 2023
1 parent 13150c5 commit 0e9bca2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 3 deletions.
47 changes: 46 additions & 1 deletion packages/react/src/components/MultiSelect/MultiSelect.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { ArgsTable } from '@storybook/blocks';
import { ArgsTable, Canvas, Story } from '@storybook/blocks';

import * as MultiSelect from './MultiSelect.stories';

# MultiSelect

Expand All @@ -8,10 +10,53 @@ import { ArgsTable } from '@storybook/blocks';
 | 
[Accessibility](https://www.carbondesignsystem.com/components/dropdown/accessibility)

{/* <!-- START doctoc generated TOC please keep comment here to allow auto update --> */}
{/* <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> */}
## Table of Contents

- [Overview](#overview)
- [With initial selected items](#with-initial-selected-items)
- [Filtering](#filtering)
- [With layer](#with-layer)
- [Component API](#component-api)
- [Feedback](#feedback)

{/* <!-- END doctoc generated TOC please keep comment here to allow auto update --> */}

## Overview

The `MultiSelect` component is a variant of the `Dropdown` component that allows for
multiple items to be selected. `MultiSelect` stays open while items are
being selected.


<Canvas>
<Story of={MultiSelect.Default} />
</Canvas>

### With initial selected items

By passing items into the `initialSelectedItems` prop, they can be pre-selected.

<Canvas>
<Story of={MultiSelect.WithInitialSelectedItems} />
</Canvas>

### Filtering

The `FilterableMultiSelect` component allows for filtering the list of selectable
items to a subset.

<Canvas>
<Story of={MultiSelect.Filterable} />
</Canvas>

### With layer

<Canvas>
<Story of={MultiSelect.WithLayerMultiSelect} />
</Canvas>

## Component API

<ArgsTable />
Expand Down
10 changes: 8 additions & 2 deletions packages/react/src/components/MultiSelect/MultiSelect.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React from 'react';

import { WithLayer } from '../../../.storybook/templates/WithLayer';
import mdx from './MultiSelect.mdx';

import MultiSelect from '.';
import FilterableMultiSelect from './FilterableMultiSelect';
Expand Down Expand Up @@ -77,6 +78,11 @@ export default {
table: { disable: true },
},
},
parameters: {
docs: {
page: mdx,
},
},
};

const items = [
Expand Down Expand Up @@ -250,7 +256,7 @@ export const WithInitialSelectedItems = () => {
);
};

export const _Filterable = () => {
export const Filterable = () => {
return (
<div style={{ width: 300 }}>
<FilterableMultiSelect
Expand All @@ -265,7 +271,7 @@ export const _Filterable = () => {
);
};

export const _WithLayer = () => (
export const WithLayerMultiSelect = () => (
<WithLayer>
{(layer) => (
<div style={{ width: 300 }}>
Expand Down
53 changes: 53 additions & 0 deletions packages/react/src/components/MultiSelect/MultiSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,36 @@ interface SortItemsOptions<ItemType>
}

interface MultiSelectSortingProps<ItemType> {
/**
* Provide a compare function that is used to determine the ordering of
* options. See 'sortItems' for more control.
*/
compareItems?(
item1: ItemType,
item2: ItemType,
options: SharedOptions
): number; // required but has default value

/**
* Provide a method that sorts all options in the control. Overriding this
* prop means that you also have to handle the sort logic for selected versus
* un-selected items. If you just want to control ordering, consider the
* `compareItems` prop instead.
*
* The return value should be a number whose sign indicates the relative order
* of the two elements: negative if a is less than b, positive if a is greater
* than b, and zero if they are equal.
*
* sortItems :
* (items: Array<Item>, {
* selectedItems: Array<Item>,
* itemToString: Item => string,
* compareItems: (itemA: string, itemB: string, {
* locale: string
* }) => number,
* locale: string,
* }) => Array<Item>
*/
sortItems?(
items: ReadonlyArray<ItemType>,
options: SortItemsOptions<ItemType>
Expand Down Expand Up @@ -697,6 +722,12 @@ MultiSelect.propTypes = {
*/
clearSelectionText: PropTypes.string,

/**
* Provide a compare function that is used to determine the ordering of
* options. See 'sortItems' for more control.
*/
compareItems: PropTypes.func.isRequired,

/**
* Specify the direction of the multiselect dropdown. Can be either top or bottom.
*/
Expand Down Expand Up @@ -824,6 +855,28 @@ MultiSelect.propTypes = {
*/
size: ListBoxPropTypes.ListBoxSize,

/**
* Provide a method that sorts all options in the control. Overriding this
* prop means that you also have to handle the sort logic for selected versus
* un-selected items. If you just want to control ordering, consider the
* `compareItems` prop instead.
*
* The return value should be a number whose sign indicates the relative order
* of the two elements: negative if a is less than b, positive if a is greater
* than b, and zero if they are equal.
*
* sortItems :
* (items: Array<Item>, {
* selectedItems: Array<Item>,
* itemToString: Item => string,
* compareItems: (itemA: string, itemB: string, {
* locale: string
* }) => number,
* locale: string,
* }) => Array<Item>
*/
sortItems: PropTypes.func.isRequired,

/**
* Provide text to be used in a `<label>` element that is tied to the
* multiselect via ARIA attributes.
Expand Down

0 comments on commit 0e9bca2

Please sign in to comment.