Skip to content

Commit b750a9d

Browse files
authored
Merge pull request #238 from fedspendingtransparency/ftr/DEV12443
DEV-12443 updated mobile table
2 parents 22d646f + d86aca6 commit b750a9d

File tree

135 files changed

+371
-109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+371
-109
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-disable array-callback-return */
2+
/* eslint-disable consistent-return */
3+
/**
4+
* MobileRowSlider.jsx
5+
* not a true new component, created to avoid using useState in a .map
6+
* Created by Nick Torres 5/14/2025
7+
*/
8+
9+
import React, { useState } from 'react';
10+
import PropTypes from 'prop-types';
11+
import { uniqueId } from 'lodash';
12+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
13+
import { faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons';
14+
import TableHeader from './TableHeader';
15+
16+
const propTypes = {
17+
row: PropTypes.array,
18+
columns: PropTypes.array,
19+
iValue: PropTypes.number,
20+
firstClick: PropTypes.bool,
21+
rowIndexForMessage: PropTypes.number
22+
};
23+
const MobileRowSlider = (props) => {
24+
const [rowOpen, setRowOpen] = useState(false);
25+
const toReturn = props.columns.length >= 6
26+
? (
27+
<div className={`collapsible-row-div ${rowOpen ? `row-opened` : ''}`}>
28+
{rowOpen && (
29+
<div className="collapsible-row--content">
30+
<div className="collapsible-row--content-wrapper">
31+
{props.row.map((data, j) => {
32+
if (j >= 6) {
33+
return (
34+
props.columns[j]?.bodyHeader
35+
? (
36+
<TableHeader
37+
className="table-header_body-header"
38+
key={uniqueId()}
39+
stickyFirstColumn={props.stickyFirstColumn}
40+
index={j}
41+
{...data} />
42+
)
43+
: (
44+
<div
45+
key={uniqueId()}
46+
className={`usda-table__cell${props.columns[j]?.right ? ' usda-table__cell_right' : ''}
47+
${(j === 0 && props.stickyFirstColumn) ? ' stickyColumn' : ''} `}>
48+
{props.columns[j]
49+
&& (
50+
<div className="usda-table__cell-heading-container">
51+
<div className="usda-table__cell-heading">{props.columns[j].displayName}</div>
52+
{(props.firstClick && j === 0 && props.rowIndexForMessage === props.iValue)
53+
&& (
54+
<div className="usda-table__cell-message">
55+
View next level
56+
{' '}
57+
<FontAwesomeIcon icon={faAngleDoubleRight} color="#2378c3" />
58+
</div>
59+
)}
60+
</div>
61+
)}
62+
<div>
63+
{data}
64+
</div>
65+
</div>
66+
)
67+
);
68+
}
69+
})}
70+
</div>
71+
</div>
72+
)}
73+
<div className="mobile-gradient__wrapper">
74+
{/* {!rowOpen && <div id="mobile-row-gradient" />} */}
75+
<span
76+
className="collapsible-row-button"
77+
role="button"
78+
tabIndex={0}
79+
onClick={() => {
80+
setRowOpen(!rowOpen);
81+
}}
82+
onKeyUp={(e) => {
83+
if (e.key === 'Enter') {
84+
setRowOpen(!rowOpen);
85+
}
86+
}}>
87+
{rowOpen ? 'Collapse additional details' : 'View additional details'}
88+
{rowOpen ? (
89+
<FontAwesomeIcon className="chevron" icon="chevron-up" />
90+
) : (
91+
<FontAwesomeIcon className="chevron" icon="chevron-down" />
92+
)}
93+
</span>
94+
</div>
95+
</div>
96+
) : null;
97+
return toReturn;
98+
};
99+
MobileRowSlider.propTypes = propTypes;
100+
export default MobileRowSlider;

components/table/Table.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ const propTypes = {
3737
isMobile: PropTypes.bool,
3838
stickyFirstColumn: PropTypes.bool,
3939
highlightedColumns: PropTypes.object,
40-
atMaxLevel: PropTypes.bool
40+
atMaxLevel: PropTypes.bool,
41+
newMobileView: PropTypes.bool
4142
};
4243

4344
const Table = ({
@@ -62,7 +63,8 @@ const Table = ({
6263
standardColumns: 9,
6364
highlightedColumns: 7
6465
},
65-
atMaxLevel = false
66+
atMaxLevel = false,
67+
newMobileView = false
6668
}) => {
6769
const stackedClass = isStacked ? `usa-dt-table__stacked` : '';
6870
const getTablePickerOptionsAsc = columns.map((col) => ({
@@ -121,7 +123,8 @@ const Table = ({
121123
stickyFirstColumn={stickyFirstColumn}
122124
highlightedColumns={highlightedColumns}
123125
isStacked={isStacked}
124-
atMaxLevel={atMaxLevel} />
126+
atMaxLevel={atMaxLevel}
127+
newMobileView={newMobileView} />
125128
);
126129
}
127130

components/table/TableData.jsx

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint-disable array-callback-return */
2+
/* eslint-disable consistent-return */
13
/**
24
* TableData.jsx
35
* Created by Lizzie Salita 5/14/20
@@ -10,6 +12,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
1012
import { faAngleDoubleRight } from '@fortawesome/free-solid-svg-icons';
1113
import ExpandableRow from './ExpandableRow';
1214
import TableHeader from './TableHeader';
15+
import MobileRowSlider from './MobileRowSlider';
1316

1417
const propTypes = {
1518
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
@@ -22,7 +25,8 @@ const propTypes = {
2225
atMaxLevel: PropTypes.bool,
2326
stickyFirstColumn: PropTypes.bool,
2427
highlightedColumns: PropTypes.object,
25-
isStacked: PropTypes.bool
28+
isStacked: PropTypes.bool,
29+
newMobileView: PropTypes.bool
2630
};
2731

2832
const TableData = ({
@@ -36,11 +40,11 @@ const TableData = ({
3640
atMaxLevel,
3741
stickyFirstColumn = false,
3842
highlightedColumns,
39-
isStacked
43+
isStacked,
44+
newMobileView = false
4045
}) => {
4146
const [firstClick, setFirstClick] = useState(false);
4247
const [rowIndexForMessage, setRowIndexForMessage] = useState();
43-
4448
const setFocus = () => {
4549
const selectedElement = document.querySelector(".selected-row");
4650
if (selectedElement) {
@@ -75,6 +79,91 @@ const TableData = ({
7579
setFocus();
7680
}, [rowIndexForMessage]);
7781

82+
if (isStacked && isMobile && newMobileView && !expandable) {
83+
return (
84+
<div className="mobile-table-rows">
85+
{rows.map((row, i) => (
86+
<div
87+
role="button"
88+
key={uniqueId()}
89+
tabIndex={0}
90+
onClick={() => localClickHandler(row, i)}
91+
onKeyUp={(e) => {
92+
if (e.key === 'Enter') {
93+
e.preventDefault();
94+
localClickHandler(row, i);
95+
}
96+
}}
97+
className={`usda-table__row-item usda-table__row ${rowIndexForMessage === i ? 'selected-row' : ''} ${highlightedColumns ? `special-hover-color-${highlightedColumns.highlightedColumns}` : ''}`}
98+
style={{ height: rowHeight }}>
99+
{row.map((data, j) => {
100+
if (j < 6) {
101+
return (
102+
columns[j]?.bodyHeader
103+
? (
104+
<TableHeader
105+
className="table-header_body-header"
106+
key={uniqueId()}
107+
stickyFirstColumn={stickyFirstColumn}
108+
index={j}
109+
{...data} />
110+
)
111+
: (
112+
<div
113+
key={uniqueId()}
114+
className={`usda-table__cell${columns[j]?.right ? ' usda-table__cell_right' : ''}
115+
${(j === 0 && stickyFirstColumn) ? ' stickyColumn' : ''} ${(j === 0 && stickyFirstColumn) ? ' stickyColumn' : ''}
116+
${j === 0 ? 'usda-mobile__header' : ''}`}>
117+
{columns[j]
118+
&& (
119+
<div className="usda-table__cell-heading-container">
120+
{isMobile
121+
&& <div className="usda-table__cell-heading">{columns[j].displayName}</div>}
122+
{(isMobile && firstClick && j === 0 && rowIndexForMessage === i)
123+
&& (
124+
<div className="usda-table__cell-message">
125+
View next level
126+
{' '}
127+
<FontAwesomeIcon icon={faAngleDoubleRight} color="#2378c3" />
128+
</div>
129+
)}
130+
</div>
131+
)}
132+
<div className="usda-table__cell-text">
133+
{data.type === 'a' && j === 0 && isStacked && isMobile
134+
? (
135+
<a
136+
target={data.props.target}
137+
rel={data.props.rel}
138+
href={data.props.href}
139+
onClick={data.props.onClick}>
140+
{data.props.children}
141+
{' '}
142+
<FontAwesomeIcon icon="arrow-right" />
143+
</a>
144+
)
145+
: data}
146+
</div>
147+
</div>
148+
)
149+
);
150+
}
151+
})}
152+
<div>
153+
<MobileRowSlider
154+
row={row}
155+
columns={columns}
156+
iValue={i}
157+
firstClick={firstClick}
158+
rowIndexForMessage={rowIndexForMessage} />
159+
</div>
160+
</div>
161+
)
162+
)}
163+
</div>
164+
);
165+
}
166+
// normal table data return, do not modify
78167
return (
79168
<>
80169
{rows.map((row, i) => {

components/table/TableHeader.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const SortIcon = ({
2222
return (
2323
<div className="table-header__sort">
2424
<button
25+
type="button"
2526
onClick={clickedSort}
2627
className={`table-header__icon${activeAsc}`}
2728
value="asc"
@@ -30,6 +31,7 @@ const SortIcon = ({
3031
<FontAwesomeIcon size="2x" icon="caret-up" />
3132
</button>
3233
<button
34+
type="button"
3335
onClick={clickedSort}
3436
className={`table-header__icon${activeDesc}`}
3537
value="desc"

0 commit comments

Comments
 (0)