@instructure/ui-table 10.2.1-snapshot-3 → 10.2.1-snapshot-11

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/es/Table/Body/index.js +24 -11
  3. package/es/Table/Body/props.js +2 -5
  4. package/es/Table/Body/styles.js +0 -2
  5. package/es/Table/Cell/index.js +3 -2
  6. package/es/Table/Cell/props.js +1 -2
  7. package/es/Table/ColHeader/styles.js +0 -1
  8. package/es/Table/Head/index.js +40 -30
  9. package/es/Table/Head/props.js +1 -3
  10. package/es/Table/Head/styles.js +0 -2
  11. package/es/Table/Row/index.js +25 -12
  12. package/es/Table/Row/props.js +2 -5
  13. package/es/Table/Row/styles.js +4 -6
  14. package/es/Table/RowHeader/index.js +3 -2
  15. package/es/Table/RowHeader/props.js +1 -2
  16. package/es/Table/TableContext.js +34 -0
  17. package/es/Table/__new-tests__/Table.test.js +74 -1
  18. package/es/Table/index.js +25 -17
  19. package/es/index.js +2 -1
  20. package/lib/Table/Body/index.js +23 -10
  21. package/lib/Table/Body/props.js +2 -5
  22. package/lib/Table/Body/styles.js +0 -2
  23. package/lib/Table/Cell/index.js +3 -2
  24. package/lib/Table/Cell/props.js +1 -2
  25. package/lib/Table/ColHeader/styles.js +0 -1
  26. package/lib/Table/Head/index.js +39 -30
  27. package/lib/Table/Head/props.js +1 -3
  28. package/lib/Table/Head/styles.js +0 -2
  29. package/lib/Table/Row/index.js +24 -11
  30. package/lib/Table/Row/props.js +2 -5
  31. package/lib/Table/Row/styles.js +4 -6
  32. package/lib/Table/RowHeader/index.js +3 -2
  33. package/lib/Table/RowHeader/props.js +1 -2
  34. package/lib/Table/TableContext.js +39 -0
  35. package/lib/Table/__new-tests__/Table.test.js +74 -1
  36. package/lib/Table/index.js +24 -16
  37. package/lib/index.js +8 -1
  38. package/package.json +17 -17
  39. package/src/Table/Body/index.tsx +23 -13
  40. package/src/Table/Body/props.ts +6 -18
  41. package/src/Table/Body/styles.ts +0 -2
  42. package/src/Table/Cell/index.tsx +6 -3
  43. package/src/Table/Cell/props.ts +7 -9
  44. package/src/Table/ColHeader/props.ts +7 -4
  45. package/src/Table/ColHeader/styles.ts +0 -1
  46. package/src/Table/Head/index.tsx +40 -40
  47. package/src/Table/Head/props.ts +20 -13
  48. package/src/Table/Head/styles.ts +0 -2
  49. package/src/Table/README.md +299 -2
  50. package/src/Table/Row/index.tsx +27 -11
  51. package/src/Table/Row/props.ts +7 -19
  52. package/src/Table/Row/styles.ts +5 -6
  53. package/src/Table/RowHeader/index.tsx +6 -4
  54. package/src/Table/RowHeader/props.ts +1 -3
  55. package/src/Table/TableContext.ts +54 -0
  56. package/src/Table/__new-tests__/Table.test.tsx +131 -2
  57. package/src/Table/index.tsx +42 -44
  58. package/src/Table/props.ts +8 -28
  59. package/src/index.ts +1 -0
  60. package/tsconfig.build.tsbuildinfo +1 -1
  61. package/types/Table/Body/index.d.ts +6 -13
  62. package/types/Table/Body/index.d.ts.map +1 -1
  63. package/types/Table/Body/props.d.ts +4 -5
  64. package/types/Table/Body/props.d.ts.map +1 -1
  65. package/types/Table/Body/styles.d.ts +0 -2
  66. package/types/Table/Body/styles.d.ts.map +1 -1
  67. package/types/Table/Cell/index.d.ts +4 -3
  68. package/types/Table/Cell/index.d.ts.map +1 -1
  69. package/types/Table/Cell/props.d.ts +6 -2
  70. package/types/Table/Cell/props.d.ts.map +1 -1
  71. package/types/Table/ColHeader/props.d.ts +6 -3
  72. package/types/Table/ColHeader/props.d.ts.map +1 -1
  73. package/types/Table/ColHeader/styles.d.ts +0 -1
  74. package/types/Table/ColHeader/styles.d.ts.map +1 -1
  75. package/types/Table/Head/index.d.ts +15 -7
  76. package/types/Table/Head/index.d.ts.map +1 -1
  77. package/types/Table/Head/props.d.ts +19 -5
  78. package/types/Table/Head/props.d.ts.map +1 -1
  79. package/types/Table/Head/styles.d.ts +0 -2
  80. package/types/Table/Head/styles.d.ts.map +1 -1
  81. package/types/Table/Row/index.d.ts +6 -13
  82. package/types/Table/Row/index.d.ts.map +1 -1
  83. package/types/Table/Row/props.d.ts +5 -6
  84. package/types/Table/Row/props.d.ts.map +1 -1
  85. package/types/Table/Row/styles.d.ts +5 -2
  86. package/types/Table/Row/styles.d.ts.map +1 -1
  87. package/types/Table/RowHeader/index.d.ts +4 -3
  88. package/types/Table/RowHeader/index.d.ts.map +1 -1
  89. package/types/Table/RowHeader/props.d.ts +0 -1
  90. package/types/Table/RowHeader/props.d.ts.map +1 -1
  91. package/types/Table/TableContext.d.ts +24 -0
  92. package/types/Table/TableContext.d.ts.map +1 -0
  93. package/types/Table/index.d.ts +1 -1
  94. package/types/Table/index.d.ts.map +1 -1
  95. package/types/Table/props.d.ts +10 -22
  96. package/types/Table/props.d.ts.map +1 -1
  97. package/types/index.d.ts +1 -0
  98. package/types/index.d.ts.map +1 -1
