Skip to content

Commit

Permalink
better docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Nov 28, 2015
1 parent 3c4c91e commit 9a533d6
Show file tree
Hide file tree
Showing 24 changed files with 505 additions and 460 deletions.
194 changes: 194 additions & 0 deletions examples/Api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import React from 'react';
import metadata from 'component-metadata!react-big-calendar/Calendar';
import transform from 'lodash/object/transform';

function displayObj(obj){
return JSON.stringify(obj, null, 2).replace(/"|'/g, '')
}

let capitalize = str => str[0].toUpperCase() + str.substr(1);
let cleanDocletValue = str => str.trim().replace(/^\{/, '').replace(/\}$/, '');

let Api = React.createClass({
render(){
let calData = metadata.Calendar;

return (
<div {...this.props}>
<h1><a href='#api'>API</a></h1>
<p dangerouslySetInnerHTML={{ __html: calData.descHtml }} />

<h2>Props</h2>
{
Object.keys(calData.props).map(propName => {
let data = calData.props[propName];

return this.renderProp(data, propName, 'h3');
})
}
</div>
)
},

renderProp(data, name, Heading){
let typeInfo = this.renderType(data);

return (
<section>
<Heading>
<a href={`#prop-${name}`}>
<code>{name}</code>
</a>
{ data.required &&
<strong>{' required'}</strong>
}
{
this.renderControllableNote(data, name)
}
</Heading>
<p dangerouslySetInnerHTML={{ __html: data.descHtml }}/>
<div style={{ paddingLeft: 20 }}>
<p>
<strong>type: </strong>
{ typeInfo && typeInfo.type === 'pre' ? typeInfo : <code>{typeInfo}</code> }
</p>
{ data.defaultValue &&
<div><strong>default: </strong><code>{data.defaultValue.trim()}</code></div>
}
</div>
</section>
)
},

renderType(prop) {
let type = prop.type || {};
let name = getDisplayTypeName(type.name);
let doclets = prop.doclets || {};

switch (name) {
case 'elementType':
return 'Component';
case 'object':
if (type.value)
return (
<pre className='shape-prop'>
{'object -> \n'}
{ displayObj(renderObject(type.value))}
</pre>
)

return name;
case 'union':
return type.value.reduce((current, val, i, list) => {
val = typeof val === 'string' ? { name: val } : val;
let item = this.renderType({ type: val });
if (React.isValidElement(item)) {
item = React.cloneElement(item, {key: i});
}
current = current.concat(item);

return i === (list.length - 1) ? current : current.concat(' | ');
}, []);
case 'array':
let child = this.renderType({ type: type.value });

return <span>{'array<'}{ child }{'>'}</span>;
case 'enum':
return this.renderEnum(type);
case 'custom':
return cleanDocletValue(doclets.type || name);
default:
return name;
}
},

renderEnum(enumType) {
const enumValues = enumType.value || [];

const renderedEnumValues = [];
enumValues.forEach(function renderEnumValue(enumValue, i) {
if (i > 0) {
renderedEnumValues.push(
<span key={`${i}c`}>, </span>
);
}

renderedEnumValues.push(
<code key={i}>{enumValue}</code>
);
});

return (
<span>one of: {renderedEnumValues}</span>
);
},

renderControllableNote(prop, propName) {
let controllable = prop.doclets.controllable;
let isHandler = prop.type && getDisplayTypeName(prop.type.name) === 'function';

if (!controllable) {
return false;
}

let text = isHandler ? (
<span>
controls <code>{controllable}</code>
</span>
) : (
<span>
controlled by: <code>{controllable}</code>,
initialized with: <code>{'default' + capitalize(propName)}</code>
</span>
);

return (
<div className='pull-right'>
<em><small>{ text }</small></em>
</div>
);
}
})

function getDisplayTypeName(typeName) {
if (typeName === 'func') {
return 'function';
} else if (typeName === 'bool') {
return 'boolean';
}

return typeName;
}

function renderObject(props){
return transform(props, (obj, val, key) => {
obj[key] = simpleType(val)

// if (val.desc && typeof obj[key] === 'string')
// obj[key] = obj[key] + ': ' + val.desc
}, {})
}

function simpleType(prop) {
let type = prop.type || {};
let name = getDisplayTypeName(type.name);
let doclets = prop.doclets || {};

switch (name) {
case 'elementType':
return 'Component';
case 'object':
if (type.value)
return renderObject(type.value)
return name;
case 'array':
let child = simpleType({ type: type.value });

return 'array<' + child + '>';
case 'custom':
return cleanDocletValue(doclets.type || name);
default:
return name;
}
}
export default Api;
104 changes: 58 additions & 46 deletions examples/App.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,82 @@
import React from 'react';
import Modal from 'react-overlays/lib/Modal';

import Api from './Api';
import cn from 'classnames';
import { render } from 'react-dom';

import globalizeLocalizer from 'react-big-calendar/globalize-localizer';
import momentLocalizer from 'react-big-calendar/moment-localizer';

import { set as setLocalizer } from 'react-big-calendar/localizer';

import moment from 'moment';
import localizer from 'react-big-calendar/localizers/globalize';
import globalize from 'globalize';

import BigCalendar from 'react-big-calendar';
localizer(globalize);

import 'react-big-calendar/less/styles.less';
import './styles.less';

import events from './events';

setLocalizer(
globalizeLocalizer(globalize)
);

function EventWeek(props) {
return <strong>{props.event.title}</strong>
}

function EventAgenda(props) {
return <em>{props.event.title}</em>
}


const Example = React.createClass({
getInitialState(){
return { showModal: false };
return {
selected: 'basic'
};
},

render() {
let selected = this.state.selected;
let Current = {
basic: require('./demos/basic'),
selectable: require('./demos/selectable'),
popup: require('./demos/popup'),
rendering: require('./demos/rendering')
}[selected];

return (
<div className='app'>
<main className=''>
<BigCalendar
selectable
popup
events={events}
onSelectEvent={this.open}
defaultDate={new Date(2015, 3, 1)}
eventPropGetter={e => ({ className: 'hi-event'})}
components={{
event: EventWeek,
agenda: {
event: EventAgenda
}
}}
/>
</main>
<div className="jumbotron">
<div className="container">
<h1>Big Calendar <i className='fa fa-calendar'/></h1>
<p>such enterprise, very business.</p>
<p>
<a href="#api">
<i className='fa fa-book'/> API documentation
</a>
{' | '}
<a target='_blank' href="https://github.com/intljusticemission/react-big-calendar">
<i className='fa fa-github'/> github
</a>
</p>
</div>
</div>
<div className='examples contain'>
<aside>
<ul className='nav nav-pills nav-stacked'>
<li className={cn({active: selected === 'basic' })}>
<a href='#' onClick={this.select.bind(null, 'basic')}>Basic</a>
</li>
<li className={cn({active: selected === 'selectable' })}>
<a href='#' onClick={this.select.bind(null, 'selectable')}>Selectable</a>
</li>
<li className={cn({active: selected === 'popup' })}>
<a href='#' onClick={this.select.bind(null, 'popup')}>Popup</a>
</li>
<li className={cn({active: selected === 'rendering' })}>
<a href='#' onClick={this.select.bind(null, 'rendering')}>Custom rendering</a>
</li>
</ul>
</aside>
<div className='example'>
<Current />
</div>
</div>
<div className='docs'>
<Api className='contain' />
</div>
</div>
);
},
close(){
this.setState({ showModal: false });
},

open(){
this.setState({ showModal: true });
select(selected, e){
e.preventDefault();
this.setState({ selected })
}
});

render(<Example/>, document.body);
render(<Example/>, document.getElementById('root'));
Loading

0 comments on commit 9a533d6

Please sign in to comment.