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
1 change: 1 addition & 0 deletions build-tools/utils/pluralize.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const pluralizationMap = {
CodeEditor: 'CodeEditors',
CollectionPreferences: 'CollectionPreferences',
ColumnLayout: 'ColumnLayouts',
ComparisonTable: 'ComparisonTables',
Container: 'Containers',
ContentLayout: 'ContentLayouts',
CopyToClipboard: 'CopyToClipboards',
Expand Down
79 changes: 79 additions & 0 deletions pages/comparison-table/simple.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import * as React from 'react';

import Box from '~components/box';
import ComparisonTable, { ComparisonTableProps } from '~components/comparison-table';
import SpaceBetween from '~components/space-between';
import StatusIndicator from '~components/status-indicator';

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

const attributes: ComparisonTableProps['attributes'] = [
{ id: 'engine', label: 'Database engine' },
{ id: 'vcpu', label: 'vCPU' },
{ id: 'memory', label: 'Memory' },
{
id: 'multiAz',
label: 'Multi-AZ',
render: value => (
<StatusIndicator type={value ? 'success' : 'stopped'}>{value ? 'Enabled' : 'Disabled'}</StatusIndicator>
),
},
{ id: 'storage', label: 'Max storage' },
];

const entities: ComparisonTableProps['entities'] = [
{
id: 'db-r6g',
title: 'db.r6g.large',
data: { engine: 'MySQL', vcpu: 2, memory: '16 GiB', multiAz: true, storage: '64 TiB' },
},
{
id: 'db-r6g-xl',
title: 'db.r6g.xlarge',
data: { engine: 'MySQL', vcpu: 4, memory: '32 GiB', multiAz: true, storage: '64 TiB' },
},
{
id: 'db-r6g-2xl',
title: 'db.r6g.2xlarge',
data: { engine: 'MySQL', vcpu: 8, memory: '64 GiB', multiAz: false, storage: '64 TiB' },
},
];

export default function ComparisonTablePage() {
const [highlight, setHighlight] = React.useState(true);
const [sticky, setSticky] = React.useState(true);

return (
<>
<h1>Comparison table (WIP)</h1>
<SpaceBetween size="l">
<SpaceBetween direction="horizontal" size="m">
<label>
<input type="checkbox" checked={highlight} onChange={e => setHighlight(e.target.checked)} /> Highlight
differences
</label>
<label>
<input type="checkbox" checked={sticky} onChange={e => setSticky(e.target.checked)} /> Sticky attribute
column
</label>
</SpaceBetween>

<ScreenshotArea>
<ComparisonTable
ariaLabel="Instance type comparison"
attributeColumnHeader="Attribute"
attributes={attributes}
entities={entities}
highlightDifferences={highlight}
stickyAttributeColumn={sticky}
/>
</ScreenshotArea>

<Box variant="h2">Empty state</Box>
<ComparisonTable attributes={[]} entities={[]} ariaLabel="Empty comparison" />
</SpaceBetween>
</>
);
}
1 change: 1 addition & 0 deletions src/__tests__/required-props-for-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { defaultSplitPanelContextProps } from '../split-panel/__tests__/helpers'
const defaultProps: Record<string, Record<string, any>> = {
tabs: { tabs: [] },
table: { columnDefinitions: [] },
'comparison-table': { attributes: [], entities: [] },
cards: { cardDefinition: {} },
autosuggest: { options: [], enteredPrefix: '' },
'anchor-navigation': { anchors: [] },
Expand Down
203 changes: 203 additions & 0 deletions src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10214,6 +10214,115 @@ and the maximum number of columns as defined by the \`columns\` property.",
}
`;

exports[`Components definition for comparison-table matches the snapshot: comparison-table 1`] = `
{
"dashCaseName": "comparison-table",
"description": "ComparisonTable renders a side-by-side comparison of two or more entities: attributes are
rendered as rows, entities as columns, with a sticky attribute column and optional
highlighting of rows whose values differ across entities.

This is a work-in-progress (v0) component built as a thin, opt-in composition over the
existing Table component.",
"events": [],
"functions": [],
"name": "ComparisonTable",
"properties": [
{
"description": "Provides an accessible name for the underlying table, announced by assistive technology.",
"name": "ariaLabel",
"optional": true,
"type": "string",
},
{
"defaultValue": "''",
"description": "Header text rendered above the sticky attribute (first) column.
Defaults to an empty string.",
"name": "attributeColumnHeader",
"optional": true,
"type": "string",
},
{
"description": "The attributes to compare across entities. Each attribute is rendered as a **row**.

The order of this array is the order the rows appear in. Use the \`render\` function on an
attribute to customize how the value for each entity is displayed.",
"name": "attributes",
"optional": false,
"type": "ReadonlyArray<ComparisonTableProps.Attribute>",
},
{
"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": "The entities being compared. Each entity is rendered as a **column** next to the sticky
attribute column.

Every entity exposes its per-attribute values through the \`data\` map, keyed by attribute \`id\`.",
"name": "entities",
"optional": false,
"type": "ReadonlyArray<ComparisonTableProps.Entity>",
},
{
"defaultValue": "false",
"description": "When \`true\`, attribute rows whose values are not identical across all entities are visually
emphasized so differences stand out.

Equality is determined with \`Object.is\` against the raw \`entity.data[attribute.id]\` values.
Rows with a custom \`render\` are still compared using their raw \`data\` values, so keep the
\`data\` values comparable (primitives) when relying on this feature.",
"name": "highlightDifferences",
"optional": true,
"type": "boolean",
},
{
"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",
},
{
"defaultValue": "true",
"description": "Whether the attribute (first) column is pinned to the inline-start edge while the entity
columns scroll horizontally. Defaults to \`true\`.",
"name": "stickyAttributeColumn",
"optional": true,
"type": "boolean",
},
{
"defaultValue": "'container'",
"description": "The visual variant of the comparison table.

- \`"container"\` (default) — renders inside a bordered container.
- \`"embedded"\` — removes the outer container border for embedding in another surface.
- \`"borderless"\` — removes borders entirely.
- \`"stacked"\` — for use in a vertically stacked set of containers.",
"inlineType": {
"name": "ComparisonTableProps.Variant",
"type": "union",
"values": [
"container",
"embedded",
"stacked",
"borderless",
],
},
"name": "variant",
"optional": true,
"type": "string",
},
],
"regions": [],
"releaseStatus": "stable",
}
`;

exports[`Components definition for container matches the snapshot: container 1`] = `
{
"dashCaseName": "container",
Expand Down Expand Up @@ -39171,6 +39280,53 @@ Note that, despite its typings, this may return null for group items since group
],
"name": "ColumnLayoutWrapper",
},
{
"methods": [
{
"description": "Returns all attribute (row header) label elements.",
"name": "findAttributeLabels",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "Array",
"typeArguments": [
{
"name": "ElementWrapper<HTMLElement>",
},
],
},
},
{
"description": "Returns all cells that are highlighted because their attribute row differs across entities.",
"name": "findHighlightedCells",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "Array",
"typeArguments": [
{
"name": "ElementWrapper<HTMLElement>",
},
],
},
},
{
"description": "Returns all rendered rows of the underlying table (one per attribute).",
"name": "findRows",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "Array",
"typeArguments": [
{
"name": "ElementWrapper<HTMLElement>",
},
],
},
},
],
"name": "ComparisonTableWrapper",
},
{
"methods": [
{
Expand Down Expand Up @@ -50181,6 +50337,53 @@ Note that, despite its typings, this may return null for group items since group
],
"name": "ColumnLayoutWrapper",
},
{
"methods": [
{
"description": "Returns all attribute (row header) label elements.",
"name": "findAttributeLabels",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "MultiElementWrapper",
"typeArguments": [
{
"name": "ElementWrapper",
},
],
},
},
{
"description": "Returns all cells that are highlighted because their attribute row differs across entities.",
"name": "findHighlightedCells",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "MultiElementWrapper",
"typeArguments": [
{
"name": "ElementWrapper",
},
],
},
},
{
"description": "Returns all rendered rows of the underlying table (one per attribute).",
"name": "findRows",
"parameters": [],
"returnType": {
"isNullable": false,
"name": "MultiElementWrapper",
"typeArguments": [
{
"name": "ElementWrapper",
},
],
},
},
],
"name": "ComparisonTableWrapper",
},
{
"methods": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ exports[`test-utils selectors 1`] = `
"awsui_column-layout_vvxn7",
"awsui_item_zqq3x",
],
"comparison-table": [
"awsui_attribute-label_gfu3l",
"awsui_cell-highlighted_gfu3l",
"awsui_root_gfu3l",
],
"container": [
"awsui_content-inner_1mwlm",
"awsui_content-wrapper_14iqq",
Expand Down
Loading
Loading