Skip to content

Commit

Permalink
feat: error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyjosephprice committed May 7, 2024
1 parent 365055b commit a5f219b
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 60 deletions.
32 changes: 30 additions & 2 deletions components/Table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
import React from 'react';

interface Props extends JSX.IntrinsicAttributes {
align?: ('left' | 'center' | 'right')[];
children: [React.ReactElement<HTMLTableCaptionElement | HTMLTableSectionElement | HTMLTableRowElement>];
rows?: [[any]];
}

const TableContent = ({ rows, align = [] }: Omit<Props, 'children'>) => {
const [head, ...body] = rows;

return (
<>
<thead>
<tr>
{head.map((cell, index) => (
<th style={{ textAlign: align[index] || 'center' }}>{cell}</th>
))}
</tr>
</thead>
<tbody>
{body.map(row => (
<tr>
{row.map((cell, index) => (

Check failure on line 24 in components/Table/index.tsx

View workflow job for this annotation

GitHub Actions / Bundle Watch

Property 'map' does not exist on type 'never'.
<td style={{ textAlign: align[index] || 'center' }}>{cell}</td>
))}
</tr>
))}
</tbody>
</>
);
};

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

return (
<div className="rdmd-table">
<div className="rdmd-table-inner">
<table>{children}</table>
<table>{rest.rows ? <TableContent {...rest} /> : children}</table>
</div>
</div>
);
Expand Down
23 changes: 23 additions & 0 deletions docs/mdx-components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Tables

If you have some tabular data, it may be easier to write it with mdx:

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

<Table align={['left', 'center', 'right']} rows={table} />;
```

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

<Table align={['left', 'center', 'right']} rows={table} />
26 changes: 17 additions & 9 deletions docs/tables.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
title: "Tables"
title: 'Tables'
category: 5fdf7610134322007389a6ed
hidden: false
---

## Syntax

| Left | Center | Right |
Expand All @@ -20,7 +21,7 @@ hidden: false
This example also shows off custom theming!

| Left | Center | Right |
|:-----|:--------:|------:|
| :--- | :------: | ----: |
| L0 | **bold** | $1600 |
| L1 | `code` | $12 |
| L2 | _italic_ | $1 |
Expand All @@ -35,25 +36,32 @@ 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;
}
```

```scss CSS Selectors
/* Table
*/
.markdown-body .rdmd-table table {}
.markdown-body .rdmd-table table {
}

/* 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 tr {
}
.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 {}
.markdown-body .rdmd-table th {
}
.markdown-body .rdmd-table td {
}
```

<style>
Expand Down
26 changes: 26 additions & 0 deletions errors/mdx-syntax-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { VFileMessage } from 'vfile-message';

