Add Fadable component

This commit is contained in:
Tom Raithel
2017-02-25 23:34:25 +01:00
parent 5e57c9caae
commit 5f20c00bec
9 changed files with 163 additions and 46 deletions

View File

@@ -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
View 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;

View File

@@ -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>
);
}

View File

@@ -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>
);
}

View File

@@ -3,49 +3,53 @@ 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 (
<div className="item-page">
<div className="item-page__nav">
<div className="item-page__nav__inner">
<div className="item-page__header">
<h3 className="headline">Languages &amp; Frameworks</h3>
</div>
<ItemList items={itemsInRing} activeItem={item}>
<div className="split">
<div className="split__left">
<Badge big type={item.ring}>{item.ring}</Badge>
<Fadeable leaving={leaving} onLeave={onLeave}>
<div className="item-page">
<div className="item-page__nav">
<div className="item-page__nav__inner">
<div className="item-page__header">
<h3 className="headline">Languages &amp; Frameworks</h3>
</div>
<ItemList items={itemsInRing} activeItem={item}>
<div className="split">
<div className="split__left">
<Badge big type={item.ring}>{item.ring}</Badge>
</div>
<div className="split__right">
<Link className="icon-link" pageName={item.quadrant}>
<span className="icon icon--pie icon-link__icon"></span>Quadrant Overview
</Link>
</div>
</div>
<div className="split__right">
<Link className="icon-link" pageName={item.quadrant}>
<span className="icon icon--pie icon-link__icon"></span>Quadrant Overview
</Link>
</div>
</div>
</ItemList>
</div>
</div>
<div className="item-page__content">
<div className="item-page__content__inner">
<div className="item-page__header">
<div className="split">
<div className="split__left">
<h1 className="hero-headline hero-headline--inverse">{item.title}</h1>
</div>
<div className="split__right">
<Badge big type={item.ring}>{item.ring}</Badge>
</ItemList>
</div>
</div>
<div className="item-page__content">
<div className="item-page__content__inner">
<div className="item-page__header">
<div className="split">
<div className="split__left">
<h1 className="hero-headline hero-headline--inverse">{item.title}</h1>
</div>
<div className="split__right">
<Badge big type={item.ring}>{item.ring}</Badge>
</div>
</div>
</div>
<div className="markdown" dangerouslySetInnerHTML={{__html: item.body}} />
</div>
<div className="markdown" dangerouslySetInnerHTML={{__html: item.body}} />
</div>
</div>
</div>
</Fadeable>
);
}

View File

@@ -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>
);
}
}

View File

@@ -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>
);
}

View File

@@ -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;