mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Refactored Installation page to no longer use tabs (#11050)
This commit is contained in:
+7
-102
@@ -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-
|
||||

|
||||
|
||||
This enables a better [error handling experience](/blog/2017/07/26/error-handling-in-react-16.html) in React 16 and later.
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user