Skip to content

Commit

Permalink
feat(Table): review fixes 2
Browse files Browse the repository at this point in the history
  • Loading branch information
alx-chernigin committed Oct 22, 2024
1 parent f63db62 commit 38d9f38
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 69 deletions.
34 changes: 34 additions & 0 deletions src/components/RowActions/ActionsCell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';

import type {CellContext} from '@tanstack/react-table';

import {RowActions} from './RowActions';
import type {TableActionsSettings} from './types';

export const ACTIONS_COLUMN_ID = '_actions';

interface ActionsCellProps<TValue extends unknown> extends TableActionsSettings<TValue> {
cellContext: CellContext<TValue, unknown>;
}

export const ActionsCell = <TValue extends unknown>({
getRowActions,
renderRowActions,
rowActionsSize,
cellContext,
}: ActionsCellProps<TValue>) => {
const {original: item, index} = cellContext.row;

if (renderRowActions) {
return renderRowActions({row: cellContext.row});
}

return (
<RowActions<TValue>
item={item}
index={index}
getRowActions={getRowActions}
rowActionsSize={rowActionsSize}
/>
);
};
96 changes: 59 additions & 37 deletions src/components/RowActions/RowActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,59 @@ const isActionGroup = <TValue extends unknown>(
return Array.isArray((config as TableActionGroup<TValue>).items);
};

interface RowActionsMenuProps<TValue extends unknown> {
size: TableActionsSettings<TValue>['rowActionsSize'];
item: TValue;
actions: TableActionConfig<TValue>[];
onMenuItemClick: () => unknown;
}

const RowActionsMenu = <TValue extends unknown>({
item,
actions,
size,
onMenuItemClick,
}: RowActionsMenuProps<TValue>) => {
const renderPopupMenuItem = (action: TableActionConfig<TValue>, index: number) => {
if (isActionGroup(action)) {
return (
<Menu.Group key={index} label={action.title}>
{action.items.map(renderPopupMenuItem)}
</Menu.Group>
);
}

const {text, icon, handler, href, ...restProps} = action;

const handleMenuItemClick = (
event: React.MouseEvent<HTMLDivElement | HTMLAnchorElement, MouseEvent>,
) => {
event.stopPropagation();
handler(item, index, event);
onMenuItemClick();
};

return (
<Menu.Item
key={index}
onClick={handleMenuItemClick}
href={typeof href === 'function' ? href(item, index) : href}
iconStart={icon}
className={b('popup-menu-item')}
{...restProps}
>
{text}
</Menu.Item>
);
};

return (
<Menu className={b('popup-menu')} size={size}>
{actions.map(renderPopupMenuItem)}
</Menu>
);
};

export const RowActions = <TValue extends unknown>({
index: rowIndex,
item,
Expand Down Expand Up @@ -62,40 +115,6 @@ export const RowActions = <TValue extends unknown>({
return null;
}

const renderPopupMenuItem = (action: TableActionConfig<TValue>, index: number) => {
if (isActionGroup(action)) {
return (
<Menu.Group key={index} label={action.title}>
{action.items.map(renderPopupMenuItem)}
</Menu.Group>
);
}

const {text, icon, handler, href, ...restProps} = action;

const handleMenuItemClick = (
event: React.MouseEvent<HTMLDivElement | HTMLAnchorElement, MouseEvent>,
) => {
event.stopPropagation();
handler(item, index, event);

setIsPopupOpen(false);
};

return (
<Menu.Item
key={index}
onClick={handleMenuItemClick}
href={typeof href === 'function' ? href(item, index) : href}
iconStart={icon}
className={b('popup-menu-item')}
{...restProps}
>
{text}
</Menu.Item>
);
};

return (
<div className={b()}>
<Popup
Expand All @@ -111,9 +130,12 @@ export const RowActions = <TValue extends unknown>({
event.stopPropagation();
}}
>
<Menu className={b('popup-menu')} size={rowActionsSize}>
{actions.map(renderPopupMenuItem)}
</Menu>
<RowActionsMenu
item={item}
actions={actions}
size={rowActionsSize}
onMenuItemClick={() => setIsPopupOpen(false)}
/>
</div>
</Popup>
<Button
Expand Down
1 change: 1 addition & 0 deletions src/components/RowActions/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export type * from './types';
export {RowActions} from './RowActions';
export {ActionsCell} from './ActionsCell';
38 changes: 6 additions & 32 deletions src/constants/actionsColumn.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,22 @@
import React from 'react';

import type {CellContext, ColumnDef, ColumnDefTemplate} from '@tanstack/react-table';
import type {ColumnDef} from '@tanstack/react-table';

import type {TableActionsSettings} from '../components';
import {RowActions} from '../components';
import {ActionsCell} from '../components';

export const ACTIONS_COLUMN_ID = '_actions';
const ACTIONS_COLUMN_SIZE = 44;

export const getActionsCell = <TData extends unknown>({
getRowActions,
renderRowActions,
rowActionsSize,
}: TableActionsSettings<TData>): ColumnDefTemplate<CellContext<TData, unknown>> => {
const ActionsCell = (props: CellContext<TData, unknown>) => {
const {original: item, index} = props.row;

if (renderRowActions) {
return renderRowActions({row: props.row});
}

return (
<RowActions<TData>
item={item}
index={index}
getRowActions={getRowActions}
rowActionsSize={rowActionsSize}
/>
);
};

ActionsCell.displayName = 'ActionsCell';
return ActionsCell;
};

export const getActionsColumn = <TData extends unknown>(
export const getActionsColumn = <TValue extends unknown>(
columnId = ACTIONS_COLUMN_ID,
options: TableActionsSettings<TData>,
): ColumnDef<TData> => {
options: TableActionsSettings<TValue>,
): ColumnDef<TValue> => {
return {
id: columnId,
header: '',
size: ACTIONS_COLUMN_SIZE,
minSize: ACTIONS_COLUMN_SIZE,
cell: getActionsCell<TData>(options),
cell: (props) => <ActionsCell {...options} cellContext={props} />,
};
};

0 comments on commit 38d9f38

Please sign in to comment.