Skip to content

Commit

Permalink
Add support for passing arbitrary props
Browse files Browse the repository at this point in the history
Closes GH-51.

Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com>
Reviewed-by: Titus Wormer <tituswormer@gmail.com>
  • Loading branch information
remcohaszing authored May 8, 2021
1 parent f17dc4e commit 0beeda6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 29 deletions.
4 changes: 2 additions & 2 deletions lib/plugin/recma-document.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ export function recmaDocument(options = {}) {
attributes: [
{
type: 'JSXSpreadAttribute',
argument: {type: 'Identifier', name: '_props'}
argument: {type: 'Identifier', name: 'props'}
}
],
selfClosing: false
Expand All @@ -477,7 +477,7 @@ export function recmaDocument(options = {}) {
return {
type: 'FunctionDeclaration',
id: {type: 'Identifier', name: 'MDXContent'},
params: [{type: 'Identifier', name: '_props'}],
params: [{type: 'Identifier', name: 'props'}],
body: {
type: 'BlockStatement',
body: [
Expand Down
2 changes: 1 addition & 1 deletion lib/plugin/recma-jsx-rewrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export function recmaJsxRewrite(options = {}) {
) {
parameters.push({
type: 'MemberExpression',
object: {type: 'Identifier', name: '_props'},
object: {type: 'Identifier', name: 'props'},
property: {type: 'Identifier', name: 'components'},
computed: false,
optional: false
Expand Down
33 changes: 19 additions & 14 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,16 @@ import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runti

export var Thing = () => _jsx(_Fragment, {children: 'World!'})

function MDXContent(_props) {
const _components = Object.assign({h1: 'h1'}, _props.components)
function MDXContent(props) {
const _components = Object.assign({h1: 'h1'}, props.components)
const {wrapper: MDXLayout} = _components
const _content = _jsx(_Fragment, {
children: _jsxs(_components.h1, {
children: ['Hello, ', _jsx(Thing, {})]
})
})
return MDXLayout
? _jsx(MDXLayout, Object.assign({}, _props, {children: _content}))
? _jsx(MDXLayout, Object.assign({}, props, {children: _content}))
: _content
}

Expand Down Expand Up @@ -379,14 +379,14 @@ async function main(code) {
```js
import {Fragment as _Fragment, jsx as _jsx} from 'react/jsx-runtime'
export var no = 3.14
function MDXContent(_props) { /**/ }
function MDXContent(props) { /**/ }
export default MDXContent
```

```js
const {Fragment: _Fragment, jsx: _jsx} = arguments[0]
var no = 3.14
function MDXContent(_props) { /**/ }
function MDXContent(props) { /**/ }
return {no, default: MDXContent}
```

Expand Down Expand Up @@ -434,7 +434,7 @@ console.log(String(compileSync(code, {outputFormat: 'function-body', useDynamicI
const {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0]
const {name} = await import('./meta.js')
const {no} = await import('./numbers.js')
function MDXContent(_props) { /**/ }
function MDXContent(props) { /**/ }
return {no, default: MDXContent}
```

Expand Down Expand Up @@ -475,7 +475,7 @@ async function main() {
```js
import {Fragment as _Fragment, jsx as _jsx} from 'react/jsx-runtime'
export {number} from 'https://a.full/data.js'
function MDXContent(_props) { /**/ }
function MDXContent(props) { /**/ }
export default MDXContent
```

Expand Down Expand Up @@ -548,9 +548,9 @@ compile(file, {providerImportSource: '@mdx-js/react'})

export var Thing = () => React.createElement(React.Fragment, null, 'World!')

function MDXContent(_props) {
- const _components = Object.assign({h1: 'h1'}, _props.components)
+ const _components = Object.assign({h1: 'h1'}, _provideComponents(), _props.components)
function MDXContent(props) {
- const _components = Object.assign({h1: 'h1'}, props.components)
+ const _components = Object.assign({h1: 'h1'}, _provideComponents(), props.components)
const {wrapper: MDXLayout} = _components
const _content = React.createElement(
React.Fragment,
Expand Down Expand Up @@ -582,8 +582,8 @@ compile(file, {jsx: true})
-export var Thing = () => React.createElement(React.Fragment, null, 'World!')
+export var Thing = () => <>World!</>

function MDXContent(_props) {
const _components = Object.assign({h1: 'h1'}, _props.components)
function MDXContent(props) {
const _components = Object.assign({h1: 'h1'}, props.components)
const {wrapper: MDXLayout} = _components
- const _content = _jsx(_Fragment, {
- children: _jsxs(_components.h1, {
Expand Down Expand Up @@ -1136,19 +1136,23 @@ Expressions can be empty or contain just a comment:
All content (headings, paragraphs, etc) you write are exported as the default
export from a compiled MDX file as a component.

It’s possible to pass components in.
It’s possible to pass props in.
The special prop `components` is used to determine how to render components.
This includes both JSX and markdown syntax.
Say we have a `message.mdx` file:

```mdx
# Hello, *<Planet />*!

Remember when we first met in {props.year}?
```

This file could be imported from JavaScript and passed components like so:

```js
import Message from './message.mdx' // Assumes an integration is used to compile MDX -> JS.

<Message components={{Planet: () => 'Venus'}} />
<Message components={{Planet: () => 'Venus'}} year={1962} />
```

You can also change the things that come from markdown:
Expand All @@ -1165,6 +1169,7 @@ You can also change the things that come from markdown:
// Pass a component.
Planet: () => 'Venus'
}}
year={1962}
/>
```

Expand Down
41 changes: 29 additions & 12 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,13 +652,13 @@ test('jsx', async function (t) {
String(compileSync('*a*', {jsx: true})),
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'function MDXContent(_props) {',
'function MDXContent(props) {',
' const _components = Object.assign({',
' p: "p",',
' em: "em"',
' }, _props.components), {wrapper: MDXLayout} = _components;',
' }, props.components), {wrapper: MDXLayout} = _components;',
' const _content = <><_components.p><_components.em>{"a"}</_components.em></_components.p></>;',
' return MDXLayout ? <MDXLayout {..._props}>{_content}</MDXLayout> : _content;',
' return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;',
'}',
'export default MDXContent;',
''
Expand All @@ -670,10 +670,10 @@ test('jsx', async function (t) {
String(compileSync('<a {...b} c d="1" e={1} />', {jsx: true})),
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'function MDXContent(_props) {',
' const _components = Object.assign({}, _props.components), {wrapper: MDXLayout} = _components;',
'function MDXContent(props) {',
' const _components = Object.assign({}, props.components), {wrapper: MDXLayout} = _components;',
' const _content = <><a {...b} c d="1" e={1} /></>;',
' return MDXLayout ? <MDXLayout {..._props}>{_content}</MDXLayout> : _content;',
' return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;',
'}',
'export default MDXContent;',
''
Expand All @@ -685,10 +685,10 @@ test('jsx', async function (t) {
String(compileSync('<><a:b /><c.d/></>', {jsx: true})),
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'function MDXContent(_props) {',
' const _components = Object.assign({}, _props.components), {wrapper: MDXLayout, c} = _components;',
'function MDXContent(props) {',
' const _components = Object.assign({}, props.components), {wrapper: MDXLayout, c} = _components;',
' const _content = <><><a:b /><c.d /></></>;',
' return MDXLayout ? <MDXLayout {..._props}>{_content}</MDXLayout> : _content;',
' return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;',
'}',
'export default MDXContent;',
''
Expand All @@ -701,17 +701,34 @@ test('jsx', async function (t) {
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'/*1*/',
'function MDXContent(_props) {',
' const _components = Object.assign({}, _props.components), {wrapper: MDXLayout} = _components;',
'function MDXContent(props) {',
' const _components = Object.assign({}, props.components), {wrapper: MDXLayout} = _components;',
' const _content = <><>{"a "}{}{" b"}</></>;',
' return MDXLayout ? <MDXLayout {..._props}>{_content}</MDXLayout> : _content;',
' return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;',
'}',
'export default MDXContent;',
''
].join('\n'),
'should serialize fragments, expressions'
)

t.equal(
String(compileSync('Hello {props.name}', {jsx: true})),
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'function MDXContent(props) {',
' const _components = Object.assign({',
' p: "p"',
' }, props.components), {wrapper: MDXLayout} = _components;',
' const _content = <><_components.p>{"Hello "}{props.name}</_components.p></>;',
' return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;',
'}',
'export default MDXContent;',
''
].join('\n'),
'should allow using props'
)

t.match(
String(compileSync("{<w x='y \" z' />}", {jsx: true})),
/x="y &quot; z"/,
Expand Down

0 comments on commit 0beeda6

Please sign in to comment.