This commit is contained in:
Tom MacWright
2016-03-07 11:20:04 -05:00
parent e90ffea98b
commit 3679b99300
12 changed files with 136 additions and 85 deletions

View File

@ -5,11 +5,12 @@ import RoundedToggle from './rounded_toggle';
import PureRenderMixin from 'react-pure-render/mixin';
import GithubSlugger from 'github-slugger';
import debounce from 'lodash.debounce';
import { brandNames, brandClasses } from '../../custom';
let slugger = new GithubSlugger();
let slug = title => { slugger.reset(); return slugger.slug(title); };
let languageOptions = ['curl', 'cli', 'python', 'javascript'];
let languageOptions = ['cURL', 'CLI', 'Python', 'JavaScript'];
let debouncedReplaceState = debounce(hash => {
window.history.replaceState('', '', hash);
@ -45,7 +46,7 @@ var App = React.createClass({
return {
mqls: mqls,
queries: {},
language: 'curl',
language: 'cURL',
activeSection: active,
showNav: false
};
@ -57,7 +58,7 @@ var App = React.createClass({
queries: {
desktop: true
},
language: 'curl',
language: 'cURL',
activeSection: '',
showNav: false
};
@ -126,11 +127,11 @@ var App = React.createClass({
{/* Content background */ }
{!queries.mobile && <div className={`fixed-top fixed-right ${queries.desktop && 'space-left16'}`}>
<div className='fill-dark col6 pin-right'></div>
<div className='fill-light col6 pin-right'></div>
</div>}
{/* Desktop nav */ }
{queries.desktop && <div className='space-top5 scroll-styled pad1 width16 sidebar fixed-left fill-light'>
{queries.desktop && <div className='space-top5 scroll-styled pad1 width16 sidebar fixed-left fill-dark dark'>
<Navigation
handleClick={this.handleClick}
activeSection={activeSection}
@ -142,12 +143,15 @@ var App = React.createClass({
<Content
ast={ast}
queries={queries}
language={this.state.language}/>
language={this.state.language.toLowerCase()}/>
</div>
{/* Language toggle */ }
<div className={`fixed-top dark ${queries.desktop && 'space-left16'}`}>
<div className={`events fill-dark2 pad1 col6 pin-topright ${queries.mobile && 'space-top5 fixed-topright'}`}>
<div className={`fixed-top ${queries.desktop && 'space-left16'}`}>
<div className={`events fill-light bottom-shadow pad1 col6 pin-topright ${queries.tablet && 'dark fill-blue'} ${queries.mobile && 'space-top5 fixed-topright'}`}>
<div className='space-right1 small quiet inline'>
Show examples in:
</div>
<RoundedToggle
options={languageOptions}
onChange={this.onChangeLanguage}
@ -156,20 +160,20 @@ var App = React.createClass({
</div>
{/* Header */ }
<div className={`fill-gray fixed-top ${queries.tablet ? 'pad1y pad2x col6' : 'pad0 width16'}`}>
<a href='/' className='active space-top1 space-left1 pin-topleft icon round fill-blue dark pad0 mapbox'></a>
<div className={`fill-dark dark bottom-shadow fixed-top ${queries.tablet ? 'pad1y pad2x col6' : 'pad0 width16'}`}>
<a href='/' className={`active space-top1 space-left1 pin-topleft icon round dark pad0 ${brandClasses}`}></a>
<div className={`strong small pad0 ${queries.mobile && 'space-left3'} ${queries.tablet ? 'space-left2' : 'space-left4 line-height15' }`}>
{queries.desktop ? 'API Documentation' :
queries.mobile ? 'API Docs' : 'API Docs'}
{queries.desktop ? brandNames.desktop :
queries.mobile ? brandNames.mobile : brandNames.tablet}
</div>
{queries.tablet && <div>
<button
onClick={this.toggleNav}
className={`short quiet pin-topright micro button rcon ${showNav ? 'caret-up' : 'caret-down'} space-right1 space-top1`}>
{activeSection}
className={`short quiet pin-topright button rcon ${showNav ? 'caret-up' : 'caret-down'} space-right1 space-top1`}>
<span className='micro'>{activeSection}</span>
</button>
{showNav && <div
className='fixed-left fill-light pin-left col6 pad2 scroll-styled space-top5'>
className='fixed-left keyline-top fill-dark pin-left col6 pad2 scroll-styled space-top5'>
<Navigation
handleClick={this.handleClick}
activeSection={activeSection}

View File

@ -2,45 +2,10 @@ import React from 'react';
import Section from './section';
import PureRenderMixin from 'react-pure-render/mixin';
import GithubSlugger from 'github-slugger';
import { transformURL } from '../../custom';
let slugger = new GithubSlugger();
let slug = title => { slugger.reset(); return slugger.slug(title); };
function highlightTokens(str) {
return str.replace(/{[\w_]+}/g,
(str) => '<span class="strong">' + str + '</span>')
.replace(
/{@2x}/g,
`<a title='Retina support: adding @2x to this URL will produce 2x scale images' href='#retina'>{@2x}</a>`);
}
function transformURL(node) {
let { value } = node;
let parts = value.split(/\s+/);
if (parts.length === 3) {
return {
type: 'html',
value: `<div class='endpoint'>
<div class='round-left pad0y pad1x fill-lighten0 code micro endpoint-method'>${parts[0]}</div>
<div class='fill-darken1 pad0 code micro endpoint-url'>${highlightTokens(parts[1])}</div>
<div class='endpoint-token contain fill-lighten0 pad0x round-topright'>
<span class='pad0 micro code'>${parts[2]}</span>
<a href='#access-tokens' class='center endpoint-scope space-top3 micro pad1x pin-top fill-lighten1 round-bottom'>
Token scope
</a>
</div>
</div>`
};
} else {
return {
type: 'html',
value: `<div class='endpoint'>
<div class='round-left pad0y pad1x fill-lighten0 code small endpoint-method'>${parts[0]}</div>
<div class='fill-darken1 pad0 code small endpoint-url'>${highlightTokens(parts[1])}</div>
</div>`
};
}
}
function chunkifyAST(ast, language) {
var preview = false;
return ast.children.reduce((chunks, node) => {
@ -72,7 +37,9 @@ function chunkifyAST(ast, language) {
right.push(node);
}
} else if (node.lang === 'endpoint') {
right.push(transformURL(node));
right.push(transformURL(node.value));
} else if (node.lang === null) {
left.push(node);
}
} else if (node.type === 'heading' && node.depth >= 4) {
right.push(node);

View File

@ -1,6 +1,7 @@
import React from 'react';
import PureRenderMixin from 'react-pure-render/mixin';
import NavigationItem from './navigation_item';
import { backLink } from '../../custom';
function getAllInSectionFromChild(headings, idx) {
for (var i = idx; i > 0; i--) {
@ -65,7 +66,7 @@ var Navigation = React.createClass({
if (child.depth === 1) {
return (<div key={i}
onClick={this.handleClick}
className='small pad0x strong space-top1'>{sectionName}</div>);
className='small pad0x quiet space-top1'>{sectionName}</div>);
} else if (child.depth === 2) {
return (<NavigationItem
key={i}
@ -87,6 +88,7 @@ var Navigation = React.createClass({
}
}
})}
<a href='/' className='space-top2 pad1y dark keyline-top block small quiet'>{backLink}</a>
</div>);
}
});

View File

@ -17,7 +17,7 @@ var NavigationItem = React.createClass({
return (<a
href={href}
onClick={this.onClick}
className={`line-height15 pad0x pad00y block ${active ? 'fill-darken0 quiet active round' : ''}`}>
className={`line-height15 pad0x pad00y quiet block ${active ? 'fill-lighten0 round' : ''}`}>
{sectionName}
</a>);
}

View File

@ -3,18 +3,16 @@ import remark from 'remark';
import remarkHTML from 'remark-html';
import remarkHighlight from 'remark-highlight.js';
import PureRenderMixin from 'react-pure-render/mixin';
import { postHighlight } from '../../custom';
function renderHighlighted(nodes) {
return {
__html: remark()
.use(remarkHTML)
.stringify(remark().use(remarkHighlight).run({
type: 'root',
children: nodes
}))
.replace(
/<span class="hljs-string">"{timestamp}"<\/span>/g,
`<span class="hljs-string">"</span><a class='hljs-linked' href='#dates'>{timestamp}</a><span class="hljs-string">"</span>`)
__html: postHighlight(remark()
.use(remarkHTML)
.stringify(remark().use(remarkHighlight).run({
type: 'root',
children: nodes
})))
};
}
@ -28,12 +26,12 @@ var Section = React.createClass({
let { left, right, preview } = chunk;
return (<div
data-title={chunk.title}
className={`section pad2y contain clearfix ${preview ? 'preview' : ''}`}>
className={`keyline-top section contain clearfix ${preview ? 'preview' : ''}`}>
<div
className='col6 pad2x prose clip'
className='space-bottom8 col6 pad2x prose clip'
dangerouslySetInnerHTML={renderHighlighted(left)} />
{right.length > 0 && <div
className='col6 pad2 prose dark space-top5 clip keyline-top fill-dark'
className='space-bottom4 col6 pad2 prose clip fill-light space-top5'
dangerouslySetInnerHTML={renderHighlighted(right)} />}
</div>);
}

View File

@ -1,7 +0,0 @@
var fs = require('fs');
module.exports =
'# Introduction\n' +
fs.readFileSync('./content/introduction.md', 'utf8') + '\n' +
'# Example\n' +
fs.readFileSync('./content/example.md', 'utf8') + '\n';

View File

@ -4,9 +4,11 @@ import ReactDOM from 'react-dom';
import App from './components/app';
import remark from 'remark';
import slug from 'remark-slug';
import content from './content';
import content from '../custom/content';
var ast = remark().use(slug).run(remark().parse(content));
var ast = remark()
.use(slug)
.run(remark().parse(content));
ReactDOM.render(
<App ast={ast} content={content} />,

View File

@ -3,10 +3,12 @@ import ReactDOMServer from 'react-dom/server';
import App from './components/app';
import remark from 'remark';
import slug from 'remark-slug';
import content from './content';
import content from '../custom/content';
import fs from 'fs';
var ast = remark().use(slug).run(remark().parse(content));
var ast = remark()
.use(slug)
.run(remark().parse(content));
var template = fs.readFileSync('./index.html', 'utf8');