Skip to content

Commit

Permalink
feat(component): refactor to show drag icon
Browse files Browse the repository at this point in the history
  • Loading branch information
animesh1987 committed Jan 5, 2021
1 parent 797bb63 commit 155abb9
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 47 deletions.
10 changes: 10 additions & 0 deletions packages/big-design/src/components/Table/HeaderCell/HeaderCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export interface HeaderCheckboxCellProps {
stickyHeader?: boolean;
}

export interface DragIconCellProps {
actionsRef: RefObject<HTMLDivElement>;
}

const InternalHeaderCell = <T extends TableItem>({
children,
column,
Expand Down Expand Up @@ -78,4 +82,10 @@ export const HeaderCheckboxCell: React.FC<HeaderCheckboxCellProps> = memo(({ sti
return <StyledTableHeaderCheckbox stickyHeader={stickyHeader} stickyHeight={actionsSize.height} />;
});

export const DragIconHeaderCell: React.FC<DragIconCellProps> = memo(({ actionsRef }) => {
const actionsSize = useComponentSize(actionsRef);

return <StyledTableHeaderCell stickyHeight={actionsSize.height} />;
});

export const HeaderCell = typedMemo(InternalHeaderCell);
8 changes: 8 additions & 0 deletions packages/big-design/src/components/Table/Row/Row.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DragIndicatorIcon } from '@bigcommerce/big-design-icons';
import React, { forwardRef, TableHTMLAttributes } from 'react';

import { typedMemo } from '../../../utils';
Expand All @@ -13,6 +14,7 @@ export interface RowProps<T> extends TableHTMLAttributes<HTMLTableRowElement> {
isSelectable?: boolean;
item: T;
columns: Array<TableColumn<T>>;
showDragIcon?: boolean;
onItemSelect?(item: T): void;
}

Expand All @@ -27,6 +29,7 @@ const InternalRow = <T extends TableItem>({
isSelectable = false,
isSelected = false,
item,
showDragIcon = false,
onItemSelect,
...rest
}: RowProps<T> & PrivateProps) => {
Expand All @@ -40,6 +43,11 @@ const InternalRow = <T extends TableItem>({

return (
<StyledTableRow isSelected={isSelected} ref={forwardedRef} isDragging={isDragging} {...rest}>
{showDragIcon && (
<DataCell>
<DragIndicatorIcon />
</DataCell>
)}
{isSelectable && (
<DataCell key="data-checkbox" isCheckbox={true}>
<Checkbox checked={isSelected} hiddenLabel label={label} onChange={onChange} />
Expand Down
90 changes: 51 additions & 39 deletions packages/big-design/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Actions } from './Actions';
import { Body } from './Body';
import { Head } from './Head';
import { HeaderCell } from './HeaderCell';
import { HeaderCheckboxCell } from './HeaderCell/HeaderCell';
import { DragIconHeaderCell, HeaderCheckboxCell } from './HeaderCell/HeaderCell';
import { Row } from './Row';
import { StyledTable, StyledTableFigure } from './styled';
import { TableColumn, TableItem, TableProps } from './types';
Expand All @@ -19,13 +19,13 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
className,
columns,
actions,
dragAndDrop,
emptyComponent,
headerless = false,
id,
itemName,
items,
keyField = 'id',
onRowDrop,
pagination,
selectable,
sortable,
Expand Down Expand Up @@ -92,9 +92,11 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
return;
}

dragAndDrop && dragAndDrop.onDragEnd(source.index, destination.index);
if (typeof onRowDrop === 'function') {
onRowDrop(source.index, destination.index);
}
},
[dragAndDrop],
[onRowDrop],
);

const shouldRenderActions = () => {
Expand All @@ -112,6 +114,7 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
const renderHeaders = () => (
<Head hidden={headerless}>
<tr>
{typeof onRowDrop === 'function' && <DragIconHeaderCell actionsRef={actionsRef} />}
{isSelectable && <HeaderCheckboxCell stickyHeader={stickyHeader} actionsRef={actionsRef} />}

{columns.map((column, index) => {
Expand All @@ -138,37 +141,42 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
</Head>
);

const renderDroppableItems = () => (
<Droppable droppableId="bd-droppable">
{(provided) => (
<Body withFirstRowBorder={headerless} ref={provided.innerRef} {...provided.droppableProps}>
{items.map((item: T, index) => {
const key = getItemKey(item, index);
const isSelected = selectedItems.has(item);

return (
<Draggable key={key} draggableId={String(key)} index={index}>
{(provided, snapshot) => (
<Row
isDragging={snapshot.isDragging}
{...provided.dragHandleProps}
{...provided.draggableProps}
ref={provided.innerRef}
columns={columns}
isSelectable={isSelectable}
isSelected={isSelected}
item={item}
onItemSelect={onItemSelect}
showDragIcon={true}
/>
)}
</Draggable>
);
})}
{provided.placeholder}
</Body>
)}
</Droppable>
);

const renderItems = () =>
dragAndDrop ? (
<Droppable droppableId="priority-droppable">
{(provided) => (
<Body withFirstRowBorder={headerless} ref={provided.innerRef} {...provided.droppableProps}>
{items.map((item: T, index) => {
const key = getItemKey(item, index);
const isSelected = selectedItems.has(item);

return (
<Draggable key={key} draggableId={String(key)} index={index}>
{(provided, snapshot) => (
<Row
isDragging={snapshot.isDragging}
{...provided.dragHandleProps}
{...provided.draggableProps}
ref={provided.innerRef}
columns={columns}
isSelectable={isSelectable}
isSelected={isSelected}
item={item}
onItemSelect={onItemSelect}
/>
)}
</Draggable>
);
})}
{provided.placeholder}
</Body>
)}
</Droppable>
onRowDrop ? (
renderDroppableItems()
) : (
<Body withFirstRowBorder={headerless}>
{items.map((item: T, index) => {
Expand Down Expand Up @@ -197,6 +205,13 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
return null;
};

const renderWithDragDropContext = () => (
<DragDropContext onDragEnd={onDragEnd}>
{renderHeaders()}
{renderItems()}
</DragDropContext>
);

return (
<>
{shouldRenderActions() && (
Expand All @@ -213,11 +228,8 @@ const InternalTable = <T extends TableItem>(props: TableProps<T>): React.ReactEl
/>
)}
<StyledTable {...rest} id={tableIdRef.current}>
{dragAndDrop ? (
<DragDropContext onDragEnd={onDragEnd}>
{renderHeaders()}
{renderItems()}
</DragDropContext>
{onRowDrop ? (
renderWithDragDropContext()
) : (
<>
{renderHeaders()}
Expand Down
6 changes: 1 addition & 5 deletions packages/big-design/src/components/Table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ export interface TableSelectable<T> {
onSelectionChange(selectedItems: T[]): void;
}

export interface TableDraggable {
onDragEnd(from: number, to: number): void;
}

export type TableSortDirection = 'ASC' | 'DESC';

export interface TableSortable<T> {
Expand Down Expand Up @@ -42,12 +38,12 @@ export type TablePaginationProps = Omit<PaginationProps, keyof MarginProps>;
export interface TableProps<T> extends React.TableHTMLAttributes<HTMLTableElement> {
actions?: React.ReactNode;
columns: Array<TableColumn<T>>;
dragAndDrop?: TableDraggable;
emptyComponent?: React.ReactElement;
headerless?: boolean;
itemName?: string;
items: T[];
keyField?: string;
onRowDrop?(from: number, to: number): void;
pagination?: TablePaginationProps;
selectable?: TableSelectable<T>;
sortable?: TableSortable<T>;
Expand Down
4 changes: 1 addition & 3 deletions packages/docs/pages/Table/TablePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,7 @@ const TablePage = () => {
]}
items={items}
itemName="Products"
dragAndDrop={{
onDragEnd,
}}
onRowDrop={onDragEnd}
/>
);
}}
Expand Down

0 comments on commit 155abb9

Please sign in to comment.