diff --git a/src/components/Table/README.md b/src/components/Table/README.md index 9ff7a7db3b..d4c2306e4e 100644 --- a/src/components/Table/README.md +++ b/src/components/Table/README.md @@ -201,7 +201,23 @@ function SelectionTable() { ## Usage with HOC `withTableSettings` -Enables functionality for table column settings. +Enables functionality for table column settings. You can use ut in two forms: + +```jsx +import {Table, withTableSettings} from './withTableSettings'; + +// No options passed +const MyTable1 = withTableSettings(Table); +// or with options +const MyTable1 = withTableSettings({sortable: false})(Table); +``` + +### Options + +| Name | Description | Type | Default | +| :------- | :------------------------------------------------ | :---------------: | :-----: | +| width | Settings' popup width | `number` `string` | | +| sortable | Whether or not add ability to sort settings items | `boolean` | `true` | ### ColumnMeta @@ -214,7 +230,7 @@ Enables functionality for table column settings. | Name | Description | Type | | :----------------- | :---------------------------- | :------------------------------------------: | -| settingsPopupWidth | TableColumnSetup pop-up width | `string` | +| settingsPopupWidth | TableColumnSetup pop-up width | `number` `string` | | settings | Current settings | `TableSettingsData` | | updateSettings | Settings update handl | `(data: TableSettingsData) => Promise` | @@ -232,7 +248,7 @@ type TableSettingsData = Array<{ ```jsx import {Table, withTableSettings} from '@gravity-ui/uikit'; -const MyTable = withTableSettings(Table); +const MyTable = withTableSettings({width: 100, sortable: false})(Table); const data = [ {id: 1, text: 'Hello'}, {id: 2, text: 'World'}, diff --git a/src/components/Table/__stories__/Table.stories.tsx b/src/components/Table/__stories__/Table.stories.tsx index 0ffc4f6873..9b5371256b 100644 --- a/src/components/Table/__stories__/Table.stories.tsx +++ b/src/components/Table/__stories__/Table.stories.tsx @@ -15,6 +15,7 @@ import { TableWithCopy, TableWithSelection, TableWithSettings, + TableWithSettingsFactory, TableWithSorting, columns, data, @@ -144,7 +145,7 @@ const WithTableSelectionTemplate: StoryFn> = (args) => { export const HOCWithTableSelection = WithTableSelectionTemplate.bind({}); // --------------------------------- -const WithTableSettingsTemplate: StoryFn> = (args) => { +const WithTableSettingsTemplate: StoryFn> = (args, context) => { const [settings, setSettings] = React.useState(() => columns.map((x) => ({id: x.id, isSelected: true})), ); @@ -154,9 +155,23 @@ const WithTableSettingsTemplate: StoryFn> = (args) => { [], ); - return ; + if (context.parameters.isFactory) { + return ( + + ); + } else { + return ; + } }; export const HOCWithTableSettings = WithTableSettingsTemplate.bind({}); +export const HOCWithTableSettingsFactory = WithTableSettingsTemplate.bind({}); +HOCWithTableSettingsFactory.parameters = { + isFactory: true, +}; // --------------------------------- const columnsWithSorting = _cloneDeep(columns); diff --git a/src/components/Table/__stories__/utils.tsx b/src/components/Table/__stories__/utils.tsx index 8d8757cb53..51c1ad1967 100644 --- a/src/components/Table/__stories__/utils.tsx +++ b/src/components/Table/__stories__/utils.tsx @@ -78,4 +78,5 @@ export const TableWithAction = withTableActions(Table); export const TableWithCopy = withTableCopy(Table); export const TableWithSelection = withTableSelection(Table); export const TableWithSettings = withTableSettings(Table); +export const TableWithSettingsFactory = withTableSettings({sortable: false})(Table); export const TableWithSorting = withTableSorting(Table); diff --git a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx index 7959fef24c..d90ac7ea42 100644 --- a/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx +++ b/src/components/Table/hoc/withTableSettings/TableColumnSetup/TableColumnSetup.tsx @@ -31,7 +31,7 @@ export interface TableColumnSetupProps { filterable?: boolean; onUpdate: (updated: Item[]) => void; - popupWidth?: string; + popupWidth?: number | string; popupPlacement?: PopperPlacement; getItemTitle?: (item: Item) => TableColumnSetupItem['title']; showStatus?: boolean; diff --git a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx index 1cf2d8f637..41fe0ff373 100644 --- a/src/components/Table/hoc/withTableSettings/withTableSettings.tsx +++ b/src/components/Table/hoc/withTableSettings/withTableSettings.tsx @@ -114,8 +114,16 @@ function prepareUpdateSettings(items: TableColumnSetupItem[]): TableSettingsData })); } +export interface WithTableSettingsOptions { + width?: number | string; + sortable?: boolean; +} + export interface WithTableSettingsProps { - settingsPopupWidth?: string; + /** + * @deprecated Use factory notation: "withTableSettings({width: })(Table)" + */ + settingsPopupWidth?: number | string; settings: TableSettingsData; updateSettings: (data: TableSettingsData) => void; } @@ -123,67 +131,92 @@ export interface WithTableSettingsProps { const b = block('table'); export function withTableSettings( - TableComponent: React.ComponentType & E>, -): React.ComponentType & WithTableSettingsProps & E> { - const componentName = getComponentName(TableComponent); - - const TableWithSettings = ({ - updateSettings, - settings, - columns, - settingsPopupWidth, - ...restTableProps - }: TableProps & WithTableSettingsProps & E) => { - const actualItems = React.useMemo( - () => getActualItems(columns, settings || []), - [columns, settings], - ); - - const onUpdateColumns = React.useCallback( - (newItems: TableColumnSetupItem[]) => { - updateSettings(prepareUpdateSettings(newItems)); - }, - [updateSettings], - ); - - const columnSetupItems = React.useMemo( - () => prepareColumnSetupItems(actualItems), - [actualItems], - ); - - const enhancedColumns = React.useMemo( - () => - enhanceSystemColumn(filterColumns(columns, actualItems), (systemColumn) => { - // eslint-disable-next-line react/display-name - systemColumn.name = () => ( -
- - - - } - /> -
- ); - }), - [actualItems, columnSetupItems, columns, onUpdateColumns, settingsPopupWidth], - ); - - return ( - - , 'columns'> & E)} - columns={enhancedColumns} - /> - - ); - }; - TableWithSettings.displayName = `withTableSettings(${componentName})`; - - return TableWithSettings; + Component: React.ComponentType & E>, +): React.ComponentType & WithTableSettingsProps & E>; +export function withTableSettings( + options?: WithTableSettingsOptions, +): ( + Component: React.ComponentType & E>, +) => React.ComponentType & WithTableSettingsProps & E>; +export function withTableSettings( + ComponentOrOptions?: WithTableSettingsOptions | React.ComponentType & E>, +): + | React.ComponentType & WithTableSettingsProps & E> + | (( + Component: React.ComponentType & E>, + ) => React.ComponentType & WithTableSettingsProps & E>) { + function tableWithSettingsFactory( + TableComponent: React.ComponentType & E>, + {width, sortable}: WithTableSettingsOptions = {}, + ) { + const componentName = getComponentName(TableComponent); + + function TableWithSettings({ + updateSettings, + settings, + columns, + settingsPopupWidth, + ...restTableProps + }: TableProps & WithTableSettingsProps & E) { + const actualItems = React.useMemo( + () => getActualItems(columns, settings || []), + [columns, settings], + ); + + const onUpdateColumns = React.useCallback( + (newItems: TableColumnSetupItem[]) => { + updateSettings(prepareUpdateSettings(newItems)); + }, + [updateSettings], + ); + + const columnSetupItems = React.useMemo( + () => prepareColumnSetupItems(actualItems), + [actualItems], + ); + + const enhancedColumns = React.useMemo( + () => + enhanceSystemColumn(filterColumns(columns, actualItems), (systemColumn) => { + // eslint-disable-next-line react/display-name + systemColumn.name = () => ( +
+ + + + } + /> +
+ ); + }), + [actualItems, columnSetupItems, columns, onUpdateColumns, settingsPopupWidth], + ); + + return ( + + , 'columns'> & E)} + columns={enhancedColumns} + /> + + ); + } + TableWithSettings.displayName = `withTableSettings(${componentName})`; + + return TableWithSettings; + } + + if (typeof ComponentOrOptions === 'function') { + return tableWithSettingsFactory(ComponentOrOptions); + } else { + return (TableComponent: React.ComponentType & E>) => + tableWithSettingsFactory(TableComponent, ComponentOrOptions); + } }