Skip to content

Commit

Permalink
Merge pull request #193 from fedspendingtransparency/ftr/10732-dtui
Browse files Browse the repository at this point in the history
DEV-10732 dtui sticky column for basic table
  • Loading branch information
brianpetway authored Apr 4, 2024
2 parents 1cb3fbd + ee0fcbf commit 5a7f535
Show file tree
Hide file tree
Showing 21 changed files with 240 additions and 38 deletions.
150 changes: 150 additions & 0 deletions .storybook/stories/newTableProp.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React from 'react';
import Table from '../../components/table/Table';

export default {
title: 'Table new props',
component: Table,
};
const Default = (args) =>
<div style={{width:'400px',overflowX: 'scroll'}}>
<Table {...args} />
</div>;
export const Primary = Default.bind({});
Primary.args = { stickyFirstColumn: true,
columns:
[
{
title: 'name',
displayName: 'Budget Function'
},
{
title: 'amount',
displayName: 'Amount'
},
{
title: 'percent',
displayName: '% of Total Amount',
right: true
},
{
title: 'test',
displayName: 'test',
},
{
title: 'mock1',
displayName: 'Mock Data 1',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
]
,
rows: [
[<a href="/">Link</a>, 'mock data', '25%', 'test', 'mock1', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2'],
[<React.Fragment><strong>jsx</strong> content</React.Fragment>, 1234, 'mock data', 'test', 'mock1', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2', 'mock2']
]};
34 changes: 32 additions & 2 deletions .storybook/stories/table.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,39 @@ const updateSort = (field, direction) => {
<Story name='Table without Sorting'>
<BasicTableWrapper>
<Table
stickyFirstColumn={true}
columns={
[
{
title: 'name',
displayName: 'Budget Function'
},
{
title: 'amount',
displayName: 'Amount'
},
{
title: 'percent',
displayName: '% of Total Amount',
right: true
},
{
title: 'test',
displayName: 'test',
},
{
title: 'mock1',
displayName: 'Mock Data 1',
},
{
title: 'mock2',
displayName: 'Mock Data 2',
},
]
}
rows={[
[<a href="/">Link</a>, 'mock data', '25%'],
[<React.Fragment><strong>jsx</strong> content</React.Fragment>, 1234, 'mock data']
[<a href="/">Link</a>, 'mock data', '25%', 'test', 'mock1', 'mock2'],
[<React.Fragment><strong>jsx</strong> content</React.Fragment>, 1234, 'mock data', 'test', 'mock1', 'mock2']
]} />
</BasicTableWrapper>
</Story>
Expand Down
17 changes: 10 additions & 7 deletions components/table/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ const propTypes = {
isStacked: PropTypes.bool,
screenReaderCaption: PropTypes.string,
onClickHandler: PropTypes.func,
isMobile: PropTypes.bool
isMobile: PropTypes.bool,
stickyFirstColumn: PropTypes.bool
};

const defaultProps = {
classNames: '',
isStacked: false
isStacked: false,
stickyFirstColumn: false
};

const Table = (props) => {
Expand All @@ -56,7 +58,6 @@ const Table = (props) => {
props.updateSort(col.title, 'desc');
}
}));

let body;
if (props.loading) {
body = (
Expand Down Expand Up @@ -90,7 +91,7 @@ const Table = (props) => {
}
return (
<>
{props.isStacked && props.updateSort && (
{props.isStacked && props.updateSort && (
<div className="usa-dt-table__stacked-picker">
<label htmlFor="stackedTableSort">Sort By</label>
<Picker
Expand All @@ -99,17 +100,18 @@ const Table = (props) => {
options={union(getTablePickerOptionsAsc, getTablePickerOptionsDesc)} />
</div>
)}
<table className={`usda-table ${stackedClass} ${props.classNames}`}>
<table className={`usda-table ${stackedClass} ${props.classNames}`}>
{props.screenReaderCaption && (
<caption className="usa-dt-sr-only">{props.screenReaderCaption}</caption>
)}
<thead className="usda-table__head">
<tr className="usda-table__row">
{props.columns.map((col) => (
{props.columns.map((col, index) => (
<TableHeader
key={uniqueId()}
currentSort={props.currentSort}
updateSort={props.updateSort}
stickyFirstColumn={props.stickyFirstColumn}
{...col} />
))}
</tr>
Expand All @@ -128,6 +130,7 @@ const Table = (props) => {
className={col?.title ? 'nested-header' : 'empty'}
currentSort={props.currentSort}
updateSort={props.updateSort}
stickyFirstColumn={props.stickyFirstColumn}
{...col} />
))
}
Expand All @@ -136,7 +139,7 @@ const Table = (props) => {
<tbody className="usda-table__body">
{body}
</tbody>
</table>
</table>
</>
);
};
Expand Down
10 changes: 7 additions & 3 deletions components/table/TableData.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const propTypes = {
divider: PropTypes.string,
onClickHandler: PropTypes.func,
isMobile: PropTypes.bool,
atMaxLevel: PropTypes.bool
atMaxLevel: PropTypes.bool,
stickyFirstColumn: PropTypes.bool
};

const TableData = ({
Expand All @@ -28,7 +29,8 @@ const TableData = ({
divider,
onClickHandler,
isMobile,
atMaxLevel
atMaxLevel,
stickyFirstColumn = false
}) => {
const [firstClick, setFirstClick] = useState(false);
const [rowIndexForMessage, setRowIndexForMessage] = useState();
Expand Down Expand Up @@ -88,11 +90,13 @@ const TableData = ({
<TableHeader
className="table-header_body-header"
key={uniqueId()}
stickyFirstColumn={stickyFirstColumn}
{...data} />
:
<td
key={uniqueId()}
className={`usda-table__cell${columns[j]?.right ? ' usda-table__cell_right' : ''}`}>
className={`usda-table__cell${columns[j]?.right ? ' usda-table__cell_right' : ''}
${ (j===0 && stickyFirstColumn) ? ' stickyColumn' : ''}`}>
{columns[j] &&
<div className="usda-table__cell-heading-container">
{isMobile &&
Expand Down
17 changes: 11 additions & 6 deletions components/table/TableHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ const SortIcon = ({
clickedSort,
displayName,
currentSort,
title
title,
stickyFirstColumn = false
}) => {
// highlight the active arrow
const activeAsc = (currentSort?.field === title && currentSort?.direction === 'asc')
? ' table-header__icon_active' : '';
const activeDesc = (currentSort?.field === title && currentSort?.direction === 'desc')
? ' table-header__icon_active' : '';


return (
<div className="table-header__sort">
<button
Expand Down Expand Up @@ -47,7 +50,8 @@ SortIcon.propTypes = {
direction: oneOf(['asc', 'desc']),
field: PropTypes.string
}).isRequired,
clickedSort: PropTypes.func.isRequired
clickedSort: PropTypes.func.isRequired,
stickyFirstColumn: PropTypes.bool
};

const propTypes = {
Expand All @@ -65,7 +69,8 @@ const propTypes = {
subColumnNames: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])),
className: PropTypes.string,
icon: PropTypes.element,
bodyHeader: PropTypes.bool
bodyHeader: PropTypes.bool,
stickyFirstColumn: PropTypes.bool
};

const TableHeaderCell = ({
Expand All @@ -79,7 +84,8 @@ const TableHeaderCell = ({
rowSpan,
subColumnNames = [],
icon = (<></>),
bodyHeader = false
bodyHeader = false,
stickyFirstColumn = false
}) => {
const handleClickedSort = (e, sortOn = title) => {
updateSort(sortOn, e.target.value);
Expand All @@ -90,10 +96,9 @@ const TableHeaderCell = ({
}
return subColumnNames.length ? "1" : "2";
};

return (
<th
className={`${className} table-header${bodyHeader ? ' table-header_body-header' : ''}`}
className={`${className} table-header${bodyHeader ? ' table-header_body-header' : ''} ${stickyFirstColumn === true ? ' stickyColumn' : ''}`}
colSpan={columnSpan}
rowSpan={rowsSpan()}
scope="col">
Expand Down
Loading

0 comments on commit 5a7f535

Please sign in to comment.