Add Fadable component
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import actions from '../actions';
|
||||
@@ -13,7 +14,7 @@ function App(props) {
|
||||
<div className="page__header">
|
||||
<Header {...props} />
|
||||
</div>
|
||||
<div className="page__content">
|
||||
<div className={classNames('page__content', { 'is-faded': props.isFaded })}>
|
||||
<Router {...props} />
|
||||
</div>
|
||||
<div className="page__footer">
|
||||
|
||||
45
js/components/Fadeable.js
Normal file
45
js/components/Fadeable.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class Fadeable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
faded: props.leaving,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps({ leaving }) {
|
||||
if (!this.props.leaving && leaving) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
faded: true,
|
||||
});
|
||||
}
|
||||
if (this.props.leaving && !leaving) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
faded: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleTransitionEnd = () => {
|
||||
if (this.state.faded) {
|
||||
this.props.onLeave();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className={classNames('fadable', { 'is-faded': this.state.faded })}
|
||||
onTransitionEnd={this.handleTransitionEnd}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Fadeable;
|
||||
@@ -1,10 +1,11 @@
|
||||
import React from 'react';
|
||||
import HeroHeadline from './HeroHeadline';
|
||||
import Fadeable from './Fadeable';
|
||||
|
||||
export default function PageHelp() {
|
||||
export default function PageHelp({ leaving, onLeave }) {
|
||||
return (
|
||||
<div>
|
||||
<Fadeable leaving={leaving} onLeave={onLeave}>
|
||||
<HeroHeadline>How to use AOE Technology Radar</HeroHeadline>
|
||||
</div>
|
||||
</Fadeable>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React from 'react';
|
||||
import HeroHeadline from './HeroHeadline';
|
||||
import QuadrantGrid from './QuadrantGrid';
|
||||
import Fadeable from './Fadeable';
|
||||
|
||||
export default function PageIndex({ items, navigate }) {
|
||||
export default function PageIndex({ leaving, onLeave, items, navigate }) {
|
||||
return (
|
||||
<div>
|
||||
<Fadeable leaving={leaving} onLeave={onLeave}>
|
||||
<div className="headline-group">
|
||||
<HeroHeadline alt="Mar 2017">AOE Technology Radar</HeroHeadline>
|
||||
</div>
|
||||
<QuadrantGrid items={items} />
|
||||
</div>
|
||||
</Fadeable>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,17 @@ import HeroHeadline from './HeroHeadline';
|
||||
import Badge from './Badge';
|
||||
import ItemList from './ItemList';
|
||||
import Link from './Link';
|
||||
import Fadeable from './Fadeable';
|
||||
|
||||
import { groupByQuadrants } from '../../common/model';
|
||||
|
||||
export default function PageItems({ pageName, items }) {
|
||||
export default function PageItems({ leaving, onLeave, pageName, items }) {
|
||||
const [quadrantName, itemName] = pageName.split('/');
|
||||
const item = items.filter(item => item.quadrant === quadrantName && item.name === itemName)[0];
|
||||
const itemsInRing = groupByQuadrants(items)[item.quadrant][item.ring];
|
||||
|
||||
return (
|
||||
<Fadeable leaving={leaving} onLeave={onLeave}>
|
||||
<div className="item-page">
|
||||
<div className="item-page__nav">
|
||||
<div className="item-page__nav__inner">
|
||||
@@ -47,5 +50,6 @@ export default function PageItems({ pageName, items }) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fadeable>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import HeadlineGroup from './HeadlineGroup';
|
||||
import HeroHeadline from './HeroHeadline';
|
||||
import Badge from './Badge';
|
||||
import Link from './Link';
|
||||
import Fadeable from './Fadeable';
|
||||
import { groupByFirstLetter } from '../../common/model';
|
||||
import { translate } from '../../common/config';
|
||||
|
||||
@@ -45,7 +46,7 @@ class PageOverview extends React.Component {
|
||||
const groups = this.getFilteredAndGroupedItems();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Fadeable leaving={this.props.leaving} onLeave={this.props.onLeave}>
|
||||
<HeadlineGroup>
|
||||
<HeroHeadline>Technologies Overview</HeroHeadline>
|
||||
</HeadlineGroup>
|
||||
@@ -106,7 +107,7 @@ class PageOverview extends React.Component {
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Fadeable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,19 @@ import React from 'react';
|
||||
import HeroHeadline from './HeroHeadline';
|
||||
import HeadlineGroup from './HeadlineGroup';
|
||||
import QuadrantSection from './QuadrantSection';
|
||||
import Fadeable from './Fadeable';
|
||||
|
||||
import { translate } from '../../common/config';
|
||||
import { groupByQuadrants } from '../../common/model';
|
||||
|
||||
export default function PageQuadrant({ pageName, items }) {
|
||||
export default function PageQuadrant({ leaving, onLeave, pageName, items }) {
|
||||
const groups = groupByQuadrants(items);
|
||||
return (
|
||||
<div>
|
||||
<Fadeable leaving={leaving} onLeave={onLeave}>
|
||||
<HeadlineGroup>
|
||||
<HeroHeadline>{translate(pageName)}</HeroHeadline>
|
||||
</HeadlineGroup>
|
||||
<QuadrantSection groups={groups} quadrantName={pageName} big />
|
||||
</div>
|
||||
</Fadeable>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,46 @@ const getPageByName = (items, pageName) => {
|
||||
return 'div';
|
||||
}
|
||||
|
||||
export default function Router({ pageName, ...props}) {
|
||||
const Comp = getPageByName(props.items, pageName);
|
||||
return <Comp {...props} pageName={pageName} />;
|
||||
class Router extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
pageName: props.pageName,
|
||||
leaving: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps({ pageName }) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
nextPageName: pageName,
|
||||
leaving: true,
|
||||
});
|
||||
}
|
||||
|
||||
handlePageLeave = () => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
pageName: this.state.nextPageName,
|
||||
leaving: true,
|
||||
nextPageName: null,
|
||||
});
|
||||
|
||||
window.setTimeout(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.setState({
|
||||
...this.state,
|
||||
leaving: false,
|
||||
});
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { pageName, leaving } = this.state;
|
||||
const Comp = getPageByName(this.props.items, pageName);
|
||||
return <Comp {...this.props} pageName={pageName} leaving={leaving} onLeave={this.handlePageLeave} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default Router;
|
||||
|
||||
23
styles/components/fadeable.css
Normal file
23
styles/components/fadeable.css
Normal file
@@ -0,0 +1,23 @@
|
||||
.fadable {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
transition: opacity 0.2s cubic-bezier(0.54, 0, 0.28, 1);
|
||||
content: '';
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
background: var(--color-gray-dark);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.is-faded {
|
||||
&::after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user