Skip to content

feat: Treeview #3477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions build-tools/utils/pluralize.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const pluralizationMap = {
TokenGroup: 'TokenGroups',
TopNavigation: 'TopNavigations',
TreeView: 'TreeViews',
Treeview: 'Treeviews',
TutorialPanel: 'TutorialPanels',
Wizard: 'Wizards',
};
Expand Down
276 changes: 276 additions & 0 deletions pages/treeview/basic.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useState } from 'react';

import Badge from '~components/badge';
import Box from '~components/box';
import ButtonGroup from '~components/button-group';
import Container from '~components/container';
import Icon from '~components/icon';
import SpaceBetween from '~components/space-between';
import StatusIndicator from '~components/status-indicator';
import Treeview, { TreeviewProps } from '~components/treeview';

const progressiveStepContent = (
<div style={{ display: 'flex' }}>
<StatusIndicator type="warning">Checked 5 nodes</StatusIndicator>
<div style={{ borderLeft: '1px solid grey', marginLeft: '8px', marginRight: '8px' }} />
<SpaceBetween direction="horizontal" size="s">
<StatusIndicator type="warning">1</StatusIndicator>
<StatusIndicator type="in-progress">1</StatusIndicator>
<StatusIndicator type="success">2</StatusIndicator>
</SpaceBetween>
</div>
);

const progressiveStepItemsContent = [
<StatusIndicator key={'success-child'} type="success">
node-17 (eksclu-node-12345)
</StatusIndicator>,
<StatusIndicator key={'loading-child'} type="loading">
node-18 (eksclu-node-09876)
</StatusIndicator>,
<StatusIndicator key={'success-child-2'} type="success">
node-19 (eksclu-node-ab123)
</StatusIndicator>,
];

const items: TreeviewProps.TreeItem[] = [
{
id: '1',
content: 'Item 1',
items: [
{
id: '1.1',
content: 'Item 1.1',
items: [
{
id: '1.1.1',
content: 'Item 1.1.1',
},
{
id: '1.1.2',
content: 'Item 1.1.2',
},
],
},
{
id: '1.2',
content: 'Item 1.2',
},
{
id: '1.3',
content: 'Item 1.3',
details: <Box color="text-status-inactive">us-east-1</Box>,
actions: <Actions />,
items: [
{
id: '1.3.1',
content: 'Item 1.3.1',
},
{
id: '1.3.2',
content: 'Item 1.3.2',
},
],
},
],
},
{
id: '2',
content: 'Item 2',
},
{
id: '3',
content: 'Item 3',
items: [
{
id: '3.1',
content: 'Item 3.1',
},
],
},
{
id: '4',
content: <RdsAccessRoleTreeItemContent />,
items: [
{
id: '4.1',
content: 'Item 4.1',
items: [
{
id: '4.1.1',
content: 'Item 4.1.1',
},
{
id: '4.1.2',
content: 'Item 4.1.2',
details: <Box color="text-status-inactive">us-east-1</Box>,
items: [
{
id: '4.1.2.1',
content: 'Item 4.1.2.1',
},
],
},
{
id: '4.1.3',
content: 'Item 4.1.3',
items: [
{
id: '4.1.3.1',
content: 'Item 4.1.3.1',
},
{
id: '4.1.3.2',
content: 'Item 4.1.3.2',
},
{
id: '4.1.3.3',
content: 'Item 4.1.3.3',
},
],
},
],
},
{
id: '4.2',
content: 'Item 4.2',
},
],
},
{
id: '5',
content: 'Item 5',
},
{
id: '6',
content: progressiveStepContent,
items: [
{
id: '6.1',
content: progressiveStepItemsContent[0],
},
{
id: '6.2',
content: progressiveStepItemsContent[1],
},
{
id: '6.3',
content: progressiveStepItemsContent[2],
},
],
},
{
id: '7',
content: 'Item 7',
},
];

function Actions() {
const [pressed, setPressed] = useState(false);

return (
<ButtonGroup
variant="icon"
items={[
{
id: 'settings',
iconName: 'settings',
type: 'icon-button',
text: 'Settings',
},
{
id: 'menu',
type: 'menu-dropdown',
text: 'Menu',
items: [
{ id: 'start', text: 'Start' },
{ id: 'stop', text: 'Stop', disabled: true },
{
id: 'hibernate',
text: 'Hibernate',
disabled: true,
},
{ id: 'reboot', text: 'Reboot', disabled: true },
{ id: 'terminate', text: 'Terminate' },
],
},
{
type: 'icon-toggle-button',
id: 'favorite',
text: 'Favorite',
pressed: pressed,
iconName: 'star',
pressedIconName: 'star-filled',
},
]}
onItemClick={({ detail }) => {
if (detail.id === 'favorite') {
setPressed(!pressed);
}
}}
/>
);
}

