From d1e861520f03ba525982973dd1cceadfa35de467 Mon Sep 17 00:00:00 2001 From: Andrei Zhaleznichenka Date: Fri, 15 Nov 2024 09:35:50 +0100 Subject: [PATCH] refactor: Componentizes table cell types and adds permutations --- pages/table/cell-permutations.page.tsx | 499 ++++++++++++++++++ .../body-cell/disabled-inline-editor.tsx | 3 +- src/table/body-cell/index.tsx | 8 +- src/table/body-cell/td-element.tsx | 4 +- src/table/header-cell/index.tsx | 12 + src/table/header-cell/th-element.tsx | 20 +- src/table/internal.tsx | 60 +-- src/table/no-data-cell.tsx | 2 +- .../progressive-loading/items-loader.tsx | 2 +- src/table/progressive-loading/loader-cell.tsx | 34 ++ src/table/selection/selection-cell.tsx | 71 +++ src/table/thead.tsx | 66 +-- 12 files changed, 685 insertions(+), 96 deletions(-) create mode 100644 pages/table/cell-permutations.page.tsx create mode 100644 src/table/progressive-loading/loader-cell.tsx create mode 100644 src/table/selection/selection-cell.tsx diff --git a/pages/table/cell-permutations.page.tsx b/pages/table/cell-permutations.page.tsx new file mode 100644 index 0000000000..93ecf0b0f3 --- /dev/null +++ b/pages/table/cell-permutations.page.tsx @@ -0,0 +1,499 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React, { useContext, useRef, useState } from 'react'; +import { range } from 'lodash'; + +import { + Box, + Button, + Checkbox, + Container, + ExpandableSection, + FormField, + Header, + Input, + Slider, + SpaceBetween, + StatusIndicator, + TableProps, +} from '~components'; +import { useMergeRefs } from '~components/internal/hooks/use-merge-refs'; +import { TableBodyCell, TableBodyCellProps } from '~components/table/body-cell'; +import { TableHeaderCell, TableHeaderCellProps } from '~components/table/header-cell'; +import { NoDataCell } from '~components/table/no-data-cell'; +import { TableLoaderCell, TableLoaderCellProps } from '~components/table/progressive-loading/loader-cell'; +import { TableBodySelectionCell, TableHeaderSelectionCell } from '~components/table/selection/selection-cell'; +import { StickyColumnsModel, useStickyColumns } from '~components/table/sticky-columns'; + +import AppContext, { AppContextType } from '../app/app-context'; +import ScreenshotArea from '../utils/screenshot-area'; + +type PageContext = React.Context< + AppContextType<{ + wrapLines?: boolean; + verticalAlignTop?: boolean; + sortingDisabled?: boolean; + resizableColumns?: boolean; + resizableColumnWidth?: string; + isExpandable?: boolean; + isExpanded?: boolean; + isEditable?: boolean; + stripedRows?: boolean; + hasSelection?: boolean; + multiSelection?: boolean; + hasFooter?: boolean; + stickyColumnsFirst?: string; + stickyColumnsLast?: string; + tableEmpty?: boolean; + tableLoading?: boolean; + }> +>; + +const columns = range(0, 10).map(index => index + 1); + +export default function InlineEditorPermutations() { + const { settings, setUrlParams } = usePageSettings(); + return ( + +

Table cell permutations

+ + + + + + setUrlParams({ wrapLines: event.detail.checked })} + > + Wrap lines + + + setUrlParams({ isExpandable: event.detail.checked })} + > + Is expandable + + + setUrlParams({ isExpanded: event.detail.checked })} + > + Is expanded + + + setUrlParams({ isEditable: event.detail.checked })} + > + Editable + + + setUrlParams({ sortingDisabled: event.detail.checked })} + > + Sorting disabled + + + setUrlParams({ verticalAlignTop: event.detail.checked })} + > + Vertical align top + + + setUrlParams({ stripedRows: event.detail.checked })} + > + Striped rows + + + setUrlParams({ hasSelection: event.detail.checked })} + > + Has selection + + + setUrlParams({ multiSelection: event.detail.checked })} + > + Multi selection + + + setUrlParams({ hasFooter: event.detail.checked })} + > + Has footer + + + setUrlParams({ resizableColumns: event.detail.checked })} + > + Resizable columns + + + setUrlParams({ tableEmpty: event.detail.checked })} + > + Table empty + + + setUrlParams({ tableLoading: event.detail.checked })} + > + Table loading + + + + + + setUrlParams({ resizableColumnWidth: event.detail.value.toString() })} + min={50} + max={300} + /> + + + + setUrlParams({ stickyColumnsFirst: event.detail.value.toString() })} + min={0} + max={3} + /> + + + + setUrlParams({ stickyColumnsLast: event.detail.value.toString() })} + min={0} + max={3} + /> + + + + + + Standard cells}> + + + +
+ ); +} + +function StandardCellsTable() { + const { settings } = usePageSettings(); + const containerRefObject = useRef(null); + const containerRef = useMergeRefs(containerRefObject, settings.stickyState.refs.wrapper); + const tableRefObject = useRef(null); + const tableRef = useMergeRefs(tableRefObject, settings.stickyState.refs.table); + return ( +
+ + + + + + {settings.tableEmpty || settings.tableLoading ? ( + + + + ) : ( + <> + + + + + + + + + + + + + )} + +
+
+ ); +} + +function TextHeaders( + props: Partial> & { + stickyState: StickyColumnsModel; + resizableColumnWidth?: number; + isExpandable?: boolean; + hasSelection?: boolean; + multiSelection?: boolean; + } +) { + return ( + + {props.hasSelection && ( + {}} + columnId="selection" + getSelectAllProps={ + props.multiSelection + ? () => ({ + name: 'select-all', + disabled: false, + selectionType: 'multi', + indeterminate: true, + checked: false, + onChange: () => {}, + }) + : undefined + } + /> + )} + {columns.map(index => ( + + {`Header cell content ${index}${index === 8 ? ' with longer text' : ''}`} + + ))} + + ); +} + +function TextColumns( + props: Partial> & { + level: number; + stickyState: StickyColumnsModel; + isExpandable?: boolean; + isExpanded?: boolean; + multiSelection?: boolean; + } +) { + return ( + + {props.hasSelection && ( + {}, + }} + /> + )} + {columns.map(index => ( + + {`Body cell content ${index}${index === 1 ? ` (L=${props.level})` : ''}${index === 8 ? ' with longer text' : ''}`} + + ))} + + ); +} + +function LoaderColumns( + props: Partial> & { + level: number; + stickyState: StickyColumnsModel; + loadingStatus: TableProps.LoadingStatus; + } +) { + return ( + + {props.hasSelection && ( + + )} + {columns.map(index => ( + } + renderLoaderLoading={() => Loading more} + renderLoaderError={() => Error when loading more} + /> + ))} + + ); +} + +function PlaygroundHeaderCell( + props: Partial> & { + children: React.ReactNode; + colIndex: number; + resizableColumnWidth?: number; + stickyState: StickyColumnsModel; + sortable?: boolean; + activeSorting?: boolean; + } +) { + const column: TableProps.ColumnDefinition = { + id: props.colIndex.toString(), + header: props.children, + cell: () => '', + sortingField: props.sortable ? 'field' : undefined, + }; + return ( +