Первые попытки анимации

This commit is contained in:
SleepWalker
2016-01-18 07:28:43 +02:00
parent 9aff4fb83a
commit 7696f9e4bf
7 changed files with 100 additions and 20 deletions

View File

@@ -22,10 +22,11 @@
"react-dom": "^0.14.3", "react-dom": "^0.14.3",
"react-helmet": "^2.3.1", "react-helmet": "^2.3.1",
"react-intl": "^2.0.0-pr-3", "react-intl": "^2.0.0-pr-3",
"react-motion": "^0.3.1",
"react-redux": "^4.0.0", "react-redux": "^4.0.0",
"react-router": "^2.0.0-rc4", "react-router": "^2.0.0-rc5",
"redux": "^3.0.4", "redux": "^3.0.4",
"redux-simple-router": "^1.0.2", "redux-simple-router": "^2.0.0",
"redux-thunk": "^1.0.0" "redux-thunk": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,4 +1,6 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux';
import { routeActions } from 'redux-simple-router';
import { FormattedMessage as Message } from 'react-intl'; import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
@@ -11,7 +13,7 @@ import { Input, Checkbox } from 'components/ui/Form';
import styles from './signIn.scss'; import styles from './signIn.scss';
import messages from './SignIn.messages'; import messages from './SignIn.messages';
export default class Login extends Component { class Login extends Component {
displayName = 'Login'; displayName = 'Login';
render() { render() {
@@ -24,7 +26,7 @@ export default class Login extends Component {
<Input icon="envelope" type="email" placeholder="E-mail or username" /> <Input icon="envelope" type="email" placeholder="E-mail or username" />
</PanelBody> </PanelBody>
<PanelFooter> <PanelFooter>
<button className={buttons.green}> <button className={buttons.green} onClick={this.onSubmit}>
<Message {...messages.next} /> <Message {...messages.next} />
</button> </button>
</PanelFooter> </PanelFooter>
@@ -37,4 +39,15 @@ export default class Login extends Component {
</div> </div>
); );
} }
onSubmit = (event) => {
event.preventDefault();
this.props.push('/password');
};
} }
export default connect(null, {
push: routeActions.push
})(Login);

View File

@@ -77,14 +77,14 @@ $authBodyLeftRightPadding: 32px;
$authBodyTopBottomPadding: 30px; $authBodyTopBottomPadding: 30px;
.authBody { .authBody {
composes: body from './../ui/panel.scss'; composes: body from 'components/ui/panel.scss';
padding: $authBodyTopBottomPadding $authBodyLeftRightPadding; padding: $authBodyTopBottomPadding $authBodyLeftRightPadding;
text-align: left; text-align: left;
} }
.authBodyHeader { .authBodyHeader {
composes: defaultBodyHeader from './../ui/panel.scss'; composes: defaultBodyHeader from 'components/ui/panel.scss';
// Отступы сверху и снизу разные т.к. мы ужимаем высоту линии строки с логином на 2 пикселя и из-за этого теряем отступ снизу // Отступы сверху и снизу разные т.к. мы ужимаем высоту линии строки с логином на 2 пикселя и из-за этого теряем отступ снизу
padding: 15px $authBodyLeftRightPadding 17px; padding: 15px $authBodyLeftRightPadding 17px;

View File

@@ -13,7 +13,7 @@ import { Provider as ReduxProvider } from 'react-redux';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
import { Router, browserHistory } from 'react-router'; import { Router, browserHistory } from 'react-router';
import { syncReduxAndRouter, routeReducer } from 'redux-simple-router'; import { syncHistory, routeReducer } from 'redux-simple-router';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';
@@ -27,19 +27,20 @@ const reducer = combineReducers({
routing: routeReducer routing: routeReducer
}); });
const reduxRouterMiddleware = syncHistory(browserHistory);
const store = applyMiddleware( const store = applyMiddleware(
reduxRouterMiddleware,
thunk thunk
)(createStore)(reducer); )(createStore)(reducer);
syncReduxAndRouter(browserHistory, store);
ReactDOM.render( ReactDOM.render(
<IntlProvider locale="en" messages={{}}> <IntlProvider locale="en" messages={{}}>
<ReduxProvider store={store}> <ReduxProvider store={store}>
<Router history={browserHistory}> <Router history={browserHistory}>
{routes} {routes}
</Router> </Router>
</ReduxProvider> </ReduxProvider>
</IntlProvider>, </IntlProvider>,
document.getElementById('app') document.getElementById('app')
); );

