Skip to content

Commit cb1b2ae

Browse files
committed
fix(ui-table): fix table crashing in stacked layout when using falsy children
Also fix a table example that was using Children instead of React.Children, fix CodeSandboxes crashing because missing imports Make CodeSandbox examples nicer by only importing samples when needed Fixes INSTUI-4534
1 parent cf3f025 commit cb1b2ae

File tree

4 files changed

+65
-16
lines changed

4 files changed

+65
-16
lines changed

packages/__docs__/src/CodeSandboxButton/index.tsx

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,25 +42,51 @@ class CodeSandboxButton extends Component<CodeSandboxButtonProps> {
4242
render() {
4343
//TODO: we should not import everything everytime
4444
//somehow conditionally import needed modules
45-
const importStatements = `import {useState, useEffect} from "react"
45+
const importStatements = `import React, {useState, useEffect, useContext, Children} from "react"
4646
import ReactDOM from "react-dom"
4747
import moment from 'moment'
48-
import {avatarSquare, avatarPortrait, lorem} from "./samplemedia"
49-
import {placeholderImage} from "./samplemedia"
50-
import iconExample from "!svg-inline-loader!./heart_lg.svg"
5148
import 'moment/min/locales'
5249
`
53-
const reactComponentPattern = /<[A-Z]\w+|Icon\w+/gm
54-
const neededClasses = this.props.code
55-
.match(reactComponentPattern)
56-
?.map((className) => className.replace(/</gm, '').trim())
50+
let importExampleIcon = ''
51+
if (this.props.code.includes('iconExample(')) {
52+
importExampleIcon =
53+
'import iconExample from "!svg-inline-loader!./heart_lg.svg"'
54+
}
5755

58-
if (this.props.code.includes('Calendar')) {
59-
neededClasses?.push('Calendar')
56+
// import sample media
57+
const neededSampleMedia: string[] = []
58+
if (this.props.code.includes('avatarSquare')) {
59+
neededSampleMedia.push('avatarSquare')
60+
}
61+
if (this.props.code.includes('avatarPortrait')) {
62+
neededSampleMedia.push('avatarPortrait')
63+
}
64+
if (this.props.code.includes('lorem.')) {
65+
neededSampleMedia.push('lorem')
66+
}
67+
if (this.props.code.includes('placeholderImage(')) {
68+
neededSampleMedia.push('placeholderImage')
6069
}
70+
const importSampleMedia =
71+
neededSampleMedia.length > 0
72+
? `import { ${neededSampleMedia.join(', ')} } from './samplemedia'\n`
73+
: ''
6174

75+
// import InstUI components/icons/Context
76+
const neededClasses: string[] = []
77+
const reactComponentPattern = /<[A-Z]\w+|Icon\w+/gm // React component or an icon
78+
this.props.code
79+
.match(reactComponentPattern)
80+
?.forEach((className) =>
81+
neededClasses.push(className.replace(/</gm, '').trim())
82+
)
83+
if (this.props.code.includes('Calendar')) {
84+
neededClasses.push('Calendar')
85+
}
86+
this.props.code
87+
.match(/[A-Z]\w+Context/gm)
88+
?.forEach((className) => neededClasses.push(className))
6289
const uniqueClasses = [...new Set(neededClasses)]
63-
6490
const externalElements = this.props.code
6591
.match(/class.\w+|function.\w+|const.\w+/gm)
6692
?.map((className) =>
@@ -86,7 +112,13 @@ import 'moment/min/locales'
86112
const renderStatement = `const render = (el) => { ReactDOM.render(el, document.getElementById('app')) }\n`
87113
const codeSandboxData = {
88114
title: this.props.title,
89-
js: importStatements + importClasses + renderStatement + codeBlock,
115+
js:
116+
importStatements +
117+
importExampleIcon +
118+
importSampleMedia +
119+
importClasses +
120+
renderStatement +
121+
codeBlock,
90122
private: true,
91123
editors: '001',
92124
html: `<div id="app"></div>

packages/ui-table/src/Table/Head/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class Head extends Component<TableHeadProps> {
117117
let count = 0
118118
Children.forEach(firstRow.props.children, (grandchild) => {
119119
count += 1
120-
if (!grandchild.props) return
120+
if (!grandchild?.props) return // grandchild can be false
121121
const { id, stackedSortByLabel, sortDirection, onRequestSort } =
122122
grandchild.props
123123
if (id && onRequestSort) {

packages/ui-table/src/Table/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,7 +2014,7 @@ Custom table with `stacked` layout support:
20142014
onMouseOver={this.toggleHoverOn}
20152015
onMouseOut={this.toggleHoverOff}
20162016
>
2017-
{Children.toArray(this.props.children)
2017+
{React.Children.toArray(this.props.children)
20182018
.filter(React.isValidElement)
20192019
.map((child, index) => {
20202020
return React.cloneElement(child, {
@@ -2144,7 +2144,7 @@ Custom table with `stacked` layout support:
21442144
onMouseOver={() => setIsHovered(true)}
21452145
onMouseOut={() => setIsHovered(false)}
21462146
>
2147-
{Children.toArray(children)
2147+
{React.Children.toArray(children)
21482148
.filter(React.isValidElement)
21492149
.map((child, index) => {
21502150
return React.cloneElement(child, {

packages/ui-table/src/Table/__new-tests__/Table.test.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,27 @@ describe('<Table />', async () => {
155155
render(
156156
<Table caption="Test table" layout="stacked">
157157
<Table.Head>
158+
{/* @ts-expect-error error is normal here */}
158159
<Table.Row>
159160
<Table.Cell>Foo</Table.Cell>
161+
{}
162+
{false}
160163
</Table.Row>
161164
</Table.Head>
165+
<Table.Body>
166+
<Table.Row>
167+
<Table.RowHeader>1</Table.RowHeader>
168+
<Table.Cell>The Shawshank Redemption</Table.Cell>
169+
<Table.Cell>1994</Table.Cell>
170+
<Table.Cell>9.3</Table.Cell>
171+
</Table.Row>
172+
<Table.Row>
173+
<Table.RowHeader>2</Table.RowHeader>
174+
<Table.Cell>The Godfather</Table.Cell>
175+
<Table.Cell>1972</Table.Cell>
176+
<Table.Cell>9.2</Table.Cell>
177+
</Table.Row>
178+
</Table.Body>
162179
</Table>
163180
)
164181
const stackedTable = screen.getByRole('table')
@@ -167,7 +184,7 @@ describe('<Table />', async () => {
167184
expect(stackedTable).not.toHaveTextContent('Foo')
168185
})
169186

170-
it('does not crash for invalid children', async () => {
187+
it('does not crash for invalid children in stacked layout', async () => {
171188
render(
172189
<Table caption="Test table" layout="stacked">
173190
test1

0 commit comments

Comments
 (0)