Skip to content

Commit fdff9a9

Browse files
committed
feat: Add list component
1 parent ad0aa3d commit fdff9a9

File tree

20 files changed

+510
-93
lines changed

20 files changed

+510
-93
lines changed

build-tools/utils/pluralize.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const pluralizationMap = {
4545
KeyValuePairs: 'KeyValuePairs',
4646
LineChart: 'LineCharts',
4747
Link: 'Links',
48+
List: 'Lists',
4849
LiveRegion: 'LiveRegions',
4950
MixedLineBarChart: 'MixedLineBarCharts',
5051
Modal: 'Modals',

pages/list/permutations.page.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import { Box, ButtonDropdown, SpaceBetween } from '~components';
6+
import List, { ListProps } from '~components/list';
7+
8+
import createPermutations from '../utils/permutations';
9+
import PermutationsView from '../utils/permutations-view';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
12+
interface Item {
13+
content: string;
14+
description?: string;
15+
timestamp?: string;
16+
}
17+
const items: Item[] = [
18+
{ content: 'Item 1', timestamp: '3:23 pm' },
19+
{ content: 'Item 2 has a longer title', timestamp: 'Two hours ago' },
20+
{
21+
content: 'Item 3 with more text',
22+
description: 'Item 3 has a long description that probably spans onto multiple lines on smaller viewports.',
23+
timestamp: 'Yesterday',
24+
},
25+
{ content: 'Item 4', description: 'Description', timestamp: 'January 1 2025' },
26+
];
27+
28+
/* eslint-disable react/jsx-key */
29+
const permutations = createPermutations<ListProps<Item> & { viewportWidth: number; _sortable: boolean | 'disabled' }>([
30+
{
31+
viewportWidth: [200, 400],
32+
items: [items],
33+
_sortable: [true, false, 'disabled'],
34+
renderItem: [
35+
({ content }) => ({ content, id: content }),
36+
({ content }) => ({ content, id: content, secondaryContent: <Box variant="small">Description</Box> }),
37+
({ content, description }) => ({
38+
id: content,
39+
content,
40+
secondaryContent: description && <Box variant="small">{description}</Box>,
41+
actions: <ButtonDropdown variant="icon" items={[{ id: 'item', text: 'item' }]} />,
42+
}),
43+
({ content, description, timestamp }) => ({
44+
id: content,
45+
content,
46+
secondaryContent: description && <Box variant="small">{description}</Box>,
47+
actions: (
48+
<SpaceBetween size="xs" direction="horizontal" alignItems="center">
49+
<Box variant="small">{timestamp}</Box>
50+
<ButtonDropdown variant="icon" items={[{ id: 'item', text: 'item' }]} />
51+
</SpaceBetween>
52+
),
53+
}),
54+
],
55+
},
56+
]);
57+
/* eslint-enable react/jsx-key */
58+
59+
export default function ListItemPermutations() {
60+
return (
61+
<>
62+
<h1>List permutations</h1>
63+
<ScreenshotArea>
64+
<PermutationsView
65+
permutations={permutations}
66+
render={({ viewportWidth, ...permutation }) => (
67+
<div style={{ width: viewportWidth, borderRight: '1px solid red', padding: '4px', overflow: 'hidden' }}>
68+
<List
69+
{...permutation}
70+
sortable={!!permutation._sortable}
71+
sortDisabled={permutation._sortable === 'disabled'}
72+
/>
73+
</div>
74+
)}
75+
/>
76+
</ScreenshotArea>
77+
</>
78+
);
79+
}

src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11449,6 +11449,65 @@ The default is \`secondary\`, except inside the following components where it de
1144911449
}
1145011450
`;
1145111451

11452+
exports[`Documenter definition for list matches the snapshot: list 1`] = `
11453+
{
11454+
"dashCaseName": "list",
11455+
"events": [],
11456+
"functions": [],
11457+
"name": "List",
11458+
"properties": [
11459+
{
11460+
"name": "items",
11461+
"optional": false,
11462+
"type": "Array<T>",
11463+
},
11464+
{
11465+
"inlineType": {
11466+
"name": "(item: T, index: number) => StructuredItemProps",
11467+
"parameters": [
11468+
{
11469+
"name": "item",
11470+
"type": "T",
11471+
},
11472+
{
11473+
"name": "index",
11474+
"type": "number",
11475+
},
11476+
],
11477+
"returnType": "StructuredItemProps",
11478+
"type": "function",
11479+
},
11480+
"name": "renderItem",
11481+
"optional": false,
11482+
"type": "(item: T, index: number) => StructuredItemProps",
11483+
},
11484+
{
11485+
"inlineType": {
11486+
"name": ""wrap" | "min-width" | "breakpoint" | "stick" | "wrap-right" | "min-width-right" | "breakpoint-right"",
11487+
"type": "union",
11488+
"values": [
11489+
"wrap",
11490+
"min-width",
11491+
"breakpoint",
11492+
"stick",
11493+
"wrap-right",
11494+
"min-width-right",
11495+
"breakpoint-right",
11496+
],
11497+
},
11498+
"name": "strategy",
11499+
"optional": true,
11500+
"type": "string",
11501+
},
11502+
],
11503+
"regions": [],
11504+
"releaseStatus": "stable",
11505+
"systemTags": [
11506+
"core",
11507+
],
11508+
}
11509+
`;
11510+
1145211511
exports[`Documenter definition for live-region matches the snapshot: live-region 1`] = `
1145311512
{
1145411513
"dashCaseName": "live-region",
@@ -17184,6 +17243,57 @@ Each step definition has the following properties:
1718417243
}
1718517244
`;
1718617245

17246+
exports[`Documenter definition for structured-item matches the snapshot: structured-item 1`] = `
17247+
{
17248+
"dashCaseName": "structured-item",
17249+
"events": [],
17250+
"functions": [],
17251+
"name": "StructuredItem",
17252+
"properties": [
17253+
{
17254+
"inlineType": {
17255+
"name": ""wrap" | "min-width" | "breakpoint" | "stick" | "wrap-right" | "min-width-right" | "breakpoint-right"",
17256+
"type": "union",
17257+
"values": [
17258+
"wrap",
17259+
"min-width",
17260+
"breakpoint",
17261+
"stick",
17262+
"wrap-right",
17263+
"min-width-right",
17264+
"breakpoint-right",
17265+
],
17266+
},
17267+
"name": "strategy",
17268+
"optional": true,
17269+
"type": "string",
17270+
},
17271+
],
17272+
"regions": [
17273+
{
17274+
"isDefault": false,
17275+
"name": "content",
17276+
},
17277+
{
17278+
"isDefault": false,
17279+
"name": "description",
17280+
},
17281+
{
17282+
"isDefault": false,
17283+
"name": "icon",
17284+
},
17285+
{
17286+
"isDefault": false,
17287+
"name": "secondaryContent",
17288+
},
17289+
],
17290+
"releaseStatus": "stable",
17291+
"systemTags": [
17292+
"core",
17293+
],
17294+
}
17295+
`;
17296+
1718717297
exports[`Documenter definition for table matches the snapshot: table 1`] = `
1718817298
{
1718917299
"dashCaseName": "table",

src/collection-preferences/content-display/content-display-option.scss

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,16 @@
1414
@include styles.styles-reset;
1515
display: flex;
1616
align-items: flex-start;
17-
padding-block: awsui.$space-xs;
18-
padding-inline-start: 0;
19-
padding-inline-end: awsui.$space-scaled-xs;
20-
background-color: awsui.$color-background-container-content;
17+
padding-block: awsui.$space-scaled-xs;
18+
padding-inline: awsui.$space-xs;
2119
border-start-start-radius: awsui.$border-radius-item;
2220
border-start-end-radius: awsui.$border-radius-item;
2321
border-end-start-radius: awsui.$border-radius-item;
2422
border-end-end-radius: awsui.$border-radius-item;
2523
}
2624

27-
.content-display-option {
28-
list-style: none;
29-
position: relative;
30-
border-block-start: awsui.$border-divider-list-width solid awsui.$color-border-divider-secondary;
31-
}
32-
3325
.content-display-option-label {
3426
flex-grow: 1;
3527
@include styles.text-wrapping;
3628
padding-inline-end: awsui.$space-l;
3729
}
38-
39-
.drag-handle-wrapper {
40-
margin-inline: awsui.$space-scaled-xxs;
41-
}

src/collection-preferences/content-display/content-display-option.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33
import React, { ForwardedRef, forwardRef } from 'react';
44

5-
import DragHandle, { DragHandleProps } from '../../internal/components/drag-handle';
65
import { useUniqueId } from '../../internal/hooks/use-unique-id';
76
import InternalToggle from '../../toggle/internal';
87
import { OptionWithVisibility } from './utils';
@@ -13,21 +12,16 @@ const componentPrefix = 'content-display-option';
1312
export const getClassName = (suffix?: string) => styles[[componentPrefix, suffix].filter(Boolean).join('-')];
1413

1514
interface ContentDisplayOptionProps {
16-
dragHandleProps: DragHandleProps;
1715
onToggle?: (option: OptionWithVisibility) => void;
1816
option: OptionWithVisibility;
1917
}
2018

2119
const ContentDisplayOption = forwardRef(
22-
({ dragHandleProps, onToggle, option }: ContentDisplayOptionProps, ref: ForwardedRef<HTMLDivElement>) => {
20+
({ onToggle, option }: ContentDisplayOptionProps, ref: ForwardedRef<HTMLDivElement>) => {
2321
const idPrefix = useUniqueId(componentPrefix);
2422
const controlId = `${idPrefix}-control-${option.id}`;
2523
return (
2624
<div ref={ref} className={getClassName('content')}>
27-
<div className={styles['drag-handle-wrapper']}>
28-
<DragHandle {...dragHandleProps} />
29-
</div>
30-
3125
<label className={getClassName('label')} htmlFor={controlId}>
3226
{option.label}
3327
</label>

0 commit comments

Comments
 (0)