View File

@@ -1,10 +1,13 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux';
import { TransitionMotion, spring } from 'react-motion';
import AppInfo from 'components/auth/AppInfo'; import AppInfo from 'components/auth/AppInfo';
import styles from './auth.scss'; import styles from './auth.scss';
export default class AuthPage extends Component { class AuthPage extends Component {
displayName = 'AuthPage'; displayName = 'AuthPage';
render() { render() {
@@ -13,15 +16,65 @@ export default class AuthPage extends Component {
description: `Лучший альтернативный лаунчер для Minecraft с большим количеством версий и их модификаций, а также возмоностью входа как с лицензионным аккаунтом, так и без него.` description: `Лучший альтернативный лаунчер для Minecraft с большим количеством версий и их модификаций, а также возмоностью входа как с лицензионным аккаунтом, так и без него.`
}; };
var { path, children } = this.props;
return ( return (
<div> <div>
<div className={styles.sidebar}> <div className={styles.sidebar}>
<AppInfo {...appInfo} /> <AppInfo {...appInfo} />
</div> </div>
<div className={styles.content}> <div className={styles.content}>
{this.props.children} <TransitionMotion
willEnter={this.willEnter}
willLeave={this.willLeave}
styles={{
[path]: {
children,
x: spring(0)
}
}}
>
{(items) => (
<div style={{position: 'relative', overflow: 'hidden', width: '100%', height: '600px'}}>
{Object.keys(items).map((path) => {
const {children, x} = items[path];
const style = {
position: 'absolute',
top: 0,
width: '100%',
left: `${x}%`
};
return (
<div key={path} style={style}>
{children}
</div>
);
})}
</div>
)}
</TransitionMotion>
</div> </div>
</div> </div>
); );
} }
willEnter(key, styles) {
return {
...styles,
x: spring(100)
};
}
willLeave(key, styles) {
return {
...styles,
x: spring(-100)
};
}
} }
export default connect((state) => ({
path: state.routing.location.pathname
}))(AuthPage);

View File

@@ -11,9 +11,20 @@ import Permissions from 'components/auth/Permissions';
import Activation from 'components/auth/Activation'; import Activation from 'components/auth/Activation';
import Password from 'components/auth/Password'; import Password from 'components/auth/Password';
function requireAuth(nextState, replace) {
// if (!auth.loggedIn()) {
replace({
pathname: '/login',
state: {
nextPathname: nextState.location.pathname
}
});
// }
}
export default ( export default (
<Route path="/" component={RootPage}> <Route path="/" component={RootPage}>
<IndexRoute component={IndexPage} /> <IndexRoute component={IndexPage} onEnter={requireAuth} />
<Route path="auth" component={AuthPage}> <Route path="auth" component={AuthPage}>
<Route path="/login" component={Login} /> <Route path="/login" component={Login} />

View File

@@ -11,6 +11,7 @@ var iconfontImporter = require('./webpack/node-sass-iconfont-importer');
/** /**
* TODO: https://babeljs.io/docs/plugins/ * TODO: https://babeljs.io/docs/plugins/
* TODO: отдельные конфиги для env (аля https://github.com/davezuko/react-redux-starter-kit) * TODO: отдельные конфиги для env (аля https://github.com/davezuko/react-redux-starter-kit)
* TODO: dev tools https://github.com/freeqaz/redux-simple-router-example/blob/master/index.jsx
* https://github.com/glenjamin/ultimate-hot-reloading-example ( обратить внимание на плагины babel ) * https://github.com/glenjamin/ultimate-hot-reloading-example ( обратить внимание на плагины babel )
* https://github.com/gajus/react-css-modules ( + BrowserSync) * https://github.com/gajus/react-css-modules ( + BrowserSync)
* *