Skip to content

Commit

Permalink
feat: tables (#874)
Browse files Browse the repository at this point in the history
| [![PR App][icn]][demo] | Fix RM-9021 |
| :--------------------: | :---------: |

## 🧰 Changes

MDX Tables!

I also took the opportunity to start an MDX components doc, and more
excitingly, a nicer compilation error!

## ✅ TODO

After poking at this a bunch, I think we should punt on doing feature
detection. It seems best that that be done as a singular after we get
everything else working.

## 🧬 QA & Testing

- [Broken on production][prod].
- [Working in this PR app][demo].

[demo]: https://markdown-pr-PR_NUMBER.herokuapp.com
[prod]: https://SUBDOMAIN.readme.io
[icn]:
https://user-images.githubusercontent.com/886627/160426047-1bee9488-305a-4145-bb2b-09d8b757d38a.svg
  • Loading branch information
kellyjosephprice committed May 10, 2024
1 parent 8ac2507 commit ec439ef
Show file tree
Hide file tree
Showing 22 changed files with 222 additions and 241 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions __tests__/browser/markdown.test.js
Expand Up @@ -19,8 +19,8 @@ describe('visual regression tests', () => {
// 'headings',
'images',
// 'lists',
// 'tables',
// 'tablesTests',
'mdxComponents',
'tables',
'codeBlockTests',
// 'tableOfContentsTests',
'varsTest',
Expand Down
99 changes: 20 additions & 79 deletions __tests__/compilers/tables.test.js
@@ -1,99 +1,40 @@
import { mdast, mdx } from '../../index';
import { visit } from 'unist-util-visit';

describe.skip('table compiler', () => {
it('converts to markdown syntax', () => {
describe('table compiler', () => {
it('writes to markdown syntax', () => {
const markdown = `
[block:parameters]
{
"data": {
"h-0": "th 1",
"h-1": "th 2",
"0-0": "cell 1",
"0-1": "cell 2"
},
"cols": 2,
"rows": 1,
"align": [
"center",
"center"
]
}
[/block]
| th 1 | th 2 |
| :----: | :----: |
| cell 1 | cell 2 |
`;

expect(mdx(mdast(markdown))).toBe(
`| th 1 | th 2 |
| :----: | :----: |
| cell 1 | cell 2 |
`
`,
);
});

it('saves to magic block syntax if there are breaks', () => {
const markdown = `
[block:parameters]
{
"data": {
"h-0": "th 1",
"h-1": "th 2",
"0-0": "cell 1\\nextra line",
"0-1": "cell 2"
},
"cols": 2,
"rows": 1,
"align": [
"center",
"center"
]
}
[/block]
`;

expect(mdx(mdast(markdown))).toBe(`[block:parameters]
{
"data": {
"h-0": "th 1",
"h-1": "th 2",
"0-0": "cell 1 \\nextra line",
"0-1": "cell 2"
},
"cols": 2,
"rows": 1,
"align": [
"center",
"center"
]
}
[/block]
`);
});

it('converts to magic block syntax if there are breaks', () => {
it.skip('saves to MDX if there are breaks', () => {
const markdown = `
| th 1 | th 2 |
| :----: | :----: |
| cell 1 | cell 2 |
`;
const nodes = mdast(markdown);
const cell = nodes.children[0].children[1].children[0];
cell.children = [...cell.children, { type: 'break' }, { type: 'text', value: 'extra line' }];

expect(mdx(nodes)).toBe(`[block:parameters]
{
"data": {
"h-0": "th 1",
"h-1": "th 2",
"0-0": "cell 1 \\nextra line",
"0-1": "cell 2"
},
"cols": 2,
"rows": 1,
"align": [
"center",
"center"
]
}
[/block]
`);
const tree = mdast(markdown);

visit(tree, 'tableCell', cell => {
cell.children.push({ type: 'break' }, { type: 'text', value: 'inserted' });
});

expect(mdx(tree)).toMatchInlineSnapshot(`
"| th 1 inserted | th 2 inserted |
| :-------------: | :-------------: |
| cell 1 inserted | cell 2 inserted |
"
`);
});
});
19 changes: 0 additions & 19 deletions components/Table/index.jsx

This file was deleted.

19 changes: 19 additions & 0 deletions components/Table/index.tsx
@@ -0,0 +1,19 @@
import React from 'react';

interface Props extends JSX.IntrinsicAttributes {
children: [React.ReactElement<HTMLTableCaptionElement | HTMLTableSectionElement | HTMLTableRowElement>];
}

const Table = (props: Props) => {
const { children } = props;

return (
<div className="rdmd-table">
<div className="rdmd-table-inner">
<table>{children}</table>
</div>
</div>
);
};

export default Table;
57 changes: 57 additions & 0 deletions docs/mdx-components.mdx
@@ -0,0 +1,57 @@
## Tables

You can use our `Table` component to match the ReadMe theming.

```jsx MDX
export const table = [
['Left', 'Center', 'Right'],
['L0', '**bold**', '$1600'],
['L1', '`code`', '$12'],
['L2', '_italic_', '$1'],
];

<Table>
<thead>
<tr>
{table[0].map((cell, index) => (
<th style={{ textAlign: table[0][index].toLowerCase() }}>{cell}</th>
))}
</tr>
</thead>
<tbody>
{table.slice(1).map(row => (
<tr>
{table[0].map((cell, index) => (
<td style={{ textAlign: table[0][index].toLowerCase() }}>{cell}</td>
))}
</tr>
))}
</tbody>
</Table>;
```

export const table = [
['Left', 'Center', 'Right'],
['L0', '**bold**', '$1600'],
['L1', '`code`', '$12'],
['L2', '_italic_', '$1'],
];

<Table>
<thead>
<tr>
{table[0].map((cell, index) => (
<th style={{ textAlign: table[0][index].toLowerCase() }}>{cell}</th>
))}
</tr>
</thead>
<tbody>
{table.slice(1).map(row => (
<tr>
{row.map((cell, index) => (
<td style={{ textAlign: table[0][index].toLowerCase() }}>{cell}</td>
))}
</tr>
))}
</tbody>
</Table>
18 changes: 0 additions & 18 deletions docs/tables-tests.md

This file was deleted.

63 changes: 34 additions & 29 deletions docs/tables.md
@@ -1,26 +1,25 @@
---
title: "Tables"
title: 'Tables'
category: 5fdf7610134322007389a6ed
hidden: false
---
## Syntax

| Left | Center | Right |
|:-----|:--------:|------:|
| L0 | **bold** | $1600 |
| L1 | `code` | $12 |
| L2 | _italic_ | $1 |
## Syntax

> ❗️ Table cells may contain inline decorations only.
>
> Lists, headings, and other block-level Markdown components are not valid and will cause errors.
```markdown
| Left | Center | Right |
|:-----|:--------:|------:|
| L0 | **bold** | $1600 |
| L1 | `code` | $12 |
| L2 | _italic_ | $1 |
```

### Examples

This example also shows off custom theming!

| Left | Center | Right |
|:-----|:--------:|------:|
| :--- | :------: | ----: |
| L0 | **bold** | $1600 |
| L1 | `code` | $12 |
| L2 | _italic_ | $1 |
Expand All @@ -35,7 +34,7 @@ Tables have been simplified to mirror a more standard implementation. We've also
--table-head: #5b1c9f;
--table-head-text: white;
--table-stripe: #f0eaf7;
--table-edges: rgba(34, 5, 64, .5);
--table-edges: rgba(34, 5, 64, 0.5);
--table-row: white;
}
```
Expand All @@ -47,30 +46,36 @@ Tables have been simplified to mirror a more standard implementation. We've also
/* Rows
*/
.markdown-body .rdmd-table tr {}
.markdown-body .rdmd-table thead tr {} /* header row's background */
.markdown-body .rdmd-table tr:nth-child(2n) {} /* striped rows' background */
.markdown-body .rdmd-table thead tr {}
/* header row's background */
.markdown-body .rdmd-table tr:nth-child(2n) {}
/* striped rows' background */

/* Cells
*/
.markdown-body .rdmd-table th {}
.markdown-body .rdmd-table td {}
```

<style>
.markdown-body .rdmd-table {
--table-text: black;
--table-head: #5b1c9f;
--table-head-text: white;
--table-stripe: #f0eaf7;
--table-edges: rgba(34, 5, 64, .5);
--table-row: white;
}
export const stylesheet = `
.markdown-body .rdmd-table {
--table-text: black;
--table-head: #5b1c9f;
--table-head-text: white;
--table-stripe: #f0eaf7;
--table-edges: rgba(34, 5, 64, .5);
--table-row: white;
}

#rdmd-demo .markdown-body .rdmd-table thead tr {
box-shadow: none;
}
#rdmd-demo .markdown-body .rdmd-table thead tr {
box-shadow: none;
}

#rdmd-demo .markdown-body .rdmd-table thead tr th:last-child {
box-shadow: none;
}
`;

#rdmd-demo .markdown-body .rdmd-table thead tr th:last-child {
box-shadow: none;
}
<style>
{stylesheet}
</style>
26 changes: 26 additions & 0 deletions errors/mdx-syntax-error.ts
@@ -0,0 +1,26 @@
import { VFileMessage } from 'vfile-message';

export default class MdxSyntaxError extends SyntaxError {
original: VFileMessage = null;

constructor(error: VFileMessage, doc: string) {
const { message, line, column, url } = error;

const messages = [
`Oh no! We ran into a syntax error at { line: ${line}, column: ${column} }, please see this url for more details: ${url}`,
];

if (typeof line !== 'undefined') {
messages.push(doc.split('\n')[line - 1]);

if (typeof column !== 'undefined') {
const prefix = new Array(column).map(() => '').join(' ');
messages.push(`${prefix}${message}`);
}
}

super(messages.join('\n'));

this.original = error;
}
}

0 comments on commit ec439ef

Please sign in to comment.