Skip to content

Commit

Permalink
feat: add support for selectable CardView in DataTable (openedx#1698)
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorrusakov authored Nov 21, 2022
1 parent 0ec9ed5 commit 5ffc3c7
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 20 deletions.
10 changes: 7 additions & 3 deletions src/Card/Card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ a .pgn__card {
background-color: $white;
}

%pgn__card-focused {
box-shadow: $level-1-box-shadow;
outline: none;
border-color: $card-border-focus-color;
}

.pgn__card {
@include pgn-box-shadow(1, "down");

Expand All @@ -281,9 +287,7 @@ a .pgn__card {

&:focus,
&.focus {
box-shadow: $level-1-box-shadow;
outline: none;
border-color: $card-border-focus-color;
@extend %pgn__card-focused;
}
}

Expand Down
79 changes: 69 additions & 10 deletions src/DataTable/CardView.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,52 @@
import React from 'react';
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import DataTableContext from './DataTableContext';
import { useRows } from './hooks';
import { selectColumn } from './utils/getVisibleColumns';
import { CardGrid } from '..';

function CardItem({
row,
prepareRow,
isSelectable,
SelectionComponent,
CardComponent,
selectionPlacement,
}) {
prepareRow(row);
const { isSelected } = row;

if (isSelectable && SelectionComponent) {
return (
<div className={classNames(
'pgn__data-table__selectable-card',
{
'is-selected': isSelected,
'selection-right': selectionPlacement === 'right',
'selection-left': selectionPlacement !== 'right',
},
)}
>
<CardComponent {...row} />
<SelectionComponent row={row} />
</div>
);
}

return <CardComponent {...row} />;
}

function CardView({
columnSizes, CardComponent, className,
columnSizes, CardComponent, className, selectionPlacement,
}) {
const {
getTableProps, prepareRow, displayRows,
} = useRows();

const renderCards = () => displayRows.map((row) => {
prepareRow(row);
return (
<CardComponent {...row} key={row.id} />
);
});
const { isSelectable, manualSelectColumn } = useContext(DataTableContext);
// use the same component for card selection that is used for row selection
// otherwise view switching might break if row selection uses component that supports backend filtering / sorting
const selectionComponent = manualSelectColumn?.Cell || selectColumn.Cell;

if (!getTableProps) {
return null;
Expand All @@ -27,18 +57,45 @@ function CardView({
className={classNames('pgn__data-table-card-view', className)}
columnSizes={columnSizes}
>
{renderCards()}
{displayRows.map((row) => (
<CardItem
key={row.id}
CardComponent={CardComponent}
SelectionComponent={selectionComponent}
isSelectable={isSelectable}
row={row}
prepareRow={prepareRow}
selectionPlacement={selectionPlacement}
/>
))}
</CardGrid>
);
}

CardItem.defaultProps = {
SelectionComponent: undefined,
};

CardItem.propTypes = {
row: PropTypes.shape({
getToggleRowSelectedProps: PropTypes.func,
isSelected: PropTypes.bool,
}).isRequired,
prepareRow: PropTypes.func.isRequired,
isSelectable: PropTypes.bool.isRequired,
CardComponent: PropTypes.func.isRequired,
SelectionComponent: PropTypes.func,
selectionPlacement: PropTypes.oneOf(['right', 'left']).isRequired,
};

CardView.defaultProps = {
columnSizes: {
xs: 12,
lg: 6,
xl: 4,
},
className: '',
selectionPlacement: 'right',
};

CardView.propTypes = {
Expand All @@ -58,6 +115,8 @@ CardView.propTypes = {
/** Your card component must be individualized to your table.
* It will be called with props from the "row" of data it will display */
CardComponent: PropTypes.func.isRequired,
/** If the Cards are selectable this prop determines from which side of the Card to show selection component. */
selectionPlacement: PropTypes.oneOf(['left', 'right']),
};

export default CardView;
34 changes: 34 additions & 0 deletions src/DataTable/DataTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,37 @@ $data-table-pagination-dropdown-min-width: 6rem !default;
box-shadow: $level-1-box-shadow;
border-radius: 4px;
}

.pgn__data-table__selectable-card {
display: flex;
align-items: flex-start;
flex-grow: 1;

&.is-selected {
> :first-child {
@extend %pgn__card-focused;
}
}

&.selection-right {
> :first-child {
[dir="rtl"] & {
margin-left: map_get($spacers, 2);
}

[dir="ltr"] & {
margin-right: map_get($spacers, 2);
}
}
}

&.selection-left {
flex-direction: row-reverse;
}
}

.pgn__data-table__controlled-select {
display: flex;
align-content: center;
padding: map_get($spacers, 1);
}
Loading

0 comments on commit 5ffc3c7

Please sign in to comment.