Refactored Installation page to no longer use tabs (#11050)

This commit is contained in:
Brian Vaughn
2017-10-02 15:45:48 -07:00
committed by GitHub
parent 4caa888bf9
commit 75ad1a9cd6
3 changed files with 7 additions and 331 deletions
+7 -102
View File
@@ -11,114 +11,24 @@ redirect_from:
- "docs/environments.html"
next: hello-world.html
---
<style>
.tab-hidden {
display: none;
}
</style>
React is flexible and can be used in a variety of projects. You can create new apps with it, but you can also gradually introduce it into an existing codebase without doing a rewrite.
<div class="toggler">
<style>
.toggler li {
display: inline-block;
position: relative;
top: 1px;
padding: 10px;
margin: 0px 2px 0px 2px;
border-bottom-color: transparent;
border-radius: 3px 3px 0px 0px;
color: #373940;
background-color: transparent;
font-size: 0.99em;
cursor: pointer;
opacity: 0.5;
}
.toggler li:active {
opacity: 1;
}
.toggler li:first-child {
margin-left: 0;
}
.toggler li:last-child {
margin-right: 0;
}
.toggler ul {
display: inline-block;
list-style-type: none;
margin: 0;
border-bottom: 1px solid #ececec;
cursor: default;
margin: 0 -15px;
padding: 0 15px;
}
@media screen and (max-width: 960px) {
.toggler li,
.toggler li:first-child,
.toggler li:last-child {
display: block;
border-radius: 3px;
margin: 2px 0px 2px 0px;
}
}
.display-target-fiddle .toggler .button-fiddle:focus,
.display-target-newapp .toggler .button-newapp:focus,
.display-target-existingapp .toggler .button-existingapp:focus {
opacity: 1;
}
.display-target-fiddle .toggler .button-fiddle,
.display-target-newapp .toggler .button-newapp,
.display-target-existingapp .toggler .button-existingapp {
opacity: 1;
font-weight: 700;
}
section {
display: none;
}
.display-target-fiddle .fiddle,
.display-target-newapp .newapp,
.display-target-existingapp .existingapp {
display: block;
}
</style>
<script>
document.querySelector('.toggler').parentElement.className += ' display-target-fiddle';
</script>
<span>Which of these options best describes what you want to do?</span>
<br />
<br />
<ul role="tablist" >
<li id="fiddle" class="button-fiddle" aria-selected="false" role="tab" tabindex="0" aria-controls="fiddletab"
onclick="display('target', 'fiddle')" onkeyup="keyToggle(event, 'fiddle', 'existingapp', 'newapp')">
Try React
</li>
<li id="newapp" class="button-newapp" aria-selected="false" role="tab" tabindex="-1" aria-controls="newapptab"
onclick="display('target', 'newapp')" onkeyup="keyToggle(event, 'newapp', 'fiddle', 'existingapp')">
Create a New App
</li>
<li id="existingapp" class="button-existingapp" aria-selected="false" role="tab" tabindex="-1" aria-controls="existingapptab"
onclick="display('target', 'existingapp')" onkeyup="keyToggle(event, 'existingapp', 'newapp', 'fiddle')">
Add React to an Existing App
</li>
</ul>
</div>
Here are a couple of ways to get started:
<div>
<section id="fiddletab" role="tabpanel" class="fiddle">
* [Try React](#trying-out-react)
* [Create a New App](#creating-a-new-application)
* [Add React to an Existing App](#adding-react-to-an-existing-application)
### Trying Out React
## Trying Out React
If you're just interested in playing around with React, you can use CodePen. Try starting from [this Hello World example code](http://codepen.io/gaearon/pen/rrpgNB?editors=0010). You don't need to install anything; you can just modify the code and see if it works.
If you prefer to use your own text editor, you can also <a href="https://raw.githubusercontent.com/facebook/react/master/docs/downloads/single-file-example.html" download="hello.html">download this HTML file</a>, edit it, and open it from the local filesystem in your browser. It does a slow runtime code transformation, so don't use it in production.
If you want to use it for a full application, there are two popular ways to get started with React: using Create React App, or adding it to an existing application.
</section>
<section id="newapptab" role="tabpanel" class="newapp">
### Creating a New Application
## Creating a New Application
[Create React App](http://github.com/facebookincubator/create-react-app) is the best way to start building a new React single page application. It sets up your development environment so that you can use the latest JavaScript features, provides a nice developer experience, and optimizes your app for production.
@@ -133,11 +43,8 @@ npm start
Create React App doesn't handle backend logic or databases; it just creates a frontend build pipeline, so you can use it with any backend you want. It uses build tools like Babel and webpack under the hood, but works with zero configuration.
When you're ready to deploy to production, running `npm run build` will create an optimized build of your app in the `build` folder. You can learn more about Create React App [from its README](https://github.com/facebookincubator/create-react-app#create-react-app-) and the [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#table-of-contents).
</section>
<section id="existingapptab" role="tabpanel" class="existingapp">
### Adding React to an Existing Application
## Adding React to an Existing Application
You don't need to rewrite your app to start using React.
@@ -249,5 +156,3 @@ We also recommend to verify that the CDN you are using sets the `Access-Control-
![Access-Control-Allow-Origin: *](../img/docs/cdn-cors-header.png)
This enables a better [error handling experience](/blog/2017/07/26/error-handling-in-react-16.html) in React 16 and later.
</section>
</div>
-9
View File
@@ -33,7 +33,6 @@ exports.createPages = async ({graphql, boundActionCreators}) => {
const docsTemplate = resolve('./src/templates/docs.js');
const tutorialTemplate = resolve('./src/templates/tutorial.js');
const homeTemplate = resolve('./src/templates/home.js');
const installationTemplate = resolve('./src/templates/installation.js');
const allMarkdown = await graphql(
`
@@ -69,14 +68,6 @@ exports.createPages = async ({graphql, boundActionCreators}) => {
slug,
},
});
} else if (slug === 'docs/installation.html') {
createPage({
path: slug,
component: installationTemplate,
context: {
slug,
},
});
} else if (slug === 'docs/error-decoder.html') {
// No-op so far as markdown templates go.
// Error codes are managed by a page (which gets created automatically).
-220
View File
@@ -1,220 +0,0 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
import Container from 'components/Container';
import Flex from 'components/Flex';
import MarkdownHeader from 'components/MarkdownHeader';
import NavigationFooter from 'templates/components/NavigationFooter';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import StickyResponsiveSidebar from 'components/StickyResponsiveSidebar';
import TitleAndMetaTags from 'components/TitleAndMetaTags';
import {createLinkDocs} from 'utils/createLink';
import findSectionForPath from 'utils/findSectionForPath';
import {sectionListDocs} from 'utils/sectionList';
import {sharedStyles} from 'theme';
import createOgUrl from 'utils/createOgUrl';
// HACK: copied from 'installation.md'
// TODO: clean this up.
function setSelected(value) {
var tabs = document.querySelectorAll('li[role="tab"]');
for (var i = 0; i < tabs.length; ++i) {
var tab = tabs[i];
if (tab.className === 'button-' + value) {
tabs[i].setAttribute('aria-selected', 'true');
tabs[i].setAttribute('tabindex', '0');
} else {
tabs[i].setAttribute('aria-selected', 'false');
tabs[i].setAttribute('tabindex', '-1');
}
}
}
function keyToggle(e, value, prevTab, nextTab) {
// left arrow <-
if (e.keyCode === 37) {
document.getElementById(prevTab).focus();
display('target', prevTab);
}
// right arrow ->
if (e.keyCode === 39) {
document.getElementById(nextTab).focus();
display('target', nextTab);
}
}
function display(type, value) {
setSelected(value);
var container = document.getElementsByTagName('section')[0].parentNode
.parentNode;
container.className =
'display-' +
type +
'-' +
value +
' ' +
container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), '');
}
var foundHash = false;
function selectTabForHashLink(location) {
var hashLinks = document.querySelectorAll('a.anchor');
for (var i = 0; i < hashLinks.length && !foundHash; ++i) {
if (location && hashLinks[i].hash === location.hash) {
var parent = hashLinks[i].parentElement;
while (parent) {
if (parent.tagName === 'SECTION') {
var target = null;
if (parent.className.indexOf('fiddle') > -1) {
target = 'fiddle';
} else if (parent.className.indexOf('newapp') > -1) {
target = 'newapp';
} else if (parent.className.indexOf('existingapp') > -1) {
target = 'existingapp';
} else {
break; // assume we don't have anything.
}
display('target', target);
foundHash = true;
break;
}
parent = parent.parentElement;
}
}
}
}
// HACK Expose toggle functions global for markup-defined event handlers.
// Don't acceess the 'window' object without checking first though,
// Because it would break the (Node only) Gatsby build step.
if (typeof window !== 'undefined') {
window.keyToggle = keyToggle;
window.display = display;
}
class InstallationPage extends Component {
componentDidMount() {
const location = this.props.location;
// If we are coming to the page with a hash in it (i.e. from a search, for example), try to get
// us as close as possible to the correct platform and dev os using the hashtag and section walk up.
if (location && location.hash !== '' && location.hash !== 'content') {
// content is default
// Hash links are added a bit later so we wait for them.
// HACK we don't have a window object if/when Gatsby executes this in node
if (
typeof window !== 'undefined' &&
typeof window.addEventListener === 'function'
) {
window.addEventListener(
'DOMContentLoaded',
selectTabForHashLink.bind(null, location),
);
}
}
display('target', 'fiddle');
}
render() {
const {data, location} = this.props;
const {markdownRemark} = data;
return (
<Flex
direction="column"
grow="1"
shrink="0"
halign="stretch"
css={{
width: '100%',
flex: '1 0 auto',
position: 'relative',
zIndex: 0,
}}>
<TitleAndMetaTags
title="Installation - React"
ogUrl={createOgUrl(markdownRemark.fields.slug)}
/>
<div css={{flex: '1 0 auto'}}>
<Container>
<div css={sharedStyles.articleLayout.container}>
<Flex type="article" direction="column" grow="1" halign="stretch">
<MarkdownHeader title={markdownRemark.frontmatter.title} />
<div css={sharedStyles.articleLayout.content}>
<div
css={[sharedStyles.markdown]}
dangerouslySetInnerHTML={{__html: markdownRemark.html}}
/>
{markdownRemark.fields.path &&
<div css={{marginTop: 80}}>
<a
css={sharedStyles.articleLayout.editLink}
href={`https://github.com/facebook/react/tree/master/docs/${markdownRemark.fields.path}`}>
Edit this page
</a>
</div>}
</div>
</Flex>
<div css={sharedStyles.articleLayout.sidebar}>
<StickyResponsiveSidebar
createLink={createLinkDocs}
defaultActiveSection={findSectionForPath(
location.pathname,
sectionListDocs,
)}
location={location}
sectionList={sectionListDocs}
title="Installation"
/>
</div>
</div>
</Container>
</div>
{/* TODO Read prev/next from index map, not this way */}
{(markdownRemark.frontmatter.next || markdownRemark.frontmatter.prev) &&
<NavigationFooter
location={location}
next={markdownRemark.frontmatter.next}
prev={markdownRemark.frontmatter.prev}
/>}
</Flex>
);
}
}
InstallationPage.propTypes = {
data: PropTypes.shape({markdownRemark: PropTypes.object.isRequired})
.isRequired,
location: PropTypes.object.isRequired,
};
// eslint-disable-next-line no-undef
export const pageQuery = graphql`
query InstallationMarkdown($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
next
prev
}
fields {
path
slug
}
}
}
`;
export default InstallationPage;