Added script to auto add component definitions to bottom of readme
parent
5c8330ac7d
commit
4ceee8d0dc
|
@ -2,6 +2,10 @@ import React, { PropTypes } from 'react';
|
|||
import ClassNames from 'classnames';
|
||||
import style from './style';
|
||||
|
||||
/**
|
||||
* The base card component. This acts as the main card element
|
||||
* that all subcomponents are placed within.
|
||||
*/
|
||||
const Card = ({
|
||||
children,
|
||||
className,
|
||||
|
@ -23,6 +27,7 @@ const Card = ({
|
|||
Card.propTypes = {
|
||||
children: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
/** Increases the shadow depth */
|
||||
raised: PropTypes.bool
|
||||
};
|
||||
|
||||
|
|
|
@ -22,17 +22,4 @@ const TestCards = () => (
|
|||
);
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Name | Type | Default | Description|
|
||||
|:-----|:-----|:-----|:-----|
|
||||
| `actions` | `Array` | | Array of objects describing actions. These actions will be rendered as buttons and the object fields will be transferred to those.|
|
||||
| `className` | `String` | `''` | Sets a class to give customized styles to the card.|
|
||||
| `color` | `String` | | Sets HEX or RGBA color to add a colored layer to the heading.|
|
||||
| `image` | `String` | | URL to sets a background image in the heading.|
|
||||
| `loading` | `Boolean` | `false` | If true, component will be disabled and showing a loading animation.|
|
||||
| `onClick` | `Function` | | Callback function that is fired when the components's is clicked. It also will display a ripple effect on click. |
|
||||
| `subtitle` | `String` | | Sets a complementary smaller text under the title.|
|
||||
| `text` | `String` | | Sets a complementary text display as a card description.|
|
||||
| `title` | `String` | | Sets the title of the card.|
|
||||
| `type` | `String` | `default` | Type of the component to display general modifications. It can be `wide` for a larger card, `image` if it's an image card or `event` which shows just a title on top. |
|
||||
<!--component-docgen-start-->
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
"babel-eslint": "^4.1.5",
|
||||
"babel-loader": "^5.3.2",
|
||||
"babel-plugin-react-transform": "^1.1.1",
|
||||
"bluebird": "^3.0.5",
|
||||
"classnames": "^2.2.0",
|
||||
"core-js": "^1.2.6",
|
||||
"cpx": "^1.2.1",
|
||||
|
@ -67,6 +68,7 @@
|
|||
"expect": "^1.8.0",
|
||||
"express": "^4.13.3",
|
||||
"extract-text-webpack-plugin": "^0.8.2",
|
||||
"glob": "^6.0.1",
|
||||
"karma": "^0.13.3",
|
||||
"karma-chrome-launcher": "^0.2.0",
|
||||
"karma-cli": "^0.1.0",
|
||||
|
@ -82,6 +84,7 @@
|
|||
"react": "^0.14",
|
||||
"react-addons-css-transition-group": "^0.14.0",
|
||||
"react-addons-test-utils": "^0.14.0",
|
||||
"react-docgen": "^2.4.0",
|
||||
"react-dom": "^0.14.0",
|
||||
"react-transform-catch-errors": "^1.0.0",
|
||||
"react-transform-hmr": "^1.0.1",
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
import Fs from 'fs';
|
||||
import GenerateMarkdown from './generateMarkdown';
|
||||
import Glob from 'glob';
|
||||
import Path from 'path';
|
||||
import { parse as ParseComponent } from 'react-docgen';
|
||||
import Promise from 'bluebird';
|
||||
|
||||
const getComponentName = (filepath) => {
|
||||
let name = Path.basename(filepath);
|
||||
let ext;
|
||||
while ((ext = Path.extname(name))) {
|
||||
name = name.substring(0, name.length - ext.length);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
|
||||
const componentGlob = Path.join(process.argv[2], '/*.jsx');
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
Glob(componentGlob, (err, files) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
return resolve(files);
|
||||
});
|
||||
}).then(filePaths => {
|
||||
const files = {};
|
||||
|
||||
filePaths.forEach(path => {
|
||||
files[getComponentName(path)] = new Promise((resolveRead, rejectRead) => {
|
||||
Fs.readFile(path, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
return rejectRead(err);
|
||||
}
|
||||
|
||||
return resolveRead(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.props(files);
|
||||
}).then(fulfillments => {
|
||||
for (const componentName in fulfillments) {
|
||||
fulfillments[componentName] = ParseComponent(fulfillments[componentName]);
|
||||
}
|
||||
|
||||
return fulfillments;
|
||||
}).then(fulfillments => {
|
||||
let markdown = '';
|
||||
|
||||
for (const componentName in fulfillments) {
|
||||
const reactAPI = fulfillments[componentName];
|
||||
markdown = markdown.concat(GenerateMarkdown(componentName, reactAPI)).concat('\n\n');
|
||||
}
|
||||
|
||||
return markdown;
|
||||
}).then(markdown => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
Fs.readFile(Path.join(process.argv[2], '/readme.md'), 'utf8', (err, contents) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
const contentLines = contents.split('\n');
|
||||
const introLines = [];
|
||||
|
||||
contentLines.some(line => {
|
||||
introLines.push(line);
|
||||
|
||||
if (line === '<!--component-docgen-start-->') {
|
||||
introLines.push('\n');
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const newMarkdown = introLines.join('\n').concat(markdown);
|
||||
|
||||
return resolve(newMarkdown);
|
||||
});
|
||||
|
||||
});
|
||||
}).then(newMarkdown => {
|
||||
Fs.writeFileSync(Path.join(process.argv[2], '/readme.md'), newMarkdown);
|
||||
});
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Copyright (c) 2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Converted to ES6 by Nathan Marks <info@nathanmarks.io>
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
// function stringOfLength (string, length) {
|
||||
// let newString = '';
|
||||
// for (let i = 0; i < length; i++) {
|
||||
// newString += string;
|
||||
// }
|
||||
// return newString;
|
||||
// }
|
||||
|
||||
function generateTitle (name) {
|
||||
return `## ${name}`;
|
||||
}
|
||||
|
||||
function generateDesciption (description) {
|
||||
return description + '\n';
|
||||
}
|
||||
|
||||
function generatePropType (type) {
|
||||
let values;
|
||||
if (Array.isArray(type.value)) {
|
||||
values = '(' +
|
||||
type.value.map(function (typeValue) {
|
||||
return typeValue.name || typeValue.value;
|
||||
}).join('|') +
|
||||
')';
|
||||
} else {
|
||||
values = type.value;
|
||||
}
|
||||
|
||||
return '`' + type.name + (values ? values : '') + '`';
|
||||
}
|
||||
|
||||
function generateProp (propName, prop) {
|
||||
return (
|
||||
`| \`${propName}\` ${prop.required ? '(required)' : ''}` +
|
||||
`| ${(prop.type ? generatePropType(prop.type) : '')} ` +
|
||||
`| ${(prop.defaultValue ? `\`${prop.defaultValue}\`` : '')} ` +
|
||||
`| ${(prop.description ? prop.description : '')} ` +
|
||||
'|'
|
||||
);
|
||||
}
|
||||
|
||||
function generateProps (props) {
|
||||
const title = '##### Props';
|
||||
|
||||
return (
|
||||
`${title}\n` +
|
||||
'| Name | Type | Default | Description |\n' +
|
||||
'|:-----|:-----|:-----|:-----|\n' +
|
||||
Object.keys(props).sort().map(propName => {
|
||||
return generateProp(propName, props[propName]);
|
||||
}).join('\n')
|
||||
);
|
||||
}
|
||||
|
||||
function generateMarkdown (name, reactAPI) {
|
||||
const markdownString =
|
||||
generateTitle(name) + '\n' +
|
||||
(reactAPI.description ? generateDesciption(reactAPI.description) + '\n' : '\n') +
|
||||
generateProps(reactAPI.props);
|
||||
|
||||
return markdownString;
|
||||
}
|
||||
|
||||
module.exports = generateMarkdown;
|
Loading…
Reference in New Issue