Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render caption in table if passed in as a prop #540

Merged
merged 10 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .storybook/styles/components/_table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,9 @@ th{
content:"▲";
}
}

.custom-caption {
font-weight: bold;
font-size: 0.8rem;
color: $blue-dark;
}
1 change: 1 addition & 0 deletions .storybook/styles/settings/variables/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//BLUE
$blue-light: #BEE4FF;
$blue-base: #6BC2FF;
$blue-dark: #006AB5;

//GREEN
$green-dark: #56C852;
Expand Down
6 changes: 3 additions & 3 deletions migration-guides/v7.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This version contains the following breaking changes:
8. `<CloudinaryFileInput />` and `<FileInput />` components now default to allowing the user to remove a selected file
9. The `previewComponent` for a file input no longer receives a `value` prop and `file` is a file object (with the url)
10. The tag on `<Spinner />` now uses the class `spinner` in place of an id and supports additional classes
11. `<TabBar />` now expects both `options` and `value` as required props.
11. `<TabBar />` now expects both `options` and `value` as required props
12. `<Modal />` no longer accepts the `hideCloseButton` prop
13. `<FlashMessageContainer />` component invokes `onDismiss` with redux-flash message object and allows message-specific overrides
14. `<Button />` and `<SubmitButton />` now accept a forwarded ref
Expand Down Expand Up @@ -244,7 +244,7 @@ Replace any styling rules that target `#spinner` with `.spinner`.
}
```

## 11. `<TabBar />` now expects both `options` and `value` as required props.
## 11. `<TabBar />` now expects both `options` and `value` as required props

Make sure that any instances of `<TabBar />` in your application are already sending these two props.

Expand All @@ -255,7 +255,7 @@ Make sure that any instances of `<TabBar />` in your application are already sen
/>
```

## 12. `<Modal />` no longer accepts the `hideCloseButton` prop.
## 12. `<Modal />` no longer accepts the `hideCloseButton` prop
Replace `hideCloseButton` with `preventClose`. If you still need the modal to close on escape and/or by clicking the overlay, you can manually set those props. By default, `shouldCloseOnEsc` and `shouldCloseOnOverlayClick` will be set to the opposite of `preventClose` (default `false`).

```jsx
Expand Down
39 changes: 24 additions & 15 deletions src/tables/sortable-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const propTypes = {
onChange: PropTypes.func,
rowComponent: Types.component,
headerComponent: Types.component,
caption: PropTypes.node,
}
const defaultProps = {
className: '',
Expand All @@ -57,6 +58,7 @@ const defaultProps = {
disableSort: false,
controlled: false,
onChange: noop,
caption: null,
}
const defaultControls = {
initialSortPath: '',
Expand Down Expand Up @@ -92,6 +94,7 @@ function SortableTable({
onChange,
rowComponent,
headerComponent,
caption,
...rest
}) {
const columns = getColumnData(children, disableSort)
Expand Down Expand Up @@ -148,28 +151,34 @@ function SortableTable({
}

return (
<table className={classnames(className, { 'sortable-table': !disableSort })} {...filterInvalidDOMProps(rest)}>
<table
className={classnames(className, { 'sortable-table': !disableSort })}
{...filterInvalidDOMProps(rest)}
>
{caption && <caption>{caption}</caption>}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only change in return

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be rendered as the first child of the <table>. See previous comment for source

<thead>
<tr>
{columns.map((column, key) => {
const Header = column.headerComponent || headerComponent || DefaultHeader
return (
<Header {...{
const Header =
column.headerComponent || headerComponent || DefaultHeader
return (
<Header
{...{
key,
column,
sortPath,
ascending,
onClick: () => handleColumnChange(column)
}} />
)
}
)}
onClick: () => handleColumnChange(column),
}}
/>
)
})}
</tr>
</thead>
<tbody>
{
data.map((rowData, key) =>
<Row {...{
{data.map((rowData, key) => (
<Row
{...{
key,
rowData,
columns,
Expand All @@ -178,9 +187,9 @@ function SortableTable({
sortPath,
sortFunc,
valueGetter,
}} />
)
}
}}
/>
))}
</tbody>
</table>
)
Expand Down
2 changes: 1 addition & 1 deletion stories/tables/sortable-table.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ storiesOf('SortableTable', module)
</SortableTable>
</div>
))
.add('with custom value getter, custom sorter, iniital column', () => (
.add('with custom value getter, custom sorter, initial column', () => (
<div>
<h2>"Name and Age" column combines name and age, sorted by age portion, initial column</h2>
<SortableTable data={tableData} initialColumn="nameAndAge">
Expand Down
14 changes: 14 additions & 0 deletions stories/tables/table.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,17 @@ storiesOf('Table', module)
<Column name="active" component={ CustomCell } />
</Table>
))
.add('with caption', () => (
<Table data={tableData} caption="Participant Attributes">
<Column name="name" />
<Column name="age" />
<Column name="active" />
</Table>
))
.add('with customized caption', () => (
<Table data={tableData} caption={<span className="custom-caption">Participant Attributes</span>}>
<Column name="name" />
<Column name="age" />
<Column name="active" />
</Table>
))
31 changes: 29 additions & 2 deletions test/tables/sortable-table.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ test('column can have a column-specific custom header component', () => {
expect(wrapper.find(MyHeader).first().props().column.name).toEqual('name')
})

test('initialColumn determines inital sortPath and sortFunc', () => {
test('initialColumn determines initial sortPath and sortFunc', () => {
const mySort = jest.fn(compareAtPath('name', sortAscending))
const wrapper = mount(
<SortableTable data={tableData} initialColumn="name">
Expand Down Expand Up @@ -273,7 +273,7 @@ test('`placeholder` option is displayed if value is `null` or `undefined`', () =
expect(wrapper.find('td').last().text()).toEqual('placeholder')
})

test('can recieve custom class name', () => {
test('can receive custom class name', () => {
const data = [
{ name: null },
{ name: undefined },
Expand Down Expand Up @@ -385,3 +385,30 @@ test('does not pass invalid DOM props to cells', () => {
)
expect(wrapper.find('td').first().prop('customAttribute')).toBe(undefined)
})

test('does not render a caption element by default', () => {
const wrapper = mount(
<SortableTable data={tableData}>
<Column name="name" />
</SortableTable>
)
expect(wrapper.find('caption').exists()).toBe(false)
})

test('renders a caption element when provided as the first descendant', () => {
const wrapper = mount(
<SortableTable data={tableData} caption="My Table">
<Column name="name" />
</SortableTable>
)
expect(wrapper.find('table').childAt(0).type()).toBe('caption')
})

test('renders a caption element with whatever is provided', () => {
const wrapper = mount(
<SortableTable data={tableData} caption={<span className="custom-caption">My Table</span>}>
<Column name="name" />
</SortableTable>
)
expect(wrapper.find('.custom-caption').text()).toBe('My Table')
})