Skip to content

Commit

Permalink
add iframe to component
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtek-krysiak committed Sep 2, 2019
1 parent 52ce3fb commit 0760b65
Show file tree
Hide file tree
Showing 6 changed files with 322 additions and 11 deletions.
162 changes: 162 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,168 @@ class YourClass {
}
```

## @component plugin

Better-docs also allows you to document your React and Vue (soon) components automatically. The only thing you have to do is to add `@component` tag. It will take all props from your components and along with an `@example` tag - generate __live preview__.

### Installation instructions

Similar as before to add a plugin - you have to update `plugins` section in your `jsdoc.json` file:

```
...
"tags": {
"allowUnknownTags": ["component"] //or true
},
"plugins": [
"node_modules/better-docs/component"
],
...
```

Since __component__ plugin uses [parcel](https://parceljs.org) as a bundler you have to install it globally. In order to do this run:

```
# if you use npm
npm install -g parcel-bundler
# or yarn
yarn global add parcel-bundler
```

### Usage

To document components simply add @component in your JSDoc documentation:

```
/**
* Some documented component
*
* @component
*/
const Documented = (props) => {
const { text } = props
return (
<div>{text}</div>
)
}
Documented.propTypes = {
/**
* Text is a text
*/
text: PropTypes.string.isRequired,
}
export default Documented
```

Plugin will take the information from your [PropTypes](https://reactjs.org/docs/typechecking-with-proptypes.html) and put them into an array.

### Preview

@component plugin also modifies the behaviour of `@example` tag in a way that it can generate an actual __component preview__ if it returns a component:

```javacript
/**
* Some documented component
*
* @component
* @example
* const text = 'some example text'
* return (
* <Documented text={text} />
* )
*/
const Component = (props) => {
///...
}
```

You put as many examples as you like in one component.

### Mixing components in preview

Also you can use other components which are documented with component tag. So lets say you have 2 components

```javascript
// component-1.js
/**
* Component 1
* @component
*
*/
const Component1 = (props) => {...}

// component-2.js
/**
* Component 2
* @component
* @example
* return (
* <Component1>
* <Component2 prop1={'some value'}/>
* <Component2 prop1={'some other value'}/>
* </Component1>
* )
*/
const Component2 = (props) => {...}
```

### Wrapper components

Most probably your components will have to run within particular context, like within redux store provider or with custom CSS libraries.
You can simulate this by passing a `component.wrapper` in your `jsdoc.json`:
_(To read more about passing options - scroll down to __Customization__ section)_

```json
// jsdoc.json
{
"opts": {...},
"templates": {
"better-docs": {
"name": "AdminBro Documentation",
"component": {
"wrapper": "./path/to/your/wrapper-component.js",
},
"...": "...",
}
}
}
```

Wrapper component can look like this:

```javascript
// wrapper-component.js
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'

const store = createStore(() => ({}), {})

const Component = (props) => {
return (
<React.Fragment>
<head>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css" />
</head>
<Provider store={store}>
<BrowserRouter>
{props.children}
</BrowserRouter>
</Provider>
</React.Fragment>
)
}

export default Component
```

### Document Vue components

_comming soon_

## Customization

Expand Down
17 changes: 15 additions & 2 deletions bundler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const fs = require('fs')
const path = require('path')
const execSync = require('child_process').execSync

module.exports = function bundle (Components, out, config) {
if (!Components.length) {
return
}
const entry = path.join(out, 'entry.js')
const absoluteOut = path.resolve(out)
let init = `
Expand All @@ -14,8 +18,8 @@ module.exports = function bundle (Components, out, config) {
window.ReactDOM = ReactDOM;\n
window.Wrapper = Wrapper;\n
`
if (config.betterDocs.wrapperComponent) {
const absolute = path.resolve(config.betterDocs.wrapperComponent)
if (config.betterDocs.component && config.betterDocs.component.wrapper) {
const absolute = path.resolve(config.betterDocs.component.wrapper)
init +=`
import _CustomWrapper from '${path.relative(absoluteOut, absolute)}';\n
Components._CustomWrapper = _CustomWrapper;\n
Expand All @@ -30,5 +34,14 @@ module.exports = function bundle (Components, out, config) {
].join('\n')
}).join('\n\n')

console.log('Generating entry file for "components" plugin')
fs.writeFileSync(entry, entryFile);
console.log('Bundling components')
try {
const outDist = path.join(out, 'build')
const cmd = `parcel build ${entry} --out-dir ${outDist}`
execSync(cmd)
} catch (error) {
throw error
}
}
7 changes: 7 additions & 0 deletions bundler.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
it('does not generate files when there are no components', function () {

})

it('throws error message when there is no parcel', function () {

})
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
},
"dependencies": {
"brace": "^0.11.1",
"react-ace": "^6.5.0"
"react-ace": "^6.5.0",
"react-docgen": "^4.1.1",
"react-frame-component": "^4.1.1"
}
}
5 changes: 3 additions & 2 deletions wrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'

import brace from 'brace';
import AceEditor from 'react-ace'
import Frame from 'react-frame-component'

import 'brace/mode/jsx';
import 'brace/theme/monokai';
Expand Down Expand Up @@ -78,11 +79,11 @@ class Wrapper extends React.Component {
</div>
<div>
<h5>Preview</h5>
<div className="component-wrapper">
<Frame className="component-wrapper">
<ComponentRenderer>
{component}
</ComponentRenderer>
</div>
</Frame>
</div>
</div>
)
Expand Down
Loading

0 comments on commit 0760b65

Please sign in to comment.