function RdsAccessRoleTreeItemContent() {
return (
<div>
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'baseline' }}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '4px' }}>
<Icon name="user-profile-active" />
<span>RdsAccessRole</span>
<Badge color="red">1</Badge>
<Badge color="blue">1</Badge>
<Badge color="green">3</Badge>
</div>

<div>
<Actions />
</div>
</div>

<div style={{ display: 'flex', gap: '10px' }}>
<Box color="text-status-inactive">
<Icon name="globe" />
us-east-1
</Box>
<Box color="text-status-inactive">
<Icon name="ticket" />
prod-eng-xyz-zip-f
</Box>
</div>
</div>
);
}

export default function BasicTreeview() {
const [expandedItems, setExpandedItems] = useState<Array<string>>(['1', '4.1']);

return (
<>
<h1>Basic treeview</h1>

<Box padding="xl">
<div style={{ width: '60%' }}>
<Container>
<Treeview
items={items}
onExpandableItemToggle={({ detail }: any) => {
if (detail.expanded) {
return setExpandedItems(prev => [...prev, detail.id]);
} else {
return setExpandedItems(prev => prev.filter(id => id !== detail.id));
}
}}
expandedItems={expandedItems}
/>
</Container>
</div>

<div style={{ marginTop: '10px' }}>Expanded items: {expandedItems.map(id => `Item ${id}`).join(', ')}</div>
</Box>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20399,6 +20399,96 @@ exports[`Documenter definition for tree-view matches the snapshot: tree-view 1`]
}
`;

exports[`Documenter definition for treeview matches the snapshot: treeview 1`] = `
{
"dashCaseName": "treeview",
"events": [
{
"cancelable": false,
"description": "Called when an item's expand toggle is clicked.",
"detailInlineType": {
"name": "TreeviewProps.ExpandableItemToggleDetail",
"properties": [
{
"name": "expanded",
"optional": false,
"type": "boolean",
},
{
"name": "id",
"optional": false,
"type": "string",
},
],
"type": "object",
},
"detailType": "TreeviewProps.ExpandableItemToggleDetail",
"name": "onExpandableItemToggle",
},
],
"functions": [],
"name": "Treeview",
"properties": [
{
"description": "Provides an \`aria-label\` to the treeview that screen readers can read (for accessibility).
If there's a visible label element that you can reference, use this instead of \`ariaLabel\`.
Don't use \`ariaLabel\` and \`ariaLabelledby\` at the same time.",
"name": "ariaLabel",
"optional": true,
"type": "string",
},
{
"description": "Sets the \`aria-labelledby\` property on the treeview.",
"name": "ariaLabelledby",
"optional": true,
"type": "string",
},
{
"deprecatedTag": "Custom CSS is not supported. For testing and other use cases, use [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes).",
"description": "Adds the specified classes to the root element of the component.",
"name": "className",
"optional": true,
"type": "string",
},
{
"description": "An array of expanded item IDs. Each item ID must match the \`id\` property of an item in the \`items\` array.",
"name": "expandedItems",
"optional": true,
"type": "ReadonlyArray<string>",
},
{
"deprecatedTag": "The usage of the \`id\` attribute is reserved for internal use cases. For testing and other use cases,
use [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes). If you must
use the \`id\` attribute, consider setting it on a parent element instead.",
"description": "Adds the specified ID to the root element of the component.",
"name": "id",
"optional": true,
"type": "string",
},
{
"description": "An array of treeview items.
Each item has the following properties:
* \`id\` (string) - The unique identifier of the item.
* \`content\` (React.ReactNode) - The content of the item.
* \`details\` (optional, React.ReactNode) - The details of the item, displayed below the content.
* \`actions\` (optional, React.ReactNode) - Actions related to item. We recommend using button group.
* \`items\` (optional, TreeItem[]) - The nested items of the item.",
"name": "items",
"optional": false,
"type": "ReadonlyArray<TreeviewProps.TreeItem>",
},
{
"description": "If \`true\`, adds guide lines connecting child items to the expanded parent item.",
"name": "showGuideLines",
"optional": true,
"type": "boolean",
},
],
"regions": [],
"releaseStatus": "stable",
}
`;

exports[`Documenter definition for tutorial-panel matches the snapshot: tutorial-panel 1`] = `
{
"dashCaseName": "tutorial-panel",
Expand Down
Loading
Loading