@instructure/ui-table 10.2.1-snapshot-2 → 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
@@ -875,12 +875,17 @@ render(
875
875
 
876
876
  ### Using Custom Components as Children
877
877
 
878
- In some cases you might want to use custom components in a `Table`, e.g. a HOC for `Table.Row` or `Table.Cell`. This is generally not recommended but sometimes it could be beneficial for codesplitting or writing cleaner code for larger and more complex Tables. In those cases you have to pay attention to always pass down the appropriate props manually.
878
+ In some cases you might want to use custom components in a `Table`, e.g. a HOC for `Table.Row` or `Table.Cell`. This is generally not recommended, but sometimes it could be beneficial for codesplitting or writing cleaner code for larger and more complex Tables.
879
+
880
+ > Do not replace `Table.Body` and `Table.Head` with custom components
881
+
882
+ Wrapper HOCs are simple, just return the original component:
879
883
 
880
884
  ```javascript
881
885
  ---
882
886
  type: example
883
887
  ---
888
+
884
889
  class CustomTableCell extends React.Component {
885
890
  render () {
886
891
  return (
@@ -944,7 +949,6 @@ class Example extends React.Component {
944
949
 
945
950
  render() {
946
951
  const { layout, hover } = this.state
947
-
948
952
  return (
949
953
  <div>
950
954
  {this.renderOptions()}
@@ -985,6 +989,299 @@ class Example extends React.Component {
985
989
  render(<Example />)
986
990
  ```
987
991
 
992
+ #### Fully custom components
993
+
994
+ If you want to use fully custom components you have to pay attention to the following:
995
+
996
+ - Render them as the appropriate HTML Table tags (`tr`, `th`, ...)
997
+ - Read the `hover` prop from `TableContext` to customize hover behaviour
998
+ - A11y: Row header cells must have the `scope='row'` HTML attribute
999
+ - A11y: Column header cells must have the `scope='col'` and `aria-sort` (if sortable) HTML attribute
1000
+
1001
+ Basic fully custom table:
1002
+
1003
+ ```javascript
1004
+ ---
1005
+ type: example
1006
+ ---
1007
+
1008
+ class CustomTableCell extends React.Component {
1009
+ render() {
1010
+ return <td>{this.props.children}</td>
1011
+ }
1012
+ }
1013
+
1014
+ class CustomTableRow extends React.Component {
1015
+ static contextType = TableContext
1016
+ state = { isHovered: false }
1017
+
1018
+ toggleHoverOff = () => {
1019
+ this.setState({isHovered: false})
1020
+ }
1021
+ toggleHoverOn = () => {
1022
+ this.setState({isHovered: true})
1023
+ }
1024
+ render() {
1025
+ // super ugly way to change CSS on hover
1026
+ let css = {backgroundColor: 'white'}
1027
+ if (this.context.hover && this.state.isHovered) {
1028
+ css = {backgroundColor: 'SeaGreen'}
1029
+ }
1030
+ return (
1031
+ <tr style={css} onMouseOver={this.toggleHoverOn} onMouseOut={this.toggleHoverOff}>
1032
+ {this.props.children}
1033
+ </tr>
1034
+ )
1035
+ }
1036
+ }
1037
+
1038
+ class Example extends React.Component {
1039
+ state = {
1040
+ layout: 'auto',
1041
+ hover: false,
1042
+ }
1043
+
1044
+ handleChange = (field, value) => {
1045
+ this.setState({
1046
+ [field]: value,
1047
+ })
1048
+ }
1049
+
1050
+ renderOptions () {
1051
+ const { layout, hover } = this.state
1052
+
1053
+ return (
1054
+ <Flex alignItems="start">
1055
+ <Flex.Item margin="small">
1056
+ <RadioInputGroup
1057
+ name="Layout"
1058
+ description="Layout"
1059
+ value={layout}
1060
+ onChange={(e, value) => this.handleChange('layout', value)}
1061
+ >
1062
+ <RadioInput label="auto" value="auto" />
1063
+ <RadioInput label="fixed" value="fixed" />
1064
+ </RadioInputGroup>
1065
+ </Flex.Item>
1066
+ <Flex.Item margin="small">
1067
+ <Checkbox
1068
+ label="hover"
1069
+ checked={hover}
1070
+ onChange={(e, value) => this.handleChange('hover', !hover)}
1071
+ />
1072
+ </Flex.Item>
1073
+ </Flex>
1074
+ )
1075
+ }
1076
+
1077
+ render() {
1078
+ const { layout, hover } = this.state
1079
+
1080
+ return (
1081
+ <div>
1082
+ {this.renderOptions()}
1083
+ <Table
1084
+ caption='Top rated movies'
1085
+ layout={layout}
1086
+ hover={hover}
1087
+ >
1088
+ <Table.Head>
1089
+ <CustomTableRow>
1090
+ <CustomTableCell scope='col'>Rank</CustomTableCell>
1091
+ <CustomTableCell scope='col'>Title</CustomTableCell>
1092
+ <CustomTableCell scope='col'>Year</CustomTableCell>
1093
+ <CustomTableCell scope='col'>Rating</CustomTableCell>
1094
+ </CustomTableRow>
1095
+ </Table.Head>
1096
+ <Table.Body>
1097
+ <CustomTableRow>
1098
+ <CustomTableCell scope='row'>1</CustomTableCell>
1099
+ <CustomTableCell>The Godfather</CustomTableCell>
1100
+ <CustomTableCell>1972</CustomTableCell>
1101
+ <CustomTableCell>9.2</CustomTableCell>
1102
+ </CustomTableRow>
1103
+ <CustomTableRow>
1104
+ <CustomTableCell scope='row'>2</CustomTableCell>
1105
+ <CustomTableCell>The Godfather: Part II</CustomTableCell>
1106
+ <CustomTableCell>1974</CustomTableCell>
1107
+ <CustomTableCell>9.0</CustomTableCell>
1108
+ </CustomTableRow>
1109
+ </Table.Body>
1110
+ </Table>
1111
+ </div>
1112
+ )
1113
+ }
1114
+ }
1115
+
1116
+ render(<Example />)
1117
+ ```
1118
+
1119
+ #### Fully custom components with `stacked` layout
1120
+
1121
+ This layout for small screens displays the table as a list. To accomplish this the headers are passed down to cells (in `TableContext`), so they can display what column they are rendering.
1122
+ In this layout for accessibility not render HTML table tags, just plain DOM elements (e.g. `div`) and use the appropriate ARIA role to signify that it's actually a `Table` (e.g. [`cell`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/cell_role), [`row`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/row_role), [`rowheader`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/rowheader_role)).
1123
+ Also you need the following props on the components:
1124
+
1125
+ ##### Table rows
1126
+
1127
+ - It should read the `headers` array from `TableContext` and pass its nth element to its nth child (if they have such prop).
1128
+
1129
+ ##### The children of the first row in `Table.Head` (`Table.ColHeader` by default)
1130
+
1131
+ - If the table is sortable the Table needs `id`, `onRequestSort`, `sortDirection` and `stackedSortByLabel` props to render a `Select` to choose how to sort the `Table` (see the props of `Table.ColHeader` for types)
1132
+
1133
+ ##### Table cells
1134
+
1135
+ - It needs to have an optional `header` prop and should display its value so the user knows which column the cell's value belongs to (you can read whether the table is using `stacked` layout from `TableContext`.
1136
+
1137
+ Custom table with `stacked` layout support:
1138
+
1139
+ ```javascript
1140
+ ---
1141
+ type: example
1142
+ ---
1143
+
1144
+ class CustomTableCell extends React.Component {
1145
+ static contextType = TableContext
1146
+
1147
+ render() {
1148
+ const isStacked = this.context.isStacked
1149
+ if (isStacked) {
1150
+ let headerTxt
1151
+ if (typeof this.props.header === 'function') {
1152
+ headerTxt = React.createElement(this.props.header)
1153
+ } else {
1154
+ headerTxt = this.props.header
1155
+ }
1156
+ return <div role="cell">
1157
+ {headerTxt && headerTxt}
1158
+ {headerTxt && ': '}
1159
+ {this.props.children}
1160
+ </div>
1161
+ }
1162
+ return <td>{this.props.children}</td>
1163
+ }
1164
+ }
1165
+
1166
+ class CustomTableRow extends React.Component {
1167
+ static contextType = TableContext
1168
+ state = { isHovered: false }
1169
+
1170
+ toggleHoverOff = () => {
1171
+ this.setState({isHovered: false})
1172
+ }
1173
+ toggleHoverOn = () => {
1174
+ this.setState({isHovered: true})
1175
+ }
1176
+ render() {
1177
+ // super ugly way to change CSS on hover
1178
+ let css = {backgroundColor: 'white'}
1179
+ if (this.context.hover && this.state.isHovered) {
1180
+ css = {backgroundColor: 'SeaGreen'}
1181
+ }
1182
+ const headers = this.context.headers
1183
+ const isStacked = this.context.isStacked
1184
+ const Tag = isStacked ? 'div' : 'tr'
1185
+ return (
1186
+ <Tag style={css} role={isStacked ? 'row' : undefined}
1187
+ onMouseOver={this.toggleHoverOn} onMouseOut={this.toggleHoverOff}>
1188
+ {React.Children.toArray(this.props.children)
1189
+ .filter(React.isValidElement)
1190
+ .map((child, index) => {
1191
+ return React.cloneElement(child, {
1192
+ key: child.props.name,
1193
+ // used by `CustomTableCell` to render its column title in `stacked` layout
1194
+ header: headers && headers[index]
1195
+ })
1196
+ })
1197
+ }
1198
+ </Tag>
1199
+ )
1200
+ }
1201
+ }
1202
+
1203
+ class Example extends React.Component {
1204
+ state = {
1205
+ layout: 'auto',
1206
+ hover: false,
1207
+ }
1208
+
1209
+ handleChange = (field, value) => {
1210
+ this.setState({
1211
+ [field]: value,
1212
+ })
1213
+ }
1214
+
1215
+ renderOptions () {
1216
+ const { layout, hover } = this.state
1217
+
1218
+ return (
1219
+ <Flex alignItems="start">
1220
+ <Flex.Item margin="small">
1221
+ <RadioInputGroup
1222
+ name="customStackedLayout"
1223
+ description="Layout"
1224
+ value={layout}
1225
+ onChange={(e, value) => this.handleChange('layout', value)}
1226
+ >
1227
+ <RadioInput label="auto" value="auto" />
1228
+ <RadioInput label="fixed" value="fixed" />
1229
+ <RadioInput label="stacked" value="stacked" />
1230
+ </RadioInputGroup>
1231
+ </Flex.Item>
1232
+ <Flex.Item margin="small">
1233
+ <Checkbox
1234
+ label="hover"
1235
+ checked={hover}
1236
+ onChange={(e, value) => this.handleChange('hover', !hover)}
1237
+ />
1238
+ </Flex.Item>
1239
+ </Flex>
1240
+ )
1241
+ }
1242
+
1243
+ render() {
1244
+ const { layout, hover } = this.state
1245
+
1246
+ return (
1247
+ <div>
1248
+ {this.renderOptions()}
1249
+ <Table
1250
+ caption='Top rated movies'
1251
+ layout={layout}
1252
+ hover={hover}
1253
+ >
1254
+ <Table.Head>
1255
+ <CustomTableRow>
1256
+ <CustomTableCell scope='col'>Rank</CustomTableCell>
1257
+ <CustomTableCell scope='col'>Title</CustomTableCell>
1258
+ <CustomTableCell scope='col'>Year</CustomTableCell>
1259
+ <CustomTableCell scope='col'>Rating</CustomTableCell>
1260
+ </CustomTableRow>
1261
+ </Table.Head>
1262
+ <Table.Body>
1263
+ <CustomTableRow>
1264
+ <CustomTableCell scope='row'>1</CustomTableCell>
1265
+ <CustomTableCell>The Godfather</CustomTableCell>
1266
+ <CustomTableCell>1972</CustomTableCell>
1267
+ <CustomTableCell>9.2</CustomTableCell>
1268
+ </CustomTableRow>
1269
+ <CustomTableRow>
1270
+ <CustomTableCell scope='row'>2</CustomTableCell>
1271
+ <CustomTableCell>The Godfather: Part II</CustomTableCell>
1272
+ <CustomTableCell>1974</CustomTableCell>
1273
+ <CustomTableCell>9.0</CustomTableCell>
1274
+ </CustomTableRow>
1275
+ </Table.Body>
1276
+ </Table>
1277
+ </div>
1278
+ )
1279
+ }
1280
+ }
1281
+
1282
+ render(<Example />)
1283
+ ```
1284
+
988
1285
  ### Guidelines
989
1286
 
990
1287
  ```js
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  /** @jsx jsx */
26
- import { Component, Children } from 'react'
26
+ import { Component, Children, ContextType, isValidElement } from 'react'
27
27
 
28
28
  import { omitProps, safeCloneElement } from '@instructure/ui-react-utils'
29
29
  import { View } from '@instructure/ui-view'
@@ -35,6 +35,7 @@ import generateComponentTheme from './theme'
35
35
 
36
36
  import type { TableRowProps } from './props'
37
37
  import { allowedProps, propTypes } from './props'
38
+ import TableContext from '../TableContext'
38
39
 
39
40
  /**
40
41
  ---
@@ -45,7 +46,8 @@ id: Table.Row
45
46
  @withStyle(generateStyle, generateComponentTheme)
46
47
  class Row extends Component<TableRowProps> {
47
48
  static readonly componentId = 'Table.Row'
48
-
49
+ static contextType = TableContext
50
+ declare context: ContextType<typeof TableContext>
49
51
  static allowedProps = allowedProps
50
52
  static propTypes = propTypes
51
53
 
@@ -54,15 +56,23 @@ class Row extends Component<TableRowProps> {
54
56
  }
55
57
 
56
58
  componentDidMount() {
57
- this.props.makeStyles?.()
59
+ this.props.makeStyles?.({
60
+ isStacked: this.context.isStacked,
61
+ hover: this.context.hover
62
+ })
58
63
  }
59
64
 
60
65
  componentDidUpdate() {
61
- this.props.makeStyles?.()
66
+ this.props.makeStyles?.({
67
+ isStacked: this.context.isStacked,
68
+ hover: this.context.hover
69
+ })
62
70
  }
63
71
 
64
72
  render() {
65
- const { children, styles, isStacked, headers } = this.props
73
+ const { children, styles } = this.props
74
+ const isStacked = this.context.isStacked
75
+ const headers = this.context.headers
66
76
 
67
77
  return (
68
78
  <View
@@ -73,12 +83,18 @@ class Row extends Component<TableRowProps> {
73
83
  >
74
84
  {Children.toArray(children)
75
85
  .filter(Boolean)
76
- .map((child: any, index) => {
77
- return safeCloneElement(child, {
78
- key: child.props.name,
79
- isStacked,
80
- header: headers && headers[index]
81
- })
86
+ .map((child, index) => {
87
+ if (isValidElement(child)) {
88
+ return safeCloneElement(child, {
89
+ key: child.props.name,
90
+ // Sent down for compatibility with custom components
91
+ // TODO DEPRECATED, remove in v11
92
+ isStacked,
93
+ // used by `Cell` to render its column title in `stacked` layout
94
+ header: headers && headers[index]
95
+ })
96
+ }
97
+ return child
82
98
  })}
83
99
  </View>
84
100
  )
@@ -25,8 +25,6 @@
25
25
  import React from 'react'
26
26
  import PropTypes from 'prop-types'
27
27
 
28
- import type { TableCellProps } from '../Cell/props'
29
-
30
28
  import type {
31
29
  OtherHTMLAttributes,
32
30
  PropValidators,
@@ -35,13 +33,13 @@ import type {
35
33
  import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
36
34
 
37
35
  type TableRowOwnProps = {
38
- hover?: boolean
39
- isStacked?: boolean
40
- headers?: TableCellProps['header'][]
41
36
  /**
42
- * `Table.ColHeader`, `Table.RowHeader` or `Table.Cell`
37
+ * A row's children should be table cells. Its children should have the
38
+ * `header` prop to render the column header in `stacked` layout
39
+ *
40
+ * By default `Table.ColHeader` or `Table.RowHeader` or `Table.Cell`
43
41
  */
44
- children?: React.ReactNode
42
+ children?: React.ReactElement | React.ReactElement[]
45
43
  }
46
44
 
47
45
  type PropKeys = keyof TableRowOwnProps
@@ -55,20 +53,10 @@ type TableRowProps = TableRowOwnProps &
55
53
  type TableRowStyle = ComponentStyle<'row'>
56
54
 
57
55
  const propTypes: PropValidators<PropKeys> = {
58
- children: PropTypes.node,
59
- hover: PropTypes.bool,
60
- isStacked: PropTypes.bool,
61
- headers: PropTypes.arrayOf(
62
- PropTypes.oneOfType([PropTypes.node, PropTypes.func])
63
- )
56
+ children: PropTypes.node
64
57
  }
65
58
 
66
- const allowedProps: AllowedPropKeys = [
67
- 'children',
68
- 'hover',
69
- 'isStacked',
70
- 'headers'
71
- ]
59
+ const allowedProps: AllowedPropKeys = ['children']
72
60
 
73
61
  export type { TableRowProps, TableRowStyle }
74
62
  export { propTypes, allowedProps }
@@ -32,15 +32,14 @@ import type { TableRowProps, TableRowStyle } from './props'
32
32
  * Generates the style object from the theme and provided additional information
33
33
  * @param {Object} componentTheme The theme variable object.
34
34
  * @param {Object} props the props of the component, the style is applied to
35
- * @param {Object} state the state of the component, the style is applied to
35
+ * @param {Object} extraArgs the state of the component, the style is applied to
36
36
  * @return {Object} The final style object, which will be used in the component
37
37
  */
38
38
  const generateStyle = (
39
39
  componentTheme: TableRowTheme,
40
- props: TableRowProps
40
+ _props: TableRowProps,
41
+ extraArgs: { isStacked: boolean; hover: boolean }
41
42
  ): TableRowStyle => {
42
- const { hover, isStacked } = props
43
-
44
43
  return {
45
44
  row: {
46
45
  label: 'row',
@@ -54,7 +53,7 @@ const generateStyle = (
54
53
  borderBottomWidth: '0.0625rem',
55
54
  borderBottomColor: componentTheme.borderColor,
56
55
 
57
- ...(hover && {
56
+ ...(extraArgs.hover && {
58
57
  borderLeft: '0.1875rem solid transparent',
59
58
  borderRight: '0.1875rem solid transparent',
60
59
 
@@ -64,7 +63,7 @@ const generateStyle = (
64
63
  }
65
64
  }),
66
65
 
67
- ...(isStacked && { padding: componentTheme.padding })
66
+ ...(extraArgs.isStacked && { padding: componentTheme.padding })
68
67
  }
69
68
  }
70
69
  }
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  /** @jsx jsx */
26
- import { Component } from 'react'
26
+ import { Component, ContextType } from 'react'
27
27
 
28
28
  import { omitProps, callRenderProp } from '@instructure/ui-react-utils'
29
29
  import { View } from '@instructure/ui-view'
@@ -34,6 +34,7 @@ import generateStyle from './styles'
34
34
  import generateComponentTheme from './theme'
35
35
  import type { TableRowHeaderProps } from './props'
36
36
  import { allowedProps, propTypes } from './props'
37
+ import TableContext from '../TableContext'
37
38
 
38
39
  /**
39
40
  ---
@@ -44,7 +45,8 @@ id: Table.RowHeader
44
45
  @withStyle(generateStyle, generateComponentTheme)
45
46
  class RowHeader extends Component<TableRowHeaderProps> {
46
47
  static readonly componentId = 'Table.RowHeader'
47
-
48
+ static contextType = TableContext
49
+ declare context: ContextType<typeof TableContext>
48
50
  static allowedProps = allowedProps
49
51
  static propTypes = propTypes
50
52
 
@@ -62,8 +64,8 @@ class RowHeader extends Component<TableRowHeaderProps> {
62
64
  }
63
65
 
64
66
  render() {
65
- const { children, isStacked, styles } = this.props
66
-
67
+ const { children, styles } = this.props
68
+ const isStacked = this.context.isStacked
67
69
  return (
68
70
  <View
69
71
  {...View.omitViewProps(
@@ -33,7 +33,6 @@ import type {
33
33
  import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
34
34
 
35
35
  type TableRowHeaderOwnProps = {
36
- isStacked?: boolean
37
36
  /**
38
37
  * Control the text alignment in row header
39
38
  */
@@ -53,11 +52,10 @@ type TableRowHeaderStyle = ComponentStyle<'rowHeader'>
53
52
 
54
53
  const propTypes: PropValidators<PropKeys> = {
55
54
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
56
- isStacked: PropTypes.bool,
57
55
  textAlign: PropTypes.oneOf(['start', 'center', 'end'])
58
56
  }
59
57
 
60
- const allowedProps: AllowedPropKeys = ['children', 'isStacked', 'textAlign']
58
+ const allowedProps: AllowedPropKeys = ['children', 'textAlign']
61
59
 
62
60
  export type { TableRowHeaderProps, TableRowHeaderStyle }
63
61
  export { propTypes, allowedProps }
@@ -0,0 +1,54 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { createContext } from 'react'
26
+ import { Renderable } from '@instructure/shared-types'
27
+
28
+ type TableContextType = {
29
+ /**
30
+ * If `true` the table gets rendered in one column to be more readable on
31
+ * narrow screens.
32
+ */
33
+ isStacked: boolean
34
+ /**
35
+ * Highlight each row on hover.
36
+ */
37
+ hover: boolean
38
+ /**
39
+ * Contents of the first row of cells. Has value if `isStacked` is `true`.
40
+ */
41
+ headers?: Renderable[]
42
+ }
43
+
44
+ /**
45
+ * React context created by the `Table` component to hold its data
46
+ */
47
+ const TableContext = createContext<TableContextType>({
48
+ isStacked: false,
49
+ hover: false
50
+ })
51
+
52
+ export default TableContext
53
+ export { TableContext }
54
+ export type { TableContextType }