mirror of
https://github.com/status-im/react-native.git
synced 2025-01-27 01:40:08 +00:00
Add logic to show style props in docs
This commit is contained in:
parent
e811181034
commit
d5f670d19c
@ -17,6 +17,7 @@ var React = require('React');
|
||||
var Site = require('Site');
|
||||
var slugify = require('slugify');
|
||||
|
||||
var styleReferencePattern = /^[^.]+\.propTypes\.style$/;
|
||||
|
||||
var ComponentDoc = React.createClass({
|
||||
renderType: function(type) {
|
||||
@ -40,12 +41,20 @@ var ComponentDoc = React.createClass({
|
||||
}
|
||||
|
||||
if (type.name === 'custom') {
|
||||
if (styleReferencePattern.test(type.raw)) {
|
||||
var name = type.raw.substring(0, type.raw.indexOf('.'));
|
||||
return <a href={slugify(name) + '.html#style'}>{name}#style</a>
|
||||
}
|
||||
if (type.raw === 'EdgeInsetsPropType') {
|
||||
return '{top: number, left: number, bottom: number, right: number}';
|
||||
}
|
||||
return type.raw;
|
||||
}
|
||||
|
||||
if (type.name === 'stylesheet') {
|
||||
return 'style';
|
||||
}
|
||||
|
||||
if (type.name === 'func') {
|
||||
return 'function';
|
||||
}
|
||||
@ -63,6 +72,8 @@ var ComponentDoc = React.createClass({
|
||||
{this.renderType(prop.type)}
|
||||
</span>}
|
||||
</Header>
|
||||
{prop.type && prop.type.name === 'stylesheet' &&
|
||||
this.renderStylesheetProps(prop.type.value)}
|
||||
{prop.description && <Marked>{prop.description}</Marked>}
|
||||
</div>
|
||||
);
|
||||
@ -78,6 +89,41 @@ var ComponentDoc = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
renderStylesheetProps: function(stylesheetName) {
|
||||
var style = this.props.content.styles[stylesheetName];
|
||||
return (
|
||||
<div className="compactProps">
|
||||
{(style.composes || []).map((name) => {
|
||||
var link;
|
||||
if (name !== 'LayoutPropTypes') {
|
||||
name = name.replace('StylePropTypes', '');
|
||||
link =
|
||||
<a href={slugify(name) + '.html#style'}>{name}#style...</a>;
|
||||
} else {
|
||||
link =
|
||||
<a href={slugify(name) + '.html#proptypes'}>{name}...</a>;
|
||||
}
|
||||
return (
|
||||
<div className="prop" key={name}>
|
||||
<h6 className="propTitle">{link}</h6>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{Object.keys(style.props).sort().map((name) =>
|
||||
<div className="prop" key={name}>
|
||||
<h6 className="propTitle">
|
||||
{name}
|
||||
{' '}
|
||||
{style.props[name].type && <span className="propType">
|
||||
{this.renderType(style.props[name].type)}
|
||||
</span>}
|
||||
</h6>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
renderProps: function(props, composes) {
|
||||
return (
|
||||
<div className="props">
|
||||
@ -197,7 +243,11 @@ var APIDoc = React.createClass({
|
||||
var Autodocs = React.createClass({
|
||||
render: function() {
|
||||
var metadata = this.props.metadata;
|
||||
var content = JSON.parse(this.props.children);
|
||||
var docs = JSON.parse(this.props.children);
|
||||
var content = docs.type === 'component' || docs.type === 'style' ?
|
||||
<ComponentDoc content={docs} /> :
|
||||
<APIDoc content={docs} />;
|
||||
|
||||
return (
|
||||
<Site section="docs">
|
||||
<section className="content wrap documentationContent">
|
||||
@ -205,11 +255,9 @@ var Autodocs = React.createClass({
|
||||
<div className="inner-content">
|
||||
<a id="content" />
|
||||
<h1>{metadata.title}</h1>
|
||||
{content.type === 'component' ?
|
||||
<ComponentDoc content={content} /> :
|
||||
<APIDoc content={content} />}
|
||||
{content}
|
||||
<Marked>
|
||||
{content.fullDescription}
|
||||
{docs.fullDescription}
|
||||
</Marked>
|
||||
<div className="docs-prevnext">
|
||||
{metadata.previous && <a className="docs-prev" href={metadata.previous + '.html#content'}>← Prev</a>}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"mkdirp": "*",
|
||||
"optimist": "0.6.0",
|
||||
"react": "~0.12.0",
|
||||
"react-docgen": "^1.0.0",
|
||||
"react-docgen": "^1.1.0",
|
||||
"react-page-middleware": "git://github.com/facebook/react-page-middleware.git",
|
||||
"request": "*"
|
||||
}
|
||||
|
67
website/server/docgenHelpers.js
Normal file
67
website/server/docgenHelpers.js
Normal file
@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
var b = require('react-docgen/node_modules/recast').types.builders;
|
||||
var docgen = require('react-docgen');
|
||||
|
||||
function stylePropTypeHandler(documentation, path) {
|
||||
var propTypesPath = docgen.utils.getPropertyValuePath(path, 'propTypes');
|
||||
if (!propTypesPath) {
|
||||
return;
|
||||
}
|
||||
propTypesPath = docgen.utils.resolveToValue(propTypesPath);
|
||||
if (!propTypesPath || propTypesPath.node.type !== 'ObjectExpression') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the there is a style prop
|
||||
propTypesPath.get('properties').each(function(propertyPath) {
|
||||
if (propertyPath.node.type !== 'Property' ||
|
||||
docgen.utils.getPropertyName(propertyPath) !== 'style') {
|
||||
return;
|
||||
}
|
||||
var valuePath = docgen.utils.resolveToValue(propertyPath.get('value'));
|
||||
// If it's a call to StyleSheetPropType, do stuff
|
||||
if (valuePath.node.type !== 'CallExpression' ||
|
||||
valuePath.node.callee.name !== 'StyleSheetPropType') {
|
||||
return;
|
||||
}
|
||||
// Get type of style sheet
|
||||
var styleSheetModule = docgen.utils.resolveToModule(
|
||||
valuePath.get('arguments', 0)
|
||||
);
|
||||
if (styleSheetModule) {
|
||||
var propDescriptor = documentation.getPropDescriptor('style');
|
||||
propDescriptor.type = {name: 'stylesheet', value: styleSheetModule};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function findExportedOrFirst(node, recast) {
|
||||
return docgen.resolver.findExportedReactCreateClassCall(node, recast) ||
|
||||
docgen.resolver.findAllReactCreateClassCalls(node, recast)[0];
|
||||
}
|
||||
|
||||
function findExportedObject(ast, recast) {
|
||||
var objPath;
|
||||
recast.visit(ast, {
|
||||
visitAssignmentExpression: function(path) {
|
||||
if (!objPath && docgen.utils.isExportsOrModuleAssignment(path)) {
|
||||
objPath = docgen.utils.resolveToValue(path.get('right'));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (objPath) {
|
||||
var b = recast.types.builders;
|
||||
// This is a bit hacky, but easier than replicating the default propType
|
||||
// handler. All this does is convert `{...}` to `{propTypes: {...}}`.
|
||||
objPath.replace(b.objectExpression([
|
||||
b.property('init', b.literal('propTypes'), objPath.node)
|
||||
]));
|
||||
}
|
||||
return objPath;
|
||||
}
|
||||
|
||||
exports.stylePropTypeHandler = stylePropTypeHandler;
|
||||
exports.findExportedOrFirst = findExportedOrFirst;
|
||||
exports.findExportedObject = findExportedObject;
|
@ -7,7 +7,8 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var docs = require('react-docgen');
|
||||
var docgen = require('react-docgen');
|
||||
var docgenHelpers = require('./docgenHelpers');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var slugify = require('../core/slugify');
|
||||
@ -21,7 +22,7 @@ function getNameFromPath(filepath) {
|
||||
return filepath;
|
||||
}
|
||||
|
||||
function componentsToMarkdown(type, json, filepath, i) {
|
||||
function componentsToMarkdown(type, json, filepath, i, styles) {
|
||||
var componentName = getNameFromPath(filepath);
|
||||
|
||||
var docFilePath = '../docs/' + componentName + '.md';
|
||||
@ -29,6 +30,9 @@ function componentsToMarkdown(type, json, filepath, i) {
|
||||
json.fullDescription = fs.readFileSync(docFilePath).toString();
|
||||
}
|
||||
json.type = type;
|
||||
if (styles) {
|
||||
json.styles = styles;
|
||||
}
|
||||
|
||||
var res = [
|
||||
'---',
|
||||
@ -84,20 +88,34 @@ var apis = [
|
||||
'../Libraries/Vibration/VibrationIOS.ios.js',
|
||||
];
|
||||
|
||||
var all = components.concat(apis);
|
||||
var styles = [
|
||||
'../Libraries/StyleSheet/LayoutPropTypes.js',
|
||||
'../Libraries/Components/View/ViewStylePropTypes.js',
|
||||
'../Libraries/Text/TextStylePropTypes.js',
|
||||
'../Libraries/Image/ImageStylePropTypes.js',
|
||||
];
|
||||
|
||||
var all = components.concat(apis).concat(styles.slice(0, 1));
|
||||
var styleDocs = styles.slice(1).reduce(function(docs, filepath) {
|
||||
docs[path.basename(filepath).replace(path.extname(filepath), '')] =
|
||||
docgen.parse(
|
||||
fs.readFileSync(filepath),
|
||||
docgenHelpers.findExportedObject,
|
||||
[docgen.handlers.propTypeHandler]
|
||||
);
|
||||
return docs;
|
||||
}, {});
|
||||
|
||||
module.exports = function() {
|
||||
var i = 0;
|
||||
return [].concat(
|
||||
components.map(function(filepath) {
|
||||
var json = docs.parse(
|
||||
var json = docgen.parse(
|
||||
fs.readFileSync(filepath),
|
||||
function(node, recast) {
|
||||
return docs.resolver.findExportedReactCreateClassCall(node, recast) ||
|
||||
docs.resolver.findAllReactCreateClassCalls(node, recast)[0];
|
||||
}
|
||||
docgenHelpers.findExportedOrFirst,
|
||||
docgen.defaultHandlers.concat(docgenHelpers.stylePropTypeHandler)
|
||||
);
|
||||
return componentsToMarkdown('component', json, filepath, i++);
|
||||
return componentsToMarkdown('component', json, filepath, i++, styleDocs);
|
||||
}),
|
||||
apis.map(function(filepath) {
|
||||
try {
|
||||
@ -107,6 +125,14 @@ module.exports = function() {
|
||||
var json = {};
|
||||
}
|
||||
return componentsToMarkdown('api', json, filepath, i++);
|
||||
}),
|
||||
styles.slice(0, 1).map(function(filepath) {
|
||||
var json = docgen.parse(
|
||||
fs.readFileSync(filepath),
|
||||
docgenHelpers.findExportedObject,
|
||||
[docgen.handlers.propTypeHandler]
|
||||
);
|
||||
return componentsToMarkdown('style', json, filepath, i++);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
@ -901,7 +901,13 @@ div[data-twttr-id] iframe {
|
||||
background-color: hsl(198, 100%, 96%);
|
||||
}
|
||||
|
||||
.prop:nth-child(2n) {
|
||||
.compactProps {
|
||||
border-left: 2px solid hsl(198, 100%, 94%);
|
||||
margin-left: 20px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.props > .prop:nth-child(2n) {
|
||||
background-color: hsl(198, 100%, 94%);
|
||||
}
|
||||
|
||||
@ -910,15 +916,30 @@ div[data-twttr-id] iframe {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.compactProps .propTitle {
|
||||
font-size: 14px;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.prop {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.compactProps .prop {
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
.propType {
|
||||
font-weight: normal;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.compactProps .propType {
|
||||
font-weight: normal;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
#content {
|
||||
display: none;
|
||||
|
Loading…
x
Reference in New Issue
Block a user