@telus-uds/components-community.data-grid 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,465 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import {
4
+ Typography,
5
+ Checkbox,
6
+ useCopy,
7
+ useThemeTokens,
8
+ variantProp,
9
+ IconButton
10
+ } from '@telus-uds/components-base'
11
+ import { styledComponents } from '@telus-uds/components-web'
12
+ import dictionary from './dictionary'
13
+ import {
14
+ resetColumnsData,
15
+ resetRowData,
16
+ DATA_TYPE,
17
+ SORT_DIRECTION,
18
+ isAtLeastOneRowUnselected,
19
+ toggleAllCheckBoxes,
20
+ toggleExpandedRow,
21
+ toggleRowCheckbox,
22
+ ROW_TYPE,
23
+ CELL_TYPE
24
+ } from './utility'
25
+ import DataGridTable from './DataGridTable'
26
+ import DataGridHead from './DataGridHead'
27
+ import DataGridBody from './DataGridBody'
28
+ import DataGridRow from './DataGridRow'
29
+ import DataGridCell from './DataGridCell'
30
+
31
+ const { styled } = styledComponents
32
+
33
+ export const StyledIconContainer = styled.div`
34
+ display: flex;
35
+ box-sizing: border-box;
36
+ align-items: center;
37
+ width: 60px;
38
+ justify-content: space-between;
39
+ `
40
+
41
+ const DataGrid = React.forwardRef(
42
+ (
43
+ {
44
+ rows = [],
45
+ columns = [],
46
+ groupedRows,
47
+ showCheckbox = false,
48
+ isSortable = false,
49
+ makeScrollBarAlwaysVisible = true,
50
+ tokens,
51
+ variant,
52
+ copy = 'en',
53
+ testID = 'data-grid'
54
+ },
55
+ ref
56
+ ) => {
57
+ const themeTokens = useThemeTokens('DataGrid', tokens, variant)
58
+ const getCopy = useCopy({ dictionary, copy })
59
+ const { expandRowIcon, hideExpandedRowIcon, sortColumnIconDown, sortColumnIconUp } = themeTokens
60
+ const [data, setData] = React.useState(
61
+ groupedRows ? resetRowData([...groupedRows], true) : resetRowData([...rows])
62
+ )
63
+ const [columnsData, setColumnsData] = React.useState(resetColumnsData(columns))
64
+ const [checkAllState, setCheckAllState] = React.useState(false)
65
+
66
+ const shouldCheckHeaderBox = (allData) => {
67
+ let isARowUnselectedInAllGroups = null
68
+ if (groupedRows) {
69
+ isARowUnselectedInAllGroups = Object.keys(allData).some((el) => {
70
+ return isAtLeastOneRowUnselected(allData[el].data)
71
+ })
72
+ } else {
73
+ isARowUnselectedInAllGroups = isAtLeastOneRowUnselected(allData)
74
+ }
75
+ return !isARowUnselectedInAllGroups
76
+ }
77
+
78
+ const shouldDisplayIconColumn = (allData, _showCheckbox) => {
79
+ let doesOneRowHaveExpandedContent = null
80
+ if (groupedRows) {
81
+ doesOneRowHaveExpandedContent = Object.keys(allData).some((el) => {
82
+ return allData[el].data.some((eachData) => eachData.hasExpandedRow === true)
83
+ })
84
+ } else {
85
+ doesOneRowHaveExpandedContent = allData.some((el) => el.hasExpandedRow === true)
86
+ }
87
+
88
+ return !!(_showCheckbox || doesOneRowHaveExpandedContent)
89
+ }
90
+
91
+ const toggleSelectAll = () => {
92
+ let _rows = null
93
+ if (groupedRows) {
94
+ _rows = {}
95
+ Object.keys(data).forEach((el) => {
96
+ _rows[el] = { ...data[el] }
97
+ _rows[el].data = toggleAllCheckBoxes(data[el].data, checkAllState)
98
+ })
99
+ } else {
100
+ _rows = toggleAllCheckBoxes(data, checkAllState)
101
+ }
102
+ setData(_rows)
103
+ setCheckAllState(!checkAllState)
104
+ }
105
+
106
+ const toggleCheckbox = (rowId) => {
107
+ let _data = null
108
+ if (groupedRows) {
109
+ const [group, _] = rowId.split('-')
110
+ const id = parseInt(_, 10)
111
+ _data = { ...data }
112
+ _data[group].data = toggleRowCheckbox(_data[group].data, id)
113
+ } else {
114
+ _data = toggleRowCheckbox(data, rowId)
115
+ }
116
+ setData(_data)
117
+ }
118
+
119
+ const toggleRowExpansion = (rowId) => {
120
+ let _row = null
121
+ if (groupedRows) {
122
+ const [group, _] = rowId.split('-')
123
+ const id = parseInt(_, 10)
124
+ _row = { ...data }
125
+ _row[group].data = toggleExpandedRow(_row[group].data, id)
126
+ } else {
127
+ _row = toggleExpandedRow(data, rowId)
128
+ }
129
+ setData(_row)
130
+ }
131
+
132
+ const HeaderCheckBoxDisplay = showCheckbox && (
133
+ <Checkbox
134
+ label={getCopy('all')}
135
+ checked={shouldCheckHeaderBox(data)}
136
+ onChange={toggleSelectAll}
137
+ />
138
+ )
139
+
140
+ const buildCheckBoxDisplay = (_showCheckbox, row, rowId) =>
141
+ _showCheckbox && <Checkbox checked={row.isSelected} onChange={() => toggleCheckbox(rowId)} />
142
+
143
+ const buildDisplayCaret = (row, rowId) =>
144
+ row.hasExpandedRow && (
145
+ <IconButton
146
+ onPress={() => toggleRowExpansion(rowId)}
147
+ icon={row.isExpandedRowOpen === true ? hideExpandedRowIcon : expandRowIcon}
148
+ accessibilityRole={`button-${rowId}`}
149
+ accessibilityLabel={
150
+ row.isExpandedRowOpen === true ? getCopy('hideRow') : getCopy('expandRow')
151
+ }
152
+ />
153
+ )
154
+
155
+ const buildExpandedRow = (row, rowId) =>
156
+ row.isExpandedRowOpen && (
157
+ <DataGridRow
158
+ type={ROW_TYPE.EXPANDEDROW}
159
+ tokens={themeTokens}
160
+ rowId={rowId}
161
+ isExpandedRowOpen={row.isExpandedRowOpen}
162
+ >
163
+ <DataGridCell
164
+ type={CELL_TYPE.EXPANDEDROWCELL}
165
+ tokens={themeTokens}
166
+ columnsLength={columns.length}
167
+ showCheckbox={showCheckbox}
168
+ isExpandedRowOpen={row.isExpandedRowOpen}
169
+ >
170
+ {row.expandedRowChildComponent.component}
171
+ </DataGridCell>
172
+ </DataGridRow>
173
+ )
174
+
175
+ const buildRowContent = (
176
+ row,
177
+ rowId,
178
+ _showCheckbox,
179
+ CheckBoxDisplay,
180
+ DisplayCaret,
181
+ ExpandedRow
182
+ ) => (
183
+ <React.Fragment key={rowId}>
184
+ <DataGridRow
185
+ key={rowId}
186
+ tokens={themeTokens}
187
+ rowId={rowId}
188
+ isExpandedRowOpen={row.isExpandedRowOpen}
189
+ hasExpandedContent={row.hasExpandedRow}
190
+ onClick={toggleRowExpansion}
191
+ >
192
+ {shouldDisplayIconColumn(data, _showCheckbox) && (
193
+ <DataGridCell tokens={themeTokens} isExpandedRowOpen={row.isExpandedRowOpen}>
194
+ <StyledIconContainer>
195
+ {CheckBoxDisplay}
196
+ {DisplayCaret}
197
+ </StyledIconContainer>
198
+ </DataGridCell>
199
+ )}
200
+ {columnsData.map((column) => (
201
+ <DataGridCell
202
+ tokens={themeTokens}
203
+ isExpandedRowOpen={row.isExpandedRowOpen}
204
+ key={`${rowId}-${column.key}`}
205
+ >
206
+ <Typography
207
+ block
208
+ variant={{ size: 'small' }}
209
+ tokens={{ color: themeTokens.cellTextColor }}
210
+ >
211
+ {row[column.key]}
212
+ </Typography>
213
+ </DataGridCell>
214
+ ))}
215
+ </DataGridRow>
216
+ {ExpandedRow}
217
+ </React.Fragment>
218
+ )
219
+
220
+ const sortColumn = (column) => {
221
+ const _col = { ...column }
222
+ if (!groupedRows) {
223
+ const _data = [...data].sort((a, b) => {
224
+ const first =
225
+ _col.dataType === DATA_TYPE.NUMBER ? parseFloat(a[_col.key]) : a[_col.key].toUpperCase()
226
+ const next =
227
+ _col.dataType === DATA_TYPE.NUMBER ? parseFloat(b[_col.key]) : b[_col.key].toUpperCase()
228
+
229
+ if (_col.sortDirection === SORT_DIRECTION.DESC) {
230
+ if (first < next) return -1
231
+ return next === first ? 0 : 1
232
+ }
233
+ if (next < first) return -1
234
+ return first === next ? 0 : 1
235
+ })
236
+
237
+ _col.sortDirection =
238
+ _col.sortDirection === SORT_DIRECTION.DESC ? SORT_DIRECTION.ASC : SORT_DIRECTION.DESC
239
+ _col.currentSort = true
240
+
241
+ const _columns = resetColumnsData(columnsData)
242
+ _columns[columnsData.findIndex((_el) => _el.key === column.key)] = _col
243
+
244
+ setColumnsData(_columns)
245
+ setData(_data)
246
+ }
247
+ }
248
+
249
+ let HeaderContent = null
250
+ let BodyContent = null
251
+ if (groupedRows) {
252
+ BodyContent = Object.keys(data).map((group) => {
253
+ const DefaultSubHeading = (
254
+ <Typography variant={{ size: 'h3' }}>{data[group].name}</Typography>
255
+ )
256
+ const GroupHeaderRow = (
257
+ <DataGridRow type={ROW_TYPE.EXPANDEDROW} tokens={themeTokens} key={group}>
258
+ <DataGridCell
259
+ type={CELL_TYPE.SUBHEADING}
260
+ tokens={themeTokens}
261
+ columnsLength={columnsData.length}
262
+ >
263
+ {data[group].groupHeaderComponent || DefaultSubHeading}
264
+ </DataGridCell>
265
+ </DataGridRow>
266
+ )
267
+
268
+ const DataRow = data[group].data.map((row) => {
269
+ const rowId = `${group}-${row.id}`
270
+ const CheckBoxDisplay = buildCheckBoxDisplay(showCheckbox, row, rowId)
271
+
272
+ const DisplayCaret = buildDisplayCaret(row, rowId)
273
+
274
+ const ExpandedRow = buildExpandedRow(row, rowId)
275
+
276
+ return buildRowContent(
277
+ row,
278
+ rowId,
279
+ showCheckbox,
280
+ CheckBoxDisplay,
281
+ DisplayCaret,
282
+ ExpandedRow
283
+ )
284
+ })
285
+
286
+ return (
287
+ <React.Fragment key={group}>
288
+ {GroupHeaderRow}
289
+ {DataRow}
290
+ </React.Fragment>
291
+ )
292
+ })
293
+ } else {
294
+ BodyContent = data.map((row) => {
295
+ const rowId = row.id
296
+
297
+ const CheckBoxDisplay = buildCheckBoxDisplay(showCheckbox, row, rowId)
298
+
299
+ const DisplayCaret = buildDisplayCaret(row, rowId)
300
+
301
+ const ExpandedRow = buildExpandedRow(row, rowId)
302
+
303
+ return buildRowContent(row, rowId, showCheckbox, CheckBoxDisplay, DisplayCaret, ExpandedRow)
304
+ })
305
+ }
306
+
307
+ HeaderContent = (
308
+ <>
309
+ {shouldDisplayIconColumn(data, showCheckbox) && (
310
+ <DataGridCell type={CELL_TYPE.HEADING} tokens={themeTokens} isFirstCol={true}>
311
+ {HeaderCheckBoxDisplay}
312
+ </DataGridCell>
313
+ )}
314
+
315
+ {columnsData.map((column) => (
316
+ <DataGridCell
317
+ type={CELL_TYPE.HEADING}
318
+ key={column.key}
319
+ tokens={themeTokens}
320
+ isSortable={isSortable}
321
+ >
322
+ <Typography
323
+ block
324
+ variant={{ size: 'h4' }}
325
+ tokens={{ color: themeTokens.headerTextColor }}
326
+ >
327
+ {column.label}
328
+ </Typography>
329
+ {isSortable && column.isSortable && (
330
+ <IconButton
331
+ variant={{ size: 'small' }}
332
+ tokens={{
333
+ iconColor: column.currentSort
334
+ ? themeTokens.sortColumnIconActiveColor
335
+ : themeTokens.sortColumnIconDefaultColor
336
+ }}
337
+ onPress={() => {
338
+ if (typeof column.fn === 'function') {
339
+ column.fn(column, data, setData, columnsData, setColumnsData)
340
+ } else sortColumn(column)
341
+ }}
342
+ icon={
343
+ column.sortDirection === SORT_DIRECTION.ASC
344
+ ? sortColumnIconUp
345
+ : sortColumnIconDown
346
+ }
347
+ accessibilityRole="sort-button"
348
+ accessibilityLabel={getCopy('button')}
349
+ />
350
+ )}
351
+ </DataGridCell>
352
+ ))}
353
+ </>
354
+ )
355
+
356
+ return (
357
+ <DataGridTable
358
+ tokens={themeTokens}
359
+ makeScrollBarAlwaysVisible={makeScrollBarAlwaysVisible}
360
+ ref={ref}
361
+ testID={testID}
362
+ >
363
+ <>
364
+ <DataGridHead>
365
+ <DataGridRow type={ROW_TYPE.HEADING}>{HeaderContent}</DataGridRow>
366
+ </DataGridHead>
367
+ <DataGridBody>{BodyContent}</DataGridBody>
368
+ </>
369
+ </DataGridTable>
370
+ )
371
+ }
372
+ )
373
+
374
+ DataGrid.displayName = 'DataGrid'
375
+
376
+ DataGrid.propTypes = {
377
+ /**
378
+ * Use `columns` to pass the data for data-grid column header items.
379
+ */
380
+ columns: PropTypes.arrayOf(
381
+ PropTypes.shape({
382
+ key: PropTypes.string.isRequired,
383
+ label: PropTypes.string.isRequired,
384
+ width: PropTypes.string,
385
+ dataType: PropTypes.oneOf(['string', 'number']),
386
+ isSortable: PropTypes.bool, // Set this to true to enable sorting for this column
387
+ fn: PropTypes.func
388
+ })
389
+ ).isRequired,
390
+ /**
391
+ * Use `groupedRows` to pass the grouped data for display
392
+ */
393
+ groupedRows: PropTypes.arrayOf(
394
+ PropTypes.shape({
395
+ key: PropTypes.string.isRequired,
396
+ name: PropTypes.string.isRequired,
397
+ groupHeaderComponent: PropTypes.node,
398
+ data: PropTypes.arrayOf(
399
+ PropTypes.shape({
400
+ id: PropTypes.number.isRequired,
401
+ expandedRow: PropTypes.shape({
402
+ rows: PropTypes.arrayOf(
403
+ PropTypes.shape({
404
+ id: PropTypes.number.isRequired
405
+ })
406
+ ),
407
+ columns: PropTypes.arrayOf(
408
+ PropTypes.shape({
409
+ key: PropTypes.string.isRequired,
410
+ label: PropTypes.string.isRequired
411
+ })
412
+ )
413
+ }),
414
+ expandedRowChildComponent: PropTypes.shape({
415
+ component: PropTypes.node,
416
+ displayOnLoad: PropTypes.bool.isRequired
417
+ })
418
+ })
419
+ )
420
+ })
421
+ ),
422
+ /**
423
+ * Use `rows` to pass ungrouped data for data-grid row cells items.
424
+ */
425
+ rows: PropTypes.arrayOf(
426
+ PropTypes.shape({
427
+ id: PropTypes.number.isRequired,
428
+ expandedRowChildComponent: PropTypes.shape({
429
+ component: PropTypes.node,
430
+ displayOnLoad: PropTypes.bool.isRequired
431
+ })
432
+ })
433
+ ),
434
+ /**
435
+ * Set this to true to enable columns to become sortable.
436
+ */
437
+ isSortable: PropTypes.bool,
438
+ /**
439
+ * Set this to true to make scrollbar always visible when content is larger than the grid
440
+ */
441
+ makeScrollBarAlwaysVisible: PropTypes.bool,
442
+ /**
443
+ * Set this to true to enable checkboxes in the first column.
444
+ */
445
+ showCheckbox: PropTypes.bool,
446
+ /**
447
+ * Use tokens prop to override theme tokens
448
+ */
449
+ tokens: PropTypes.object,
450
+ /**
451
+ * No available variants
452
+ */
453
+ variant: variantProp.propType,
454
+ /**
455
+ * Use copy for localisations of keys.
456
+ */
457
+ copy: PropTypes.oneOf(['en', 'fr']),
458
+
459
+ /**
460
+ * Use in tests if the datagrid test cases need to find the element with the id.
461
+ */
462
+ testID: PropTypes.string
463
+ }
464
+
465
+ export default DataGrid
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ const DataGridBody = React.forwardRef(({ children }, ref) => {
5
+ return <tbody ref={ref}>{children}</tbody>
6
+ })
7
+
8
+ DataGridBody.displayName = 'DataGridBody'
9
+
10
+ DataGridBody.propTypes = {
11
+ /**
12
+ * Accepts any React or HTML node
13
+ */
14
+ children: PropTypes.node.isRequired
15
+ }
16
+
17
+ export default DataGridBody
@@ -0,0 +1,200 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { styledComponents } from '@telus-uds/components-web'
4
+ import { CELL_TYPE } from './utility'
5
+
6
+ const { styled, css } = styledComponents
7
+
8
+ const StyledHeaderCell = styled.th`
9
+ ${(props) => {
10
+ return css`
11
+ background-color: ${props.headerRowBackgroundColor};
12
+ border-top: solid ${props.headerBorderTopWidth}px ${props.headerBorderTopColor};
13
+ border-bottom: solid ${props.headerBorderBottomWidth}px ${props.headerBorderBottomColor};
14
+ padding: ${props.headerPadding}px;
15
+ text-align: ${props.headerTextAlign};
16
+ box-sizing: border-box;
17
+ font-size: ${props.headerFontSize}px;
18
+ font-weight: bold;
19
+ line-height: ${props.headerLineHeight * props.headerFontSize}px;
20
+ color: ${props.headerTextColor};
21
+ width: ${props.firstColWidth};
22
+ font-family: ${props.headerFontFamily};
23
+ `
24
+ }}
25
+ `
26
+ const StyledHeaderCellDiv = styled.div`
27
+ display: flex;
28
+ align-items: center;
29
+ `
30
+
31
+ const StyledGroupHeaderCell = styled.td`
32
+ ${(props) => {
33
+ return css`
34
+ background-color: ${props.subHeadingBackgroundColor};
35
+ padding: ${props.cellPadding}px;
36
+ border-top: solid ${props.cellBorderBottomWidth}px ${props.cellBorderBottomColor};
37
+ text-align: ${props.cellTextAlign};
38
+ font-size: ${props.cellFontSize}px;
39
+ font-weight: normal;
40
+ line-height: ${props.cellLineHeight * props.cellFontSize}px;
41
+ color: ${props.cellTextColor};
42
+ font-family: ${props.cellFontFamily};
43
+ `
44
+ }}
45
+ `
46
+
47
+ const StyledGroupHeaderCellDiv = styled.div`
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: start;
51
+ `
52
+
53
+ const StyledExpandedCell = styled.td`
54
+ ${(props) => {
55
+ return css`
56
+ padding: ${props.cellPadding}px;
57
+ border-bottom: ${
58
+ props.isExpandedRowOpen
59
+ ? `solid ${props.cellBorderBottomWidth}px ${props.headerBorderBottomColor};`
60
+ : `solid ${props.cellBorderBottomWidth}px ${props.cellBorderBottomColor};`
61
+ }
62
+ text-align: ${props.cellTextAlign};
63
+ font-size: ${props.cellFontSize}px;
64
+ font-weight: normal;
65
+ line-height: ${props.cellLineHeight * props.cellFontSize}px;
66
+ color: ${props.cellTextColor};
67
+ font-family: ${props.cellFontFamily};
68
+ `
69
+ }}
70
+ `
71
+
72
+ const StyledExpandedCellDiv = styled.div`
73
+ ${(props) => {
74
+ return css`
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: ${props.expandedContentAlignment ? props.expandedContentAlignment : 'start'};
78
+ padding-left: ${props.showCheckbox
79
+ ? `${props.expandedContentLeftPadding}px`
80
+ : `${props.expandedContentDefaultLeftPadding}px`};
81
+ `
82
+ }}
83
+ `
84
+
85
+ export const StyledCell = styled.td`
86
+ ${(props) => {
87
+ if (props.isExpandedRowOpen) {
88
+ return css`
89
+ padding: ${props.cellPadding}px;
90
+ text-align: ${props.cellTextAlign};
91
+ font-size: ${props.cellFontSize}px;
92
+ font-weight: normal;
93
+ line-height: ${props.cellLineHeight * props.cellFontSize}px;
94
+ color: ${props.cellTextColor};
95
+ font-family: ${props.cellFontFamily};
96
+ border-top: solid ${props.headerBorderTopWidth}px ${props.headerBorderTopColor};
97
+ `
98
+ }
99
+ return css`
100
+ padding: ${props.cellPadding}px;
101
+ border-bottom: ${props.hideRowBottomBorder === 1
102
+ ? `none`
103
+ : `solid ${props.cellBorderBottomWidth}px ${props.cellBorderBottomColor}`};
104
+ text-align: ${props.cellTextAlign};
105
+ font-size: ${props.cellFontSize}px;
106
+ font-weight: normal;
107
+ line-height: ${props.cellLineHeight * props.cellFontSize}px;
108
+ color: ${props.cellTextColor};
109
+ font-family: ${props.cellFontFamily};
110
+ `
111
+ }}
112
+ `
113
+
114
+ const DataGridCell = React.forwardRef(
115
+ (
116
+ {
117
+ children,
118
+ tokens,
119
+ type,
120
+ columnsLength,
121
+ showCheckbox = false,
122
+ isFirstCol = false,
123
+ isExpandedRowOpen = false
124
+ },
125
+ ref
126
+ ) => {
127
+ if (type === CELL_TYPE.HEADING) {
128
+ return (
129
+ <StyledHeaderCell
130
+ {...tokens}
131
+ firstColWidth={isFirstCol ? tokens.firstColWidth : 'auto'}
132
+ ref={ref}
133
+ >
134
+ <StyledHeaderCellDiv>{children}</StyledHeaderCellDiv>
135
+ </StyledHeaderCell>
136
+ )
137
+ }
138
+ if (type === CELL_TYPE.SUBHEADING) {
139
+ return (
140
+ <StyledGroupHeaderCell colSpan={columnsLength + 1} {...tokens} ref={ref}>
141
+ <StyledGroupHeaderCellDiv {...tokens}>{children}</StyledGroupHeaderCellDiv>
142
+ </StyledGroupHeaderCell>
143
+ )
144
+ }
145
+ if (type === CELL_TYPE.EXPANDEDROWCELL) {
146
+ return (
147
+ <StyledExpandedCell
148
+ colSpan={columnsLength + 1}
149
+ {...tokens}
150
+ isExpandedRowOpen={isExpandedRowOpen}
151
+ ref={ref}
152
+ >
153
+ <StyledExpandedCellDiv showCheckbox={showCheckbox} {...tokens}>
154
+ {children}
155
+ </StyledExpandedCellDiv>
156
+ </StyledExpandedCell>
157
+ )
158
+ }
159
+ return (
160
+ <StyledCell {...tokens} isExpandedRowOpen={isExpandedRowOpen} ref={ref}>
161
+ {children}
162
+ </StyledCell>
163
+ )
164
+ }
165
+ )
166
+
167
+ DataGridCell.displayName = 'DataGridCell'
168
+
169
+ DataGridCell.propTypes = {
170
+ /**
171
+ cell type
172
+ */
173
+ type: PropTypes.oneOf(['heading', 'subHeading', 'expandedRowCell']),
174
+ /**
175
+ * Accepts any React or HTML node
176
+ */
177
+ children: PropTypes.node,
178
+ /**
179
+ * Tokens passed to the component
180
+ */
181
+ tokens: PropTypes.object,
182
+ /**
183
+ * columnsLength passed to the component for certain scenarios in which colSpan is required
184
+ */
185
+ columnsLength: PropTypes.number,
186
+ /**
187
+ * showCheckbox passed to the component for certain scenarios in which checkbox visibility impacts the display design
188
+ */
189
+ showCheckbox: PropTypes.bool,
190
+ /**
191
+ * isFirstCol passed to the component to determine if cell is first within the row
192
+ */
193
+ isFirstCol: PropTypes.bool,
194
+ /**
195
+ * isExpandedRowOpen passed to the component to determine if cell is displaying additional data
196
+ */
197
+ isExpandedRowOpen: PropTypes.bool
198
+ }
199
+
200
+ export default DataGridCell
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ const DataGridHead = React.forwardRef(({ children }, ref) => <thead ref={ref}>{children}</thead>)
5
+
6
+ DataGridHead.displayName = 'DataGridHead'
7
+
8
+ DataGridHead.propTypes = {
9
+ /**
10
+ * Accepts any React or HTML node
11
+ */
12
+ children: PropTypes.node
13
+ }
14
+
15
+ export default DataGridHead