Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions pages/list/selectable.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useState } from 'react';

import { Box, SpaceBetween } from '~components';
import List, { ListProps } from '~components/list';

import ScreenshotArea from '../utils/screenshot-area';

interface Item {
id: string;
content: string;
description?: string;
disabled?: boolean;
}

const items: Item[] = [
{ id: 'apples', content: 'Apples', description: 'Crisp and sweet' },
{ id: 'bananas', content: 'Bananas', description: 'Rich in potassium' },
{ id: 'cherries', content: 'Cherries', description: 'Currently out of stock', disabled: true },
{ id: 'dates', content: 'Dates', description: 'Naturally sweet' },
{ id: 'elderberries', content: 'Elderberries', description: 'Best cooked' },
];

const renderItem = (item: Item): ReturnType<ListProps<Item>['renderItem']> => ({
id: item.id,
content: item.content,
secondaryContent: item.description && <Box variant="small">{item.description}</Box>,
});

export default function SelectableListPage() {
const [singleSelected, setSingleSelected] = useState<ReadonlyArray<Item>>([items[0]]);
const [multiSelected, setMultiSelected] = useState<ReadonlyArray<Item>>([items[1], items[3]]);

return (
<ScreenshotArea>
<h1>Selectable list</h1>
<SpaceBetween size="l">
<div>
<h2 id="single-heading">Single selection</h2>
<List
ariaLabelledby="single-heading"
selectionType="single"
items={items}
renderItem={renderItem}
isItemDisabled={item => !!item.disabled}
selectedItems={singleSelected}
onSelectionChange={({ detail }) => setSingleSelected(detail.selectedItems)}
/>
<Box variant="small">Selected: {singleSelected.map(item => item.content).join(', ') || 'none'}</Box>
</div>

<div>
<h2 id="multi-heading">Multi selection</h2>
<List
ariaLabelledby="multi-heading"
selectionType="multi"
items={items}
renderItem={renderItem}
isItemDisabled={item => !!item.disabled}
selectedItems={multiSelected}
onSelectionChange={({ detail }) => setMultiSelected(detail.selectedItems)}
/>
<Box variant="small">Selected: {multiSelected.map(item => item.content).join(', ') || 'none'}</Box>
</div>
</SpaceBetween>
</ScreenshotArea>
);
}
112 changes: 112 additions & 0 deletions src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -18586,6 +18586,23 @@ exports[`Components definition for list matches the snapshot: list 1`] = `
{
"dashCaseName": "list",
"events": [
{
"cancelable": false,
"description": "Called when the selection changes. The event \`detail\` contains the updated \`selectedItems\`.",
"detailInlineType": {
"name": "ListProps.SelectionChangeDetail<T>",
"properties": [
{
"name": "selectedItems",
"optional": false,
"type": "ReadonlyArray<T>",
},
],
"type": "object",
},
"detailType": "ListProps.SelectionChangeDetail<T>",
"name": "onSelectionChange",
},
{
"cancelable": false,
"description": "Called when items are reordered in a sortable list.",
Expand Down Expand Up @@ -18740,6 +18757,24 @@ exports[`Components definition for list matches the snapshot: list 1`] = `
"optional": true,
"type": "DndAreaI18nStrings",
},
{
"description": "A function that determines whether a given item can be selected. Return \`true\` to
prevent an item from being selected.",
"inlineType": {
"name": "(item: T) => boolean",
"parameters": [
{
"name": "item",
"type": "T",
},
],
"returnType": "boolean",
"type": "function",
},
"name": "isItemDisabled",
"optional": true,
"type": "((item: T) => boolean)",
},
{
"description": "The items to display in the list.",
"name": "items",
Expand Down Expand Up @@ -18770,6 +18805,32 @@ exports[`Components definition for list matches the snapshot: list 1`] = `
"optional": false,
"type": "(item: T) => { id: string; content: React.ReactNode; secondaryContent?: React.ReactNode; icon?: React.ReactNode; actions?: React.ReactNode; announcementLabel?: string | undefined; }",
},
{
"description": "The currently selected items. Use together with \`selectionType\` and \`onSelectionChange\`
to control the selection state. Items are matched using the \`id\` returned by \`renderItem\`.",
"name": "selectedItems",
"optional": true,
"type": "ReadonlyArray<T>",
},
{
"description": "Enables item selection and defines the selection behavior:
* \`single\` - Only one item can be selected at a time (renders as a radio control).
* \`multi\` - Multiple items can be selected at a time (renders as a checkbox control).

When set, the list is rendered as an ARIA \`listbox\` and each item as an \`option\`.
Selection is not supported together with \`sortable\`; when both are provided, sorting takes precedence.",
"inlineType": {
"name": "ListProps.SelectionType",
"type": "union",
"values": [
"single",
"multi",
],
},
"name": "selectionType",
"optional": true,
"type": "string",
},
{
"description": "Makes the list sortable by enabling drag and drop functionality.",
"name": "sortable",
Expand Down Expand Up @@ -41775,6 +41836,20 @@ The dismiss button is only rendered when the \`dismissible\` property is set to
],
},
},
{
"description": "Returns all currently selected items. Only meaningful for selectable lists.",
"name": "findSelectedItems",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "Array",
"typeArguments": [
{
"name": "ListItemWrapper",
},
],
},
},
],
"name": "ListWrapper",
},
Expand Down Expand Up @@ -41857,6 +41932,20 @@ The dismiss button is only rendered when the \`dismissible\` property is set to
],
},
},
{
"description": "Returns the selection control (checkbox or radio) for a selectable list item, if present.",
"name": "findSelectionControl",
"parameters": [],
"returnType": {
"isNullable": true,
"name": "ElementWrapper",
"typeArguments": [
{
"name": "HTMLElement",
},
],
},
},
],
"name": "ListItemWrapper",
},
Expand Down Expand Up @@ -51998,6 +52087,20 @@ The dismiss button is only rendered when the \`dismissible\` property is set to
],
},
},
{
"description": "Returns all currently selected items. Only meaningful for selectable lists.",
"name": "findSelectedItems",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "MultiElementWrapper",
"typeArguments": [
{
"name": "ListItemWrapper",
},
],
},
},
],
"name": "ListWrapper",
},
Expand Down Expand Up @@ -52055,6 +52158,15 @@ The dismiss button is only rendered when the \`dismissible\` property is set to
"name": "ElementWrapper",
},
},
{
"description": "Returns the selection control (checkbox or radio) for a selectable list item, if present.",
"name": "findSelectionControl",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "ElementWrapper",
},
},
],
"name": "ListItemWrapper",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ exports[`test-utils selectors 1`] = `
"list": [
"awsui_item_rckk5",
"awsui_root_rckk5",
"awsui_selected_rckk5",
"awsui_selection-control_rckk5",
],
"live-region": [
"awsui_root_1pc7b",
Expand Down
Loading
Loading