import React, { Component } from "react";
import { Link, Switch, Route } from "react-router-dom";
import Animated from "animated/lib/targets/react-dom";
import ChevronLeft from "react-icons/lib/md/chevron-left";
import PropTypes from "prop-types";
import { Block, Col } from "jsxstyle";
import EnvironmentHeader from "./EnvironmentHeader.js";
import { RED } from "../Theme.js";
import Example from "./Example.js";
import API from "./APISmall.js";
import Guide from "./Guide.js";
const paths = {
api: match => `${match.path}/api/:mod`,
example: match => `${match.path}/example/:example`,
guide: match => `${match.path}/guides/:mod/:header?`
};
export default class EnvironmentSmall extends Component {
static propTypes = {
data: PropTypes.object,
match: PropTypes.object,
location: PropTypes.object,
history: PropTypes.object
};
state = {
// 0 = parent is active
// 1 = child is active
anim: new Animated.Value(this.props.match.isExact ? 0 : 1),
animating: false
};
componentDidMount() {
this.preloadExamples();
}
preloadExamples() {
const { data } = this.props;
data.examples.forEach(example => {
// native doesn't have `load`
if (example.load) example.load(() => {});
// all have `loadSource`
if (example.loadSource) example.loadSource(() => {});
});
}
componentWillReceiveProps(nextProps) {
const { anim } = this.state;
// only animate if we're going from here to direct child.
// child to child we'll ignore
const goingToChild =
nextProps.match.isExact === false && this.props.match.isExact === true;
const comingFromChild =
nextProps.match.isExact === true && this.props.match.isExact === false;
if (goingToChild || comingFromChild) {
this.setState(
{
animating: true
},
() => {
Animated.timing(anim, {
toValue: goingToChild ? 1 : 0,
duration: 350
}).start(() => {
this.setState({
animating: false
});
});
}
);
}
}
render() {
const { data, match, location } = this.props;
const { anim, animating } = this.state;
return (
(
)}
/>
(
{getExampleTitle(data, example)}
)}
/>
(
{getGuideTitle(data, mod)}
)}
/>
(
)}
/>
}
/>
}
/>
);
}
}
function AnimatedHeaderBg({ anim, children }) {
return (
{children}
);
}
AnimatedHeaderBg.propTypes = {
anim: PropTypes.object,
children: PropTypes.node
};
function AnimatedParentHeader({ anim, children }) {
return (
);
}
AnimatedParentHeader.propTypes = {
anim: PropTypes.object,
children: PropTypes.node
};
function AnimatedNav({ anim, children }) {
return (
{children}
);
}
AnimatedNav.propTypes = {
children: PropTypes.node,
anim: PropTypes.object
};
class AnimatedChild extends Component {
static propTypes = {
children: PropTypes.node,
anim: PropTypes.object,
atParent: PropTypes.bool,
animating: PropTypes.bool
};
state = {
previousChildren: null
};
componentWillReceiveProps(nextProps) {
const navigatingToParent = nextProps.atParent && !this.props.atParent;
const animationEnded = this.props.animating && !nextProps.animating;
if (navigatingToParent) {
this.setState({
previousChildren: this.props.children
});
} else if (animationEnded) {
this.setState({
previousChildren: null
});
}
}
render() {
const { anim, children } = this.props;
const { previousChildren } = this.state;
return (
{previousChildren || children}
);
}
}
class AnimatedChildHeader extends Component {
static propTypes = {
children: PropTypes.node,
anim: PropTypes.object,
atParent: PropTypes.bool,
animating: PropTypes.bool
};
state = { previousChildren: null };
componentWillReceiveProps(nextProps) {
const navigatingToParent = nextProps.atParent && !this.props.atParent;
const animationEnded = this.props.animating && !nextProps.animating;
if (navigatingToParent) {
this.setState({
previousChildren: this.props.children
});
} else if (animationEnded) {
this.setState({
previousChildren: null
});
}
}
render() {
const { anim, children } = this.props;
const { previousChildren } = this.state;
return (
{previousChildren || children}
);
}
}
const getApiTitle = (data, slug) => {
const item = data.api.find(item => item.title.slug === slug);
return item ? item.title.text : null;
};
const getExampleTitle = (data, slug) => {
const item = data.examples.find(item => item.slug === slug);
return item ? item.label : null;
};
const getGuideTitle = (data, slug) => {
const item = data.guides.find(item => item.title.slug === slug);
return item ? item.title.text : null;
};
class GoUp extends Component {
static propTypes = {
url: PropTypes.string
};
state = {
justClicked: false
};
render() {
const { url } = this.props;
const { justClicked } = this.state;
return (
this.setState({ justClicked: true })
}}
position="absolute"
top="3px"
left="-8px"
>
);
}
}
function Header({ children, url, ...rest }) {
return (
{children}
);
}
Header.propTypes = {
children: PropTypes.node,
url: PropTypes.string
};
class Page extends Component {
static childContextTypes = {
scrollToDoc: PropTypes.string
};
getChildContext() {
return { scrollToDoc: "mobile-page" };
}
render() {
return (
);
}
}
function Title(props) {
return (
);
}
function NavLink({ to, ...props }) {
return (
(
)}
/>
);
}
NavLink.propTypes = { to: PropTypes.string };
function Nav({ environment, data }) {
return (
{Array.isArray(data.examples) && data.examples.length > 0 && (
Examples
{data.examples.map((item, i) => (
))}
)}
Guides
{data.guides.map((item, i) => (
))}
API
{data.api.map((item, i) => (
{item.headers.map((header, i) => (
))}
))}
);
}
Nav.propTypes = {
data: PropTypes.object,
environment: PropTypes.string
};