Skip to content

Commit

Permalink
Improve the user experience with large and complex tables (#1508)
Browse files Browse the repository at this point in the history
* feat: added table column width distribution input & fixed table exploding outside set width

* feat: added scrollable cell for wider content

* chore: updated table documentation and prep for merge

* fix: remove formatting from README.md and add to ignore file
  • Loading branch information
dmitrymatio committed May 10, 2023
1 parent c1f305a commit fa50cf6
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 33 deletions.
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package.json
example
.cache
.cache
README.md
91 changes: 90 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1691,6 +1691,95 @@ Use `videoUrl` to add the local video to the block
Use `position` to position the video values are `left`, `right`. The preset variant is left.
### Table Block
The table block automatically decorates markdown and html tables:
Markdown:
```md
| Tables | Are | Cool |
| ------------- | :-----------: | ----: |
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
```
HTML:
```html
<table>
<th>
<td>Tables</td>
<td>Are</td>
<td>Cool</td>
</th>
<tr>
<td>col 3 is</td>
<td>right-aligned</td>
<td>$1600</td>
</tr>
<tr>
<td>col 2 is</td>
<td>centered</td>
<td>$12</td>
</tr>
<tr>
<td>zebra stripes</td>
<td>are neat</td>
<td>$1</td>
</tr>
</table>
```
Will both look like this:
![styled markdown table](docs/images/table-md.png)
**When should I use an HTML table over Markdown?**
Markdown has a simple way of defining and formatting your tables, but it can be limited in customization and difficult to format with a lot of data. You should consider using HTML tables if you're experiencing said limitations.
_Here is a couple of examples:_
By default, the column width distribution is even across all columns in the table. To customize it we support a `columnWidths` property which you can configure like so:
```html
<table columnWidths="20,60,20">
...
</table>
```
![styled markdown table](docs/images/table-custom-distribution.png)
The `columnWidths` property expects a distribution by percentage of the table width. _Comma separated numbers only_.
You can assign any distribution as long as the number of entries matches the number of columns and the distribution adds up to 100% otherwise it may not work as expected.
| # Columns | Default Distribution | Custom Distribution Example |
| --------- | -------------------- | --------------------------- |
| 2 | "50,50" | "25,75" |
| 3 | "33.33,33.33,33.33" | "10,20,70" |
| 4 | "25,25,25,25" | "10,20,35,35" |
We also support inline css overrides using the css property like so:
```html
<table
css="
background-color:teal;
tbody {
background-color:orange;
}">
...
</table>
```
![styled markdown table](docs/images/table-custom-css.png)
Combining modifiers is supported as well unless mentioned otherwise.
### Tabs Block
Tabs block is a custom block component that allows for tabbed content that can be displayed either vertically or horizontally.
Expand Down Expand Up @@ -2295,4 +2384,4 @@ You can check the latest released version of the theme at <https://github.com/ad
This repository is setup as a monorepo using [lerna](https://github.com/lerna/lerna) for automated publishing to NPM.
Use `GH_TOKEN=[YOUR_GH_TOKEN] lerna version --create-release github --conventional-commits --no-private -m "chore(release): publish"` for publishing the theme on npm.
Use `GH_TOKEN=[YOUR_GH_TOKEN] lerna version --create-release github --conventional-commits --no-private -m "chore(release): publish"` for publishing the theme on npm.
Binary file added docs/images/table-custom-css.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/table-custom-distribution.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/table-md.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
148 changes: 117 additions & 31 deletions packages/gatsby-theme-aio/src/components/Table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,132 @@
* governing permissions and limitations under the License.
*/

import React from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { css } from '@emotion/react';
import PropTypes from 'prop-types';
import '@spectrum-css/table';
import {layoutColumns, MOBILE_SCREEN_WIDTH, TABLET_SCREEN_WIDTH} from "../../utils";

const tableOverrides = `
margin-top: var(--spectrum-global-dimension-size-150);
`;

const Table = ({ children, css: cssOverrides, ...props }) => (
<div css={css`overflow-x: auto; overflow-y: hidden;`}>
<table className="spectrum-Table spectrum-Table--sizeM" {...props}
css={css`
${tableOverrides}
${cssOverrides}`}>
{children}
import { MOBILE_SCREEN_WIDTH } from '../../utils';

const Table = ({ children, css: cssOverrides, columnWidths, ...props }) => {
const [width, setWidth] = useState(MOBILE_SCREEN_WIDTH);
const tableRef = useRef(null);
const columnWidthDistribution = columnWidths
? columnWidths
.split(',')
.map(num => (width * Number(num)) / 100)
.filter(width => !isNaN(width))
: [];

useEffect(() => {
if (tableRef.current.parentNode) {
setWidth(Number(tableRef.current.parentNode.offsetWidth));
}
}, [width]);

return (
<table
ref={tableRef}
className="spectrum-Table spectrum-Table--sizeM"
css={css`
overflow: hidden;
margin-bottom: var(--spectrum-global-dimension-size-150);
width: ${width}px;
${cssOverrides}
`}
{...props}>
{children.map(child => {
child.props.tableWidth = width;
child.props.columnWidthDistribution = columnWidthDistribution;
return child;
})}
</table>
</div>
);
);
};

const THead = ({ children }) => <thead className="spectrum-Table-head">{children}</thead>;
const THead = ({ children, ...props }) => {
return (
<thead
className="spectrum-Table-head"
css={css`
width: ${props.parentWidth}px;
`}>
{[children].map(child => {
child.props.tableWidth = props.tableWidth;
child.props.columnWidthDistribution = props.columnWidthDistribution;
return child;
})}
</thead>
);
};

const Th = ({ children }) => <th className="spectrum-Table-headCell">{children}</th>;

const TBody = ({ children }) => <tbody className="spectrum-Table-body">{children}</tbody>;
const TBody = ({ children, ...props }) => {
const childrenArr = children.length > 1 ? children : [children];
return (
<tbody
className="spectrum-Table-body"
css={css`
width: ${props.tableWidth}px;
`}>
{childrenArr.map(child => {
child.props.tableWidth = props.tableWidth;
child.props.columnWidthDistribution = props.columnWidthDistribution;
return child;
})}
</tbody>
);
};

const Tr = ({ children, ...props }) => {
const tableWidth = props.tableWidth;
const columnCount = parseInt(children.length);
const columnWidthDistribution = !props.columnWidthDistribution.length
? Array(columnCount).fill(Number(tableWidth) / columnCount)
: props.columnWidthDistribution;

return (
<tr
className="spectrum-Table-row"
css={css`
cursor: inherit;
width: ${props.tableWidth}px;
&:hover {
background-color: inherit;
}
`}>
{children.map((child, index) => {
child.props.cellWidth = columnWidthDistribution[index];
return child;
})}
</tr>
);
};

const Tr = ({ children }) => (
<tr
className="spectrum-Table-row"
css={css`
cursor: inherit;
const Td = ({ children, ...props }) => {
return (
<td
className="spectrum-Table-cell"
css={css`
width: ${props.cellWidth}px;
max-width: ${props.cellWidth}px;
&:hover {
background-color: inherit;
}
`}>
{children}
</tr>
);
overflow-x: auto;
`}>
<div
css={css`
max-width: ${props.cellWidth}px;
`}>
{children}
</div>
</td>
);
};

const Td = ({ children }) => <td className="spectrum-Table-cell">{children}</td>;
Table.propTypes = {
css: PropTypes.string,
columnWidths: PropTypes.string,
};

export { Table, THead, Th, TBody, Tr, Td };

0 comments on commit fa50cf6

Please sign in to comment.