@@ -24,7 +24,7 @@
24
24
 
25
25
  import React from 'react'
26
26
  import { render, screen, waitFor } from '@testing-library/react'
27
- import { vi } from 'vitest'
27
+ import { MockInstance, vi } from 'vitest'
28
28
  import { userEvent } from '@testing-library/user-event'
29
29
  import '@testing-library/jest-dom'
30
30
 
@@ -36,7 +36,7 @@ import { runAxeCheck } from '@instructure/ui-axe-check'
36
36
  // see https://github.com/vitest-dev/eslint-plugin-vitest/issues/511
37
37
  // eslint-disable-next-line vitest/valid-describe-callback
38
38
  describe('<Table />', async () => {
39
- let consoleErrorMock: any
39
+ let consoleErrorMock: MockInstance<typeof console.error>
40
40
 
41
41
  beforeEach(() => {
42
42
  // Mocking console to prevent test output pollution
@@ -169,6 +169,45 @@ describe('<Table />', async () => {
169
169
  expect(stackedTable).not.toHaveTextContent('Foo')
170
170
  })
171
171
 
172
+ it('does not crash for invalid children', async () => {
173
+ render(
174
+ <Table caption="Test table" layout="stacked">
175
+ test1
176
+ <span>test</span>
177
+ {/* @ts-ignore error is normal here */}
178
+ <Table.Head>
179
+ <span>test</span>
180
+ test2
181
+ {/* @ts-ignore error is normal here */}
182
+ <Table.Row>
183
+ test3
184
+ <span>test</span>
185
+ <Table.Cell>Foo</Table.Cell>
186
+ </Table.Row>
187
+ test4
188
+ <span>test</span>
189
+ </Table.Head>
190
+ test5
191
+ <Table.Body>
192
+ test
193
+ <span>test</span>
194
+ {/* @ts-ignore error is normal here */}
195
+ <Table.Row>
196
+ test
197
+ <span>test</span>
198
+ <Table.Cell>Foo</Table.Cell>
199
+ test
200
+ <span>test</span>
201
+ </Table.Row>
202
+ </Table.Body>
203
+ </Table>
204
+ )
205
+ const table = screen.getByRole('table')
206
+
207
+ expect(table).toBeInTheDocument()
208
+ expect(table).toHaveTextContent('Foo')
209
+ })
210
+
172
211
  // see https://github.com/vitest-dev/eslint-plugin-vitest/issues/511
173
212
  // eslint-disable-next-line vitest/valid-describe-callback
174
213
  describe('when table is sortable', async () => {
@@ -294,4 +333,94 @@ describe('<Table />', async () => {
294
333
  expect(header).toHaveAttribute('aria-sort', 'descending')
295
334
  })
296
335
  })
336
+
337
+ describe('when using custom components', () => {
338
+ it('should render wrapper HOCs', () => {
339
+ class CustomTableCell extends React.Component<any> {
340
+ render() {
341
+ return <Table.Cell {...this.props}>{this.props.children}</Table.Cell>
342
+ }
343
+ }
344
+ class CustomTableRow extends React.Component {
345
+ render() {
346
+ return (
347
+ <Table.Row {...this.props}>
348
+ <Table.RowHeader>1</Table.RowHeader>
349
+ <Table.Cell>The Shawshank Redemption</Table.Cell>
350
+ <CustomTableCell>9.3</CustomTableCell>
351
+ </Table.Row>
352
+ )
353
+ }
354
+ }
355
+ const table = render(
356
+ <Table caption="Test custom table">
357
+ <Table.Head>
358
+ <Table.Row>
359
+ <Table.ColHeader id="foo">ColHeader</Table.ColHeader>
360
+ <Table.ColHeader id="bar">Bar-header</Table.ColHeader>
361
+ <Table.ColHeader id="baz">Bar-header</Table.ColHeader>
362
+ </Table.Row>
363
+ </Table.Head>
364
+ <Table.Body>
365
+ <CustomTableRow />
366
+ <Table.Row>
367
+ <Table.RowHeader>RowHeader</Table.RowHeader>
368
+ <Table.Cell>Cell</Table.Cell>
369
+ <Table.Cell>Cell2</Table.Cell>
370
+ </Table.Row>
371
+ </Table.Body>
372
+ </Table>
373
+ )
374
+ const stackedTable = screen.getByRole('table')
375
+
376
+ expect(stackedTable).toBeInTheDocument()
377
+ const { container } = table
378
+ expect(container).toBeInTheDocument()
379
+ expect(container).toHaveTextContent('The Shawshank Redemption')
380
+ expect(container).toHaveTextContent('9.3')
381
+ })
382
+
383
+ it('should render fully custom components', () => {
384
+ class CustomTableCell extends React.Component<any> {
385
+ render() {
386
+ return <td>{this.props.children}</td>
387
+ }
388
+ }
389
+
390
+ class CustomTableRow extends React.Component<any> {
391
+ render() {
392
+ return <tr>{this.props.children}</tr>
393
+ }
394
+ }
395
+
396
+ const table = render(
397
+ <Table caption="Test custom table">
398
+ <Table.Head>
399
+ <CustomTableRow>
400
+ <CustomTableCell id="foo">ColHeader</CustomTableCell>
401
+ <CustomTableCell id="bar">Bar-header</CustomTableCell>
402
+ <Table.ColHeader id="baz">Bar-header</Table.ColHeader>
403
+ </CustomTableRow>
404
+ </Table.Head>
405
+ <Table.Body>
406
+ <CustomTableRow>
407
+ <Table.RowHeader>RowHeader2</Table.RowHeader>
408
+ <CustomTableCell>Cell</CustomTableCell>
409
+ <Table.Cell>Cell2</Table.Cell>
410
+ </CustomTableRow>
411
+ </Table.Body>
412
+ </Table>
413
+ )
414
+ const stackedTable = screen.getByRole('table')
415
+
416
+ expect(stackedTable).toBeInTheDocument()
417
+ const { container } = table
418
+ expect(container).toBeInTheDocument()
419
+ expect(container).toHaveTextContent('ColHeader')
420
+ expect(container).toHaveTextContent('Bar-header')
421
+ expect(container).toHaveTextContent('RowHeader2')
422
+ expect(container).toHaveTextContent('Cell')
423
+ expect(container).toHaveTextContent('Cell2')
424
+ })
425
+ })
297
426
  })
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  /** @jsx jsx */
26
- import { Component, Children } from 'react'
26
+ import { Component, Children, isValidElement } from 'react'
27
27
 
28
28
  import { safeCloneElement, omitProps } from '@instructure/ui-react-utils'
29
29
  import { View } from '@instructure/ui-view'
@@ -41,15 +41,10 @@ import { ColHeader } from './ColHeader'
41
41
  import { RowHeader } from './RowHeader'
42
42
  import { Cell } from './Cell'
43
43
 
44
- import type {
45
- TableProps,
46
- HeadChild,
47
- ColHeaderChild,
48
- RowHeaderChild,
49
- CellChild
50
- } from './props'
44
+ import type { TableProps } from './props'
51
45
 
52
46
  import { allowedProps, propTypes } from './props'
47
+ import TableContext from './TableContext'
53
48
 
54
49
  /**
55
50
  ---
@@ -97,17 +92,14 @@ class Table extends Component<TableProps> {
97
92
  }
98
93
 
99
94
  getHeaders() {
100
- const { children } = this.props
101
- const [head] = Children.toArray(children) as HeadChild[]
102
- const [row]: any = Children.toArray(head.props.children)
103
- if (!row) return undefined
104
-
105
- return Children.map(
106
- row.props.children as (ColHeaderChild | RowHeaderChild | CellChild)[],
107
- (colHeader) => {
108
- return colHeader.props.children
109
- }
110
- )
95
+ const [headChild] = Children.toArray(this.props.children)
96
+ if (!headChild || !isValidElement(headChild)) return undefined
97
+ const [firstRow] = Children.toArray(headChild.props.children)
98
+ if (!firstRow || !isValidElement(firstRow)) return undefined
99
+ return Children.map(firstRow.props.children, (colHeader) => {
100
+ if (!isValidElement<{ children?: any }>(colHeader)) return undefined
101
+ return colHeader.props.children
102
+ })
111
103
  }
112
104
 
113
105
  render() {
@@ -116,32 +108,38 @@ class Table extends Component<TableProps> {
116
108
  const headers = isStacked ? this.getHeaders() : undefined
117
109
 
118
110
  return (
119
- <View
120
- {...View.omitViewProps(
121
- omitProps(this.props, Table.allowedProps),
122
- Table
123
- )}
124
- as={isStacked ? 'div' : 'table'}
125
- margin={margin}
126
- elementRef={this.handleRef}
127
- css={styles?.table}
128
- role={isStacked ? 'table' : undefined}
129
- aria-label={isStacked ? (caption as string) : undefined}
111
+ <TableContext.Provider
112
+ value={{
113
+ isStacked: isStacked,
114
+ hover: hover!,
115
+ headers: headers
116
+ }}
130
117
  >
131
- {!isStacked && (
132
- <caption>
133
- <ScreenReaderContent>{caption}</ScreenReaderContent>
134
- </caption>
135
- )}
136
- {Children.map(children, (child: any) => {
137
- return safeCloneElement(child, {
138
- key: child.props.name,
139
- isStacked,
140
- hover,
141
- headers
142
- })
143
- })}
144
- </View>
118
+ <View
119
+ {...View.omitViewProps(
120
+ omitProps(this.props, Table.allowedProps),
121
+ Table
122
+ )}
123
+ as={isStacked ? 'div' : 'table'}
124
+ margin={margin}
125
+ elementRef={this.handleRef}
126
+ css={styles?.table}
127
+ role={isStacked ? 'table' : undefined}
128
+ aria-label={isStacked ? (caption as string) : undefined}
129
+ >
130
+ {!isStacked && (
131
+ <caption>
132
+ <ScreenReaderContent>{caption}</ScreenReaderContent>
133
+ </caption>
134
+ )}
135
+ {Children.map(children, (child) => {
136
+ if (isValidElement(child)) {
137
+ return safeCloneElement(child, { key: child.props.name })
138
+ }
139
+ return child
140
+ })}
141
+ </View>
142
+ </TableContext.Provider>
145
143
  )
146
144
  }
147
145
  }
@@ -37,25 +37,7 @@ import type {
37
37
  TableTheme
38
38
  } from '@instructure/shared-types'
39
39
 
40
- import { Head } from './Head'
41
- import type { TableHeadProps } from './Head/props'
42
- import { Body } from './Body'
43
- import type { TableBodyProps } from './Body/props'
44
- import { Row } from './Row'
45
- import type { TableRowProps } from './Row/props'
46
- import { ColHeader } from './ColHeader'
47
- import type { TableColHeaderProps } from './ColHeader/props'
48
- import { RowHeader } from './RowHeader'
49
- import type { TableRowHeaderProps } from './RowHeader/props'
50
- import { Cell } from './Cell'
51
- import type { TableCellProps } from './Cell/props'
52
-
53
- type HeadChild = React.ComponentElement<TableHeadProps, Head>
54
- type BodyChild = React.ComponentElement<TableBodyProps, Body>
55
- type RowChild = React.ComponentElement<TableRowProps, Row>
56
- type ColHeaderChild = React.ComponentElement<TableColHeaderProps, ColHeader>
57
- type RowHeaderChild = React.ComponentElement<TableRowHeaderProps, RowHeader>
58
- type CellChild = React.ComponentElement<TableCellProps, Cell>
40
+ type RowChild = React.ReactElement<{ children: React.ReactElement }>
59
41
 
60
42
  type TableOwnProps = {
61
43
  /**
@@ -79,12 +61,15 @@ type TableOwnProps = {
79
61
  hover?: boolean
80
62
  /**
81
63
  * `auto` lets the browser determine table column widths based on cell content,
82
- * while `fixed` forces columns of equal width. `stacked` renders table in one
83
- * column to be more readable on narrow screens
64
+ * while `fixed` forces columns of equal width (sets the
65
+ * [tableLayout](https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout)
66
+ * CSS prop to `fixed`).
67
+ *
68
+ * `stacked` renders table in one column to be more readable on narrow screens
84
69
  */
85
70
  layout?: 'auto' | 'fixed' | 'stacked'
86
71
  /**
87
- * Build table via `Table.Head` and `Table.Body`
72
+ * `Table.Head` or `Table.Body`
88
73
  */
89
74
  children?: React.ReactNode
90
75
  }
@@ -121,11 +106,6 @@ export type {
121
106
  TableProps,
122
107
  TableStyle,
123
108
  // children
124
- HeadChild,
125
- BodyChild,
126
- RowChild,
127
- ColHeaderChild,
128
- RowHeaderChild,
129
- CellChild
109
+ RowChild
130
110
  }
131
111
  export { propTypes, allowedProps }
package/src/index.ts CHANGED
@@ -22,6 +22,7 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
  export { Table } from './Table'
25
+ export { TableContext } from './Table/TableContext'
25
26
 
26
27
  export type { TableProps } from './Table/props'
27
28
  export type { TableBodyProps } from './Table/Body/props'