export default class MdxSyntaxError extends SyntaxError {
original = '';

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

const messages = [
`Uh oh! 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;

Check failure on line 24 in errors/mdx-syntax-error.ts

View workflow job for this annotation

GitHub Actions / Bundle Watch

Type 'VFileMessage' is not assignable to type 'string'.
}
}
14 changes: 10 additions & 4 deletions example/Doc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const Doc = () => {
fixture === 'edited' ? [fixture, searchParams.get('edit') || ''] : [docs[fixture].name, docs[fixture].doc];

const [Content, setContent] = useState<FunctionComponent>(null);
const [error, setError] = useState<string>(null);

useEffect(() => {
const render = async () => {
Expand All @@ -23,10 +24,15 @@ const Doc = () => {
safeMode,
};

const code = mdx.compile(doc, opts);
const content = await mdx.run(code);
try {
const code = mdx.compile(doc, opts);
const content = await mdx.run(code);

setContent(() => content);
setError(() => null);
setContent(() => content);
} catch (e) {
setError(() => e.message);
}
};

render();
Expand All @@ -38,7 +44,7 @@ const Doc = () => {
<section id="hub-content">
{!ci && <h2 className="rdmd-demo--markdown-header">{name}</h2>}
<div id="content-container">
<RenderError>
<RenderError error={error}>
<div className="markdown-body">{Content && <Content />}</div>
</RenderError>
</div>
Expand Down
10 changes: 6 additions & 4 deletions example/RenderError.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { PropsWithChildren } from 'react';

interface Props {}
interface Props {
error?: string;
}

interface State {
hasError: boolean;
Expand All @@ -19,13 +21,13 @@ class RenderError extends React.Component<PropsWithChildren<Props>, State> {
}

render() {
const { children } = this.props;
const { children, error } = this.props;
const { hasError, message } = this.state;

return hasError ? (
return hasError || error ? (
<div className="error">
<pre>
<code>{message}</code>
<code>{message || error}</code>
</pre>
</div>
) : (
Expand Down
3 changes: 3 additions & 0 deletions example/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import images from '../docs/images.md';
// @ts-ignore
import lists from '../docs/lists.md';
// @ts-ignore
import mdxComponents from '../docs/mdx-components.mdx';
// @ts-ignore
import sanitizingTests from '../docs/sanitizing-tests.md';
// @ts-ignore
import tableOfContentsTests from '../docs/table-of-contents-tests.md';
Expand All @@ -43,6 +45,7 @@ const fixtures = Object.entries({
headings,
images,
lists,
mdxComponents,
sanitizingTests,
tableOfContentsTests,
tables,
Expand Down
32 changes: 18 additions & 14 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { getHref } from './components/Anchor';
import BaseUrlContext from './contexts/BaseUrl';
import { options } from './options';

require('./styles/main.scss');
import transformers from './processor/transform';
import compilers from './processor/compile';
import MdxSyntaxError from './errors/mdx-syntax-error';

import calloutTransformer from './processor/transform/callouts';
import gemojiTransformer from './processor/transform/gemoji+';
import gemojiCompiler from './processor/compile/gemoji';
require('./styles/main.scss');

const unimplemented = debug('mdx:unimplemented');

Expand Down Expand Up @@ -46,21 +46,25 @@ const makeUseMDXComponents = (more: RunOpts['components']) => {
return () => components;
};

const remarkPlugins = [remarkFrontmatter, calloutTransformer, gemojiTransformer];
const remarkPlugins = [remarkFrontmatter, ...transformers];

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/astToPlainText.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/astToPlainText.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/compilers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/disabling-tokenizers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/disabling-tokenizers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/html-block-parser.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/html-block-parser.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/index.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/index.test.js:4:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/link-parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/link-parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/react.test.tsx

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/react.test.tsx:2:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/compilers/break.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/break.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 18)

__tests__/compilers/code-tabs.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/code-tabs.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/astToPlainText.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/astToPlainText.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/compilers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/disabling-tokenizers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/disabling-tokenizers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/html-block-parser.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/html-block-parser.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/index.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/index.test.js:4:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/link-parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/link-parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/react.test.tsx

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/react.test.tsx:2:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/compilers/break.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/break.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 16)

__tests__/compilers/code-tabs.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/code-tabs.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/astToPlainText.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/astToPlainText.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/compilers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/disabling-tokenizers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/disabling-tokenizers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/html-block-parser.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/html-block-parser.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/index.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/index.test.js:4:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/link-parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/link-parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/parsers.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/parsers.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/react.test.tsx

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/react.test.tsx:2:31

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/compilers/break.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/break.test.js:1:1

Check failure on line 49 in index.tsx

View workflow job for this annotation

GitHub Actions / Test (lts/-1, 17)

__tests__/compilers/code-tabs.test.js

TypeError: default is not iterable ❯ index.tsx:49:46 ❯ __tests__/compilers/code-tabs.test.js:1:1

export const reactProcessor = (opts = {}) => {
return createProcessor({ remarkPlugins, ...opts });
};

export const compile = (text: string, opts = {}) => {
return String(
compileSync(text, {
outputFormat: 'function-body',
providerImportSource: '#',
remarkPlugins,
...opts,
}),
).replace(/await import\(_resolveDynamicMdxSpecifier\('react'\)\)/, 'arguments[0].imports.React');
try {
return String(
compileSync(text, {
outputFormat: 'function-body',
providerImportSource: '#',
remarkPlugins,
...opts,
}),
).replace(/await import\(_resolveDynamicMdxSpecifier\('react'\)\)/, 'arguments[0].imports.React');
} catch (error) {
throw new MdxSyntaxError(error, text);
}
};

export const run = async (code: string, _opts: RunOpts = {}) => {
Expand All @@ -86,7 +90,7 @@ export const reactTOC = (text: string, opts = {}) => {
export const mdx = (tree: any, opts = {}) => {
return remark()
.use(remarkMdx)
.data({ toMarkdownExtensions: [{ extensions: [gemojiCompiler] }] })
.data({ toMarkdownExtensions: [{ extensions: compilers }] })
.stringify(tree, opts);
};

Expand Down
Loading

0 comments on commit a5f219b

Please sign in to comment.