diff --git a/packages/main/src/components/AnalyticalTable/AnalyticalTable.test.tsx b/packages/main/src/components/AnalyticalTable/AnalyticalTable.test.tsx index 55bee2822f0..3942a417806 100644 --- a/packages/main/src/components/AnalyticalTable/AnalyticalTable.test.tsx +++ b/packages/main/src/components/AnalyticalTable/AnalyticalTable.test.tsx @@ -260,5 +260,19 @@ describe('AnalyticalTable', () => { expect(wrapper.render()).toMatchSnapshot(); }); + test('without selection Column', () => { + const wrapper = mountThemedComponent( + + ); + + expect(wrapper.render()).toMatchSnapshot(); + }); + createPassThroughPropsTest(AnalyticalTable); }); diff --git a/packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx b/packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx index f71c358ef8c..61eb96e3712 100644 --- a/packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx +++ b/packages/main/src/components/AnalyticalTable/ColumnHeader/index.tsx @@ -200,7 +200,9 @@ const ColumnHeader: FC = (props) => { ) : (
{openBy}
)} -
+ {column.getResizerProps && ( +
+ )}
); }; diff --git a/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap b/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap index 2db815133bf..3c4cf86cea1 100644 --- a/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap +++ b/packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap @@ -1477,13 +1477,36 @@ exports[`AnalyticalTable Tree Table 1`] = `
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3731,3 +3782,475 @@ exports[`AnalyticalTable test drag and drop of a draggable column 1`] = `
`; + +exports[`AnalyticalTable without selection Column 1`] = ` +
+
+ + Table Title + +
+
+
+
+
+
+
+ + Name + +
+
+
+ + + + Sort Ascending + + + Sort Descending + + + +
+
+
+
+
+ + Age + +
+
+
+ + + + Sort Ascending + + + Sort Descending + + + +
+
+
+
+
+ + Friend Name + +
+
+
+ + + + Sort Ascending + + + Sort Descending + + + +
+
+
+
+
+ + + Friend Age + + +
+
+
+ + + + Sort Ascending + + + Sort Descending + + + +
+
+
+
+
+
+
+ + Fra + +
+
+ + 40 + +
+
+ + MAR + +
+
+ + 28 + +
+
+
+
+ + bla + +
+
+ + 20 + +
+
+ + Nei + +
+
+ + 50 + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`; diff --git a/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx b/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx index f365594c007..d58b45c68fb 100644 --- a/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx +++ b/packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx @@ -86,6 +86,7 @@ export const defaultTable = () => { rowHeight={number('rowHeight', 44)} selectedRowIds={object('selectedRowIds', { 3: true })} onColumnsReordered={action('onColumnsReordered')} + noSelectionColumn={boolean('noSelectionColumn', false)} />
); diff --git a/packages/main/src/components/AnalyticalTable/hooks/useColumnsDependencies.ts b/packages/main/src/components/AnalyticalTable/hooks/useColumnsDependencies.ts index eb27b172669..52cf3757a5c 100644 --- a/packages/main/src/components/AnalyticalTable/hooks/useColumnsDependencies.ts +++ b/packages/main/src/components/AnalyticalTable/hooks/useColumnsDependencies.ts @@ -1,5 +1,12 @@ export const useColumnsDependencies = (hooks) => { hooks.columnsDeps.push((deps, { instance: { state, webComponentsReactProperties } }) => { - return [state.tableClientWidth, state.hiddenColumns, webComponentsReactProperties.scaleWidthMode, webComponentsReactProperties.loading]; + return [ + state.tableClientWidth, + state.hiddenColumns, + webComponentsReactProperties.scaleWidthMode, + webComponentsReactProperties.loading, + webComponentsReactProperties.selectionMode, + webComponentsReactProperties.noSelectionColumn + ]; }); }; diff --git a/packages/main/src/components/AnalyticalTable/hooks/useDynamicColumnWidths.ts b/packages/main/src/components/AnalyticalTable/hooks/useDynamicColumnWidths.ts index a83ce2f9710..26eb17d7552 100644 --- a/packages/main/src/components/AnalyticalTable/hooks/useDynamicColumnWidths.ts +++ b/packages/main/src/components/AnalyticalTable/hooks/useDynamicColumnWidths.ts @@ -1,5 +1,5 @@ -import { DEFAULT_COLUMN_WIDTH } from '../defaults/Column'; import { TableScaleWidthMode } from '@ui5/webcomponents-react/lib/TableScaleWidthMode'; +import { DEFAULT_COLUMN_WIDTH } from '../defaults/Column'; const ROW_SAMPLE_SIZE = 20; const DEFAULT_HEADER_NUM_CHAR = 10; @@ -12,7 +12,7 @@ const approximateContentPxFromCharLength = (charLength) => 8 * charLength; export const useDynamicColumnWidths = (hooks) => { hooks.columns.push((columns, { instance }) => { - if(!instance.state || !instance.rows) { + if (!instance.state || !instance.rows) { return columns; } @@ -31,17 +31,17 @@ export const useDynamicColumnWidths = (hooks) => { const defaultColumnsCount = visibleColumns.length - columnsWithFixedWidth.length; - //check if columns are visible and table has width + // check if columns are visible and table has width if (visibleColumns.length > 0 && totalWidth > 0) { - //set fixedWidth as defaultWidth if visible columns have fixed value + // set fixedWidth as defaultWidth if visible columns have fixed value if (visibleColumns.length === columnsWithFixedWidth.length) { return fixedWidth / visibleColumns.length; } - //spread default columns + // spread default columns if (totalWidth >= fixedWidth + defaultColumnsCount * DEFAULT_COLUMN_WIDTH) { return (totalWidth - fixedWidth) / defaultColumnsCount; } else { - //set defaultWidth for default columns if table is overflowing + // set defaultWidth for default columns if table is overflowing return DEFAULT_COLUMN_WIDTH; } } else { @@ -51,7 +51,7 @@ export const useDynamicColumnWidths = (hooks) => { if (columns.length === 0 || !totalWidth) return columns; - const hasData = rows.some(row => !row.original?.emptyRow); + const hasData = rows.some((row) => !row.original?.emptyRow); if (scaleWidthMode === TableScaleWidthMode.Default || (!hasData && loading)) { const defaultWidth = calculateDefaultTableWidth(); @@ -61,6 +61,15 @@ export const useDynamicColumnWidths = (hooks) => { const rowSample = rows.slice(0, ROW_SAMPLE_SIZE); const columnMeta = visibleColumns.reduce((acc, column) => { + if (column.id === '__ui5wcr__internal_selection_column') { + acc[column.accessor] = { + minHeaderWidth: column.width, + fullWidth: column.width, + contentCharAvg: 0 + }; + return acc; + } + const headerLength = typeof column.Header === 'string' ? column.Header.length : DEFAULT_HEADER_NUM_CHAR; // max character length @@ -131,7 +140,7 @@ export const useDynamicColumnWidths = (hooks) => { const isColumnVisible = (column.isVisible ?? true) && !hiddenColumns.includes(column.accessor); if (isColumnVisible) { const { minHeaderWidth, contentCharAvg } = columnMeta[column.accessor]; - let additionalSpaceFactor = totalCharNum > 0 ? (contentCharAvg / totalCharNum) : 1 / visibleColumns.length; + const additionalSpaceFactor = totalCharNum > 0 ? contentCharAvg / totalCharNum : 1 / visibleColumns.length; const targetWidth = additionalSpaceFactor * availableWidth + minHeaderWidth; diff --git a/packages/main/src/components/AnalyticalTable/hooks/useRowSelectionColumn.tsx b/packages/main/src/components/AnalyticalTable/hooks/useRowSelectionColumn.tsx new file mode 100644 index 00000000000..1f52ada9123 --- /dev/null +++ b/packages/main/src/components/AnalyticalTable/hooks/useRowSelectionColumn.tsx @@ -0,0 +1,70 @@ +import { CheckBox } from '@ui5/webcomponents-react/lib/CheckBox'; +import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode'; +import React from 'react'; +import { PluginHook } from 'react-table'; + +const divStyle = { width: '100%', height: '100%' }; +const customCheckBoxStyling = { + '--_ui5_checkbox_compact_width_height': 'var(--_ui5_checkbox_compact_inner_size)', + '--_ui5_checkbox_width_height': 'var(--_ui5_checkbox_inner_width_height)', + verticalAlign: 'middle' +}; +const noop = () => { + // do nothing +}; + +export const useRowSelectionColumn: PluginHook<{}> = (hooks) => { + hooks.columns.push((columns, { instance }) => { + const { selectionMode, noSelectionColumn } = instance.webComponentsReactProperties; + + if (selectionMode === TableSelectionMode.NONE || noSelectionColumn) { + return columns; + } + + const toggleAllRowsSelected = (e) => { + instance.toggleAllRowsSelected(e.getParameter('checked')); + }; + + return [ + // Let's make a column for selection + { + id: '__ui5wcr__internal_selection_column', + accessor: '__ui5wcr__internal_selection_column', + sortable: false, + groupable: false, + filterable: false, + disableResizing: true, + width: 36, + minWidth: 36, + // The header can use the table's getToggleAllRowsSelectedProps method + // to render a checkbox + // eslint-disable-next-line react/prop-types,react/display-name + Header: ({ getToggleAllRowsSelectedProps }) => { + if (selectionMode === TableSelectionMode.SINGLE_SELECT) { + return null; + } + return ( + + ); + }, + // The cell can use the individual row's getToggleRowSelectedProps method + // to the render a checkbox + // eslint-disable-next-line react/prop-types,react/display-name + Cell: ({ row }) => { + if (selectionMode === TableSelectionMode.SINGLE_SELECT) { + // eslint-disable-next-line react/prop-types + return
; + } + // eslint-disable-next-line react/prop-types + return ; + } + }, + ...columns + ]; + }); +}; +useRowSelectionColumn.pluginName = 'useRowSelectionColumn'; diff --git a/packages/main/src/components/AnalyticalTable/index.tsx b/packages/main/src/components/AnalyticalTable/index.tsx index 7966d741dc7..4d037ccdb94 100644 --- a/packages/main/src/components/AnalyticalTable/index.tsx +++ b/packages/main/src/components/AnalyticalTable/index.tsx @@ -40,6 +40,7 @@ import { DefaultLoadingComponent } from './defaults/LoadingComponent'; import { TablePlaceholder } from './defaults/LoadingComponent/TablePlaceholder'; import { DefaultNoDataComponent } from './defaults/NoDataComponent'; import { useDragAndDrop } from './hooks/useDragAndDrop'; +import { useRowSelectionColumn } from './hooks/useRowSelectionColumn'; import { useTableCellStyling } from './hooks/useTableCellStyling'; import { useTableHeaderGroupStyling } from './hooks/useTableHeaderGroupStyling'; import { useTableHeaderStyling } from './hooks/useTableHeaderStyling'; @@ -93,9 +94,9 @@ export interface TableProps extends CommonProps { noDataText?: string; rowHeight?: number; alternateRowColor?: boolean; + noSelectionColumn?: boolean; // features - filterable?: boolean; sortable?: boolean; groupable?: boolean; @@ -115,7 +116,7 @@ export interface TableProps extends CommonProps { * additional options which will be passed to [react-tableĀ“s useTable hook](https://github.com/tannerlinsley/react-table/blob/master/docs/api.md#table-options) */ reactTableOptions?: object; - tableHooks?: Array>; + tableHooks?: PluginHook[]; subRowsKey?: string; selectedRowIds?: { [key: string]: boolean }; isTreeTable?: boolean; @@ -160,7 +161,8 @@ const AnalyticalTable: FC = forwardRef((props: TableProps, ref: Ref< isTreeTable, alternateRowColor, overscanCount, - scaleWidthMode + scaleWidthMode, + noSelectionColumn } = props; const classes = useStyles({ rowHeight: props.rowHeight }); @@ -206,10 +208,12 @@ const AnalyticalTable: FC = forwardRef((props: TableProps, ref: Ref< isTreeTable, alternateRowColor, scaleWidthMode, - loading + loading, + noSelectionColumn }, ...reactTableOptions }, + useRowSelectionColumn, useAbsoluteLayout, useFilters, useGroupBy, diff --git a/packages/main/src/enums/TableScaleWidthMode.ts b/packages/main/src/enums/TableScaleWidthMode.ts index 3bf44ba6988..5b5e2aff348 100644 --- a/packages/main/src/enums/TableScaleWidthMode.ts +++ b/packages/main/src/enums/TableScaleWidthMode.ts @@ -1,5 +1,17 @@ export enum TableScaleWidthMode { + /* + * Every column without fixed width get's the maximum available space of the table + */ Default = 'Default', + /* + * Every column gets the space it needs for displaying the full header text. If all headers need more space than the + * available table width, horizontal scrolling will be enabled. + * If there is space left, columns with a long content will get more space until there is no more table space left + */ Smart = 'Smart', + /* + * Every column get's the space it needs for displaying it's full header text and full content of all cells. + * If it requires more space than the table has, horizontal scrolling will be enabled. + */ Grow = 'Grow' }