Skip to content

Commit

Permalink
[docs] redesign to use dr-ui components (#7530)
Browse files Browse the repository at this point in the history
* initial layout

* clean up style spec layout

* clean up examples page

* fix links in style spec toc

* split style spec

* add examples landing page

* update plugins page layout

* format roadmap page

* fix icon positioning

* delete generated bench files

* address @mollymerp's feedback

* update dr ui version

* clean up console errors

* refactor page shell

* use docs-page-shell; update dr-ui and assembly; remove ProductDropdown

* fix spacing; add borderRadius

* various spacing, sizing

* remove additional space between h2  h3 siblings

* runs eslint --fix on component files

* remove unused lines; linting fixes

* navigation style updates: make link `link--gray` indent nested items

* add spacing to code blocks

* remove `color-gray` from non link elements

* api item + member styling

* remove base classes from /plugins; fix heading spacing

* use mr-ui copy-button in copyable.js

* run eslint --fix on docs/pages, docs/util

* linter fixes

* heading spacing for mobile

* rework copyable to use codesnippet

* add hover class to simple-map card

* make examples header consistent with other headers

* turn off h2 borders for the api section as they clash with the instance members toggle sections; max height and pretty scroll for code examples

* remove unused css

* adds hover state

* replace color-gray-light with color-gray; it's too light on white backgrounds

* remove padding conditional

* rm unused file

* break style-spec into components

* make tocnote link--gray

* adds back top padding to ApiItemMember

* set borderRadius on table rows

* readjust border on ApiItemMember

* adds txt-break-word to overflowing code blocks

* adds style spec to header

* light header adjustments

* style error note

* Merge branch 'publisher-production' into docs-redesign

* publisher-production: (115 commits)
  fix inter-documentation link (#7791)
  [docs] use docs subdomain in examples (#7789)
  Bump Publisher
  First shot at new-domain staging
  [docs] Update page shell (#7760)
  updates API docs links to new url structure (#7757)
  add mapbox-gl-utils to plugins (#7752)
  [docs] Use docs-page-shell (#7742)
  Fixes bugs in documentation (#7741)
  Add worldviews example (#7720)
  Update compatibility matrix for `fill-extrusion-vertical-gradient` for ios & macos. (#7712)
  updates mapbox-gl-directions version in example (#7719)
  v0.52.0
  cherry-pick color state fix to release branch (#7715)
  Update location of drone video used in examples.
  v0.52.0-beta.2
  Cache hillshade textures based on texture size, not tile size. (#7695)
  avoid incomplete webp support in Edge 18 (#7687) (#7692)
  only align raster sources to pixel grid when map is idle to prevent shaking (#7426) (#7694)
  Flattens nested single element all expressions when converting to expressions (#7679)
  ...

* update batfish, react, and react-dom

* rm unused module

* update mr-ui and github-slugger

* adds version var to OverviewHeader

* mb-pages -> publisher-production

* fix bool on iframe

* clean up page shell to fix build errors

* update/add pathname; add descriptions

* make toggles buttons for acessbility; increase hit box; make icon larger; do not change location on click

* use push state to change hash on click, but not to move page

* update dr-ui

* adds interactiveClass and sideBarColSize

* smaller sidebar on spec

* adds addtional padding to h3s on api page to clear the sticker

* make hit box larger for nav items on sidebard

* adjust topbarstick columns when `sidebarColSize` is set

* adds make-table-scroll plugin; make non markdown table scroll

* remove extra docs-content ids

* make table scroll; wrap code

* reorder tabs

* adds back to top button long pages

* update dr-ui

* sets unStickWidth on TopbarSticker

* Update batfish.config.js

* Update yarn.lock

* adds unit tests for examples

* fix tests

* add missing images

* adds test to make sure every example as a thumbnail image

* compress images

* resize thumbnail images to 1200 x 500

* compress again

* add a little wiggle room for image size

* updates documentation for tags and adds information about example thumbnail images
  • Loading branch information
colleenmcginnis authored and katydecorah committed Jan 25, 2019
1 parent 80c4725 commit 8bdd869
Show file tree
Hide file tree
Showing 168 changed files with 4,083 additions and 4,396 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- Thanks for the PR! Feel free to add or remove items from the checklist. -->

<!-- If your PR affects documentation relevant to the currently released version, please use `mb-pages` as the base branch. See https://github.com/mapbox/mapbox-gl-js/blob/master/docs/README.md#committing-and-publishing-documentation -->
<!-- If your PR affects documentation relevant to the currently released version, please use `publisher-production` as the base branch. See https://github.com/mapbox/mapbox-gl-js/blob/master/docs/README.md#committing-and-publishing-documentation -->

- [ ] briefly describe the changes in this PR
- [ ] write tests for all new functionality
Expand Down
34 changes: 32 additions & 2 deletions batfish.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { webpack } = require('@mapbox/batfish');
const webpack = require('webpack');
const mapboxAssembly = require('@mapbox/mbx-assembly');
const path = require('path');

module.exports = () => {
Expand All @@ -7,7 +8,11 @@ module.exports = () => {
siteOrigin: 'https://docs.mapbox.com',
pagesDirectory: `${__dirname}/docs/pages`,
outputDirectory: path.join(__dirname, '_site'),
browserslist: mapboxAssembly.browsersList,
postcssPlugins: mapboxAssembly.postcssPipeline.plugins,
stylesheets: [
require.resolve('@mapbox/mbx-assembly/dist/assembly.css'),
require.resolve('@mapbox/dr-ui/css/docs-prose.css'),
`${__dirname}/docs/components/site.css`,
`${__dirname}/docs/components/prism_highlight.css`,
`${__dirname}/vendor/docs-page-shell/page-shell-styles.css`
Expand All @@ -33,11 +38,36 @@ module.exports = () => {
filename: `${__dirname}/vendor/docs-page-shell/page-shell-script.js`
}
],
jsxtremeMarkdownOptions: {
wrapper: path.join(__dirname, './docs/components/markdown-page-shell.js'),
rehypePlugins: [
require('@mapbox/dr-ui/plugins/add-links-to-headings'),
require('@mapbox/dr-ui/plugins/make-table-scroll')
]
},
dataSelectors: {
examples: ({pages}) => {
return pages
.filter(({path, frontMatter}) => /\/example\//.test(path) && frontMatter.tags)
.map(({frontMatter}) => frontMatter);
.map(example => {
return {
path: example.path,
title: example.frontMatter.title,
description: example.frontMatter.description,
tags: example.frontMatter.tags,
pathname: example.frontMatter.pathname
};
});
},
listSubfolders: data => {
const folders = data.pages
.filter(file => {
return file.path.split('/').length === 4;
})
.map(folder => {
return folder;
});
return folders;
}
},
devBrowserslist: false
Expand Down
2 changes: 1 addition & 1 deletion build/check-bundle-size.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function getMergeBase() {
// base branch.
const head = process.env['CIRCLE_SHA1'];
for (const sha of execSync(`git rev-list --max-count=10 ${head}`).toString().trim().split('\n')) {
const base = execSync(`git branch -r --contains ${sha} origin/master origin/release-* origin/mb-pages`).toString().split('\n')[0].trim().replace(/^origin\//, '');
const base = execSync(`git branch -r --contains ${sha} origin/master origin/release-* origin/publisher-production`).toString().split('\n')[0].trim().replace(/^origin\//, '');
if (base) {
return Promise.resolve(execSync(`git merge-base origin/${base} ${head}`).toString().trim());
}
Expand Down
15 changes: 10 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ code for the example, and a `.js` file containing example boilerplate and front

* `title`: A short title for the example in **sentence case** as a **verb phrase**
* `description`: A one sentence description of the example
* `tags`: An array of tags for the example, which determine the sections it is listed in in the sidebar navigation
* `tags`: An array of tags for the example, which determine the sections it is listed in in the sidebar navigation, see `docs/data/tags.js` for a list of tags
* `pathname`: The relative path of the example, including leading `/mapbox-gl-js/example/` path

In the `.html` file, write the HTML and JavaScript constituting the example.
Expand All @@ -33,6 +33,11 @@ In the `.html` file, write the HTML and JavaScript constituting the example.
* Do **not** use custom styles from your personal account. Use only the default `mapbox` account styles.
* When embedding literal JSON (GeoJSON or Mapbox style snippets) into script code, double-quote property names and string values. Elsewhere, use single-quoted strings.

Every example must have an accompanying thumbnail image:

* Save a thumbnail image (1200 x 500 pixel .png, under 500 KB) in `docs/pages/img/`.
* The file name of the image must match the example's file name.

## Running the Documentation Server Locally

To start a documentation server locally run
Expand All @@ -44,13 +49,13 @@ The command will print the URL you can use to view the documentation.

## Committing and Publishing Documentation

The mapbox-gl-js repository has both `master` and `mb-pages` as active branches. The **`master` branch** is used for mainline code development: the next version of mapbox-gl-js will come from the code in this branch, and it may contain documentation and examples for APIs that are not yet part of a public release. The **`mb-pages` branch** is published to https://www.mapbox.com/mapbox-gl-js/ on any push to the branch. For the purposes of documentation changes, use these two branches as follows:
The mapbox-gl-js repository has both `master` and `publisher-production` as active branches. The **`master` branch** is used for mainline code development: the next version of mapbox-gl-js will come from the code in this branch, and it may contain documentation and examples for APIs that are not yet part of a public release. The **`publisher-production` branch** is published to https://www.mapbox.com/mapbox-gl-js/ on any push to the branch. For the purposes of documentation changes, use these two branches as follows:

* If your changes are relevant to the **currently released version**, make them on `mb-pages`. Examples: correcting the API documentation for a released API, adding a new example that depends only on current APIs.
* If your changes are relevant to the **currently released version**, make them on `publisher-production`. Examples: correcting the API documentation for a released API, adding a new example that depends only on current APIs.
* If your changes depend on gl-js features **not in the currently released version**, make them on `master`. Examples: documenting or adding an example for a newly-added API.

When releasing, the release manager will:

* Merge `mb-pages` to `master`, ensuring that any accumulated changes in `mb-pages` propagate to `master`
* Merge `publisher-production` to `master`, ensuring that any accumulated changes in `publisher-production` propagate to `master`
* Make the release
* Fast-forward `mb-pages` to the current `master`, ensuring that all accumulated changes are published to mapbox.com
* Fast-forward `publisher-production` to the current `master`, ensuring that all accumulated changes are published to mapbox.com
76 changes: 76 additions & 0 deletions docs/components/api-item-member.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from 'react';
import GithubSlugger from 'github-slugger';
import createFormatters from 'documentation/lib/output/util/formatters';
import LinkerStack from 'documentation/lib/output/util/linker_stack';
import docs from '../components/api.json'; // eslint-disable-line import/no-unresolved
import ApiItem from '../components/api-item';
import Icon from '@mapbox/mr-ui/icon';

const linkerStack = new LinkerStack({})
.namespaceResolver(docs, (namespace) => {
const slugger = new GithubSlugger();
return `#${slugger.slug(namespace)}`;
});

const formatters = createFormatters(linkerStack.link);

class ApiItemMember extends React.Component {
constructor(props) {
super(props);
this.state = {disclosed: false};
this.hashChange = this.hashChange.bind(this);
}

href = m => `#${m.namespace.toLowerCase()}`

render() {
const member = this.props;
return (
<div className='border-b border--gray-light'>
<div className='pt60' style={{ marginTop: '-60px' }} id={member.namespace.toLowerCase()} />
<div>
<button
className='cursor-pointer toggle-sibling color-blue-on-hover w-full py18'
onClick={(e) => {
this.setState({disclosed: !this.state.disclosed});
if (history.pushState) {
history.pushState(null, null, this.href(member));
} else {
location.hash = this.href(member);
}

e.preventDefault();
}}
>
<span className='txt-code truncate bg-white'>{member.name}</span>
{member.kind === 'function' &&
<span className='color-gray txt-code mr12' dangerouslySetInnerHTML={{__html: formatters.parameters(member, true)}}/>}
<Icon size={30} name={`${this.state.disclosed ? 'caret-down' : 'caret-right'}`} themeIcon="fr" inline={true} />
</button>
</div>

{this.state.disclosed &&
<div className="toggle-target bg-gray-faint round py18 px18 mb12">
<ApiItem nested={true} {...member}/>
</div>}
</div>
);
}

hashChange() {
if (window.location.hash === this.href(this.props)) {
this.setState({disclosed: true });
}
}

componentDidMount() {
window.addEventListener("hashchange", this.hashChange);
this.hashChange();
}

componentWillUnmount() {
window.removeEventListener("hashchange", this.hashChange);
}
}

export default ApiItemMember;
169 changes: 169 additions & 0 deletions docs/components/api-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import React from 'react';
import createFormatters from 'documentation/lib/output/util/formatters';
import LinkerStack from 'documentation/lib/output/util/linker_stack';
import GithubSlugger from 'github-slugger';
import {highlightJavascript} from '../components/prism_highlight.js';
import docs from '../components/api.json'; // eslint-disable-line import/no-unresolved
import ApiItemMember from './api-item-member';
import IconText from '@mapbox/mr-ui/icon-text';


const linkerStack = new LinkerStack({})
.namespaceResolver(docs, (namespace) => {
const slugger = new GithubSlugger();
return `#${slugger.slug(namespace)}`;
});

const formatters = createFormatters(linkerStack.link);

class ApiItem extends React.Component {

md = (ast, inline) => {
if (inline && ast && ast.children.length && ast.children[0].type === 'paragraph') {
ast = {
type: 'root',
children: ast.children[0].children.concat(ast.children.slice(1))
};
}
return <span dangerouslySetInnerHTML={{__html: formatters.markdown(ast)}}/>;
}
formatType = type => <span dangerouslySetInnerHTML={{__html: formatters.type(type)}}/>

render() {
const section = this.props;

const empty = members => !members || members.length === 0;

const membersList = (members, title) => !empty(members) &&
<div>
<div className='py6 mt12 txt-m txt-bold'>{title}</div>
<div className='mb18'>
{members.map((member, i) => <ApiItemMember key={i} {...member}/>)}
</div>
</div>;

return (
<section className='prose mb24'>
{!this.props.nested &&
<div className='mb24'>
<h3 className='mb12' id={section.namespace.toLowerCase()}><a className="unprose color-blue-on-hover" href={`#${section.namespace.toLowerCase()}`}>{section.name}</a></h3>
{section.context && section.context.github &&
<a className='pt6 link--gray txt-s unprose' href={section.context.github.url}><IconText iconBefore="github" >{section.context.github.path}</IconText></a>}
</div>}

{this.md(section.description)}

{!empty(section.augments) &&
<p>Extends {section.augments.map((tag, i) => <span key={i} dangerouslySetInnerHTML={{__html: formatters.autolink(tag.name)}}/>)}.</p>}

{section.kind === 'class' &&
!section.interface &&
(!section.constructorComment || section.constructorComment.access !== 'private') &&
<div className='txt-code px6 py6 txt-s round bg-gray-faint my18'
dangerouslySetInnerHTML={{__html: `new ${section.name}${formatters.parameters(section)}`}}/>}

{section.version && <div>Version: {section.version}</div>}
{section.license && <div>License: {section.license}</div>}
{section.author && <div>Author: {section.author}</div>}
{section.copyright && <div>Copyright: {section.copyright}</div>}
{section.since && <div>Since: {section.since}</div>}

{!empty(section.params) && (section.kind !== 'class' || !section.constructorComment || section.constructorComment.access !== 'private') &&
<div>
<div className='py6 mt12 txt-m txt-bold'>Parameters</div>
<div>
{section.params.map((param, i) => <div key={i} className='mb6'>
<div>
<span className='txt-code bg-transparent ml-neg3 txt-bold'>{param.name}</span>
<code className='color-gray'>({this.formatType(param.type)})</code>
{param.default && <span>{'('}default <code>{param.default}</code>{')'}</span>}
{this.md(param.description, true)}
</div>
{param.properties &&
<div className='mt6 mb12 scroll-auto'>
<table className='fixed-table'>
<colgroup>
<col width='30%' />
<col width='70%' />
</colgroup>
<thead>
<tr className='txt-bold bg-gray-faint'>
<td style={{borderTopLeftRadius: '4px'}}>Name</td>
<td style={{borderTopRightRadius: '4px'}}>Description</td>
</tr>
</thead>
<tbody className='mt6'>
{param.properties.map((property, i) => <tr key={i}>
<td>
<span className='txt-code txt-bold txt-break-word bg-white ml-neg3'>{property.name}</span><br />
<code className='color-gray txt-break-word'>{this.formatType(property.type)}</code><br />
{property.default && <span className='color-gray txt-break-word'>default <code>{property.default}</code></span>}
</td>
<td><span>{this.md(property.description, true)}</span></td>
</tr>)}
</tbody>
</table>
</div>}
</div>)}
</div>
</div>}

{!empty(section.properties) &&
<div>
<div className='py6 mt12 txt-m txt-bold'>Properties</div>
<div>
{section.properties.map((property, i) => <div key={i} className='mb6'>
<span className='txt-code txt-bold bg-white mr3 ml-neg3'>{property.name}</span>
<code className='color-gray'>({this.formatType(property.type)})</code>
{property.default && <span>{'('}default <code>{property.default}</code>{')'}</span>}
{property.description && <span>: {this.md(property.description, true)}</span>}
{property.properties &&
<ul>
{property.properties.map((property, i) => <li key={i}>
<code>{property.name}</code> {this.formatType(property.type)}
{property.default && <span>{'('}default <code>{property.default}</code>{')'}</span>}
{this.md(property.description)}
</li>)}
</ul>}
</div>)}
</div>
</div>}

{section.returns && section.returns.map((ret, i) => <div key={i}>
<div className='py6 mt12 txt-m txt-bold'>Returns</div>
<code>{this.formatType(ret.type)}</code>
{ret.description && <span>: {this.md(ret.description, true)}</span>}
</div>)}

{!empty(section.throws) &&
<div>
<div className='py6 mt12 txt-m txt-bold'>Throws</div>
<ul>
{section.throws.map((throws, i) => <li key={i}>{this.formatType(throws.type)}: {this.md(throws.description, true)}</li>)}
</ul>
</div>}

{!empty(section.examples) &&
<div>
<div className='py6 mt12 txt-m txt-bold'>Example</div>
{section.examples.map((example, i) => <div key={i}>
{example.caption && <p>{this.md(example.caption)}</p>}
{highlightJavascript(example.description)}
</div>)}
</div>}

{membersList(section.members.static, 'Static Members')}
{membersList(section.members.instance, 'Instance Members')}
{membersList(section.members.events, 'Events')}

{!empty(section.sees) &&
<div>
<div className='py6 mt12 txt-m txt-bold'>Related</div>
<ul>{section.sees.map((see, i) => <li key={i}>{this.md(see, true)}</li>)}</ul>
</div>}
</section>
);
}
}

export default ApiItem;
Loading

0 comments on commit 8bdd869

Please sign in to comment.