From 30fcdf9d7779f0ada8dc5bae8834bbc6d10eda83 Mon Sep 17 00:00:00 2001 From: John Lyon-Smith Date: Fri, 2 Mar 2018 08:55:17 -0800 Subject: [PATCH] Created custom Loader component --- mobile/.expo/packager-info.json | 2 +- website/package-lock.json | 5 ++++ website/package.json | 1 + website/src/Auth/Login.js | 2 +- website/src/Modal/WaitModal.js | 9 ++++-- website/src/index.js | 7 +++++ website/src/ui/Anime.js | 50 +++++++++++++++++++++++++++++++++ website/src/ui/Dimmer.js | 2 +- website/src/ui/Input.style.js | 5 +--- website/src/ui/Loader.js | 50 +++++++++++++++++++++------------ website/src/ui/Text.js | 4 +-- website/src/ui/index.js | 1 + website/src/ui/style.js | 6 +++- 13 files changed, 113 insertions(+), 31 deletions(-) create mode 100644 website/src/ui/Anime.js diff --git a/mobile/.expo/packager-info.json b/mobile/.expo/packager-info.json index 2457a5a..727331b 100644 --- a/mobile/.expo/packager-info.json +++ b/mobile/.expo/packager-info.json @@ -1,5 +1,5 @@ { "expoServerPort": 19000, "packagerPort": 19001, - "packagerPid": 46572 + "packagerPid": 694 } \ No newline at end of file diff --git a/website/package-lock.json b/website/package-lock.json index de4f82c..2c388f7 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -127,6 +127,11 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "animejs": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/animejs/-/animejs-2.2.0.tgz", + "integrity": "sha1-Ne79/FNbgZScnLBvCz5gwC5v3IA=" + }, "ansi-align": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", diff --git a/website/package.json b/website/package.json index b2399e1..fe0da53 100644 --- a/website/package.json +++ b/website/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "private": true, "dependencies": { + "animejs": "^2.2.0", "auto-bind2": "^1.0.2", "eventemitter3": "^2.0.3", "prop-types": "^15.5.10", diff --git a/website/src/Auth/Login.js b/website/src/Auth/Login.js index e037f05..dd50c81 100644 --- a/website/src/Auth/Login.js +++ b/website/src/Auth/Login.js @@ -150,7 +150,7 @@ export class Login extends React.Component { - + + - {this.props.message && {this.props.message}...} + {message && {message}} ) } diff --git a/website/src/index.js b/website/src/index.js index 46869da..3433880 100644 --- a/website/src/index.js +++ b/website/src/index.js @@ -1,8 +1,15 @@ import React from 'react' import ReactDOM from 'react-dom' import { App } from './App' +import { colorInfo } from 'ui/style' ReactDOM.render( , document.getElementById('root') ) + +// HACK: See https://github.com/facebook/react/issues/5619 +let css = document.createElement('style') + +document.body.appendChild(css) +css.innerHTML = `::-webkit-input-placeholder { color: ${colorInfo.textPlaceholder} }` diff --git a/website/src/ui/Anime.js b/website/src/ui/Anime.js new file mode 100644 index 0000000..7d0ebeb --- /dev/null +++ b/website/src/ui/Anime.js @@ -0,0 +1,50 @@ +import React from 'react' +import anime from 'animejs' +import PropTypes from 'prop-types' + +export default class Anime extends React.Component { + static propTypes = { + as: PropTypes.string, + children: PropTypes.node, + } + + constructor(props) { + super(props) + this.targets = [] + } + + componentDidMount() { + let animeProps = Object.assign({}, this.props, { + targets: this.targets + }) + + delete animeProps.children + delete animeProps.as + this.anime = anime(animeProps) + } + + shouldComponentUpdate(nextProps) { + this.anime = anime(Object.assign({}, { targets: this.targets }, nextProps)) + return true + } + + addTarget = (newTarget) => { + this.targets = [...this.targets, newTarget] + } + + render() { + let children = [] + + if (this.props.children) { + if (Array.isArray(this.props.children)) { + children = this.props.children + } else { + children = [this.props.children] + } + } + + return React.createElement( + (this.props.as || 'div'), {}, children.map((child, i) => (React.cloneElement(child, { key: i, ref: this.addTarget }))) + ) + } +} diff --git a/website/src/ui/Dimmer.js b/website/src/ui/Dimmer.js index f9738b0..a4d4116 100644 --- a/website/src/ui/Dimmer.js +++ b/website/src/ui/Dimmer.js @@ -6,8 +6,8 @@ import { reactAutoBind } from 'auto-bind2' export class Dimmer extends Component { static propTypes = { + active: PropTypes.bool.isRequired, children: PropTypes.node, - active: PropTypes.bool } constructor(props) { diff --git a/website/src/ui/Input.style.js b/website/src/ui/Input.style.js index baadf02..3bab9f4 100644 --- a/website/src/ui/Input.style.js +++ b/website/src/ui/Input.style.js @@ -8,11 +8,8 @@ export default { color: '#000000', borderStyle: 'solid', borderRadius: '5px', - // boxShadow: '0px 0px 0px rgba(66,66,66,.75)' - // textShadow: 'undefined 0px 0px 5px px rgba(66,66,66,.75)' - ':focus': { outline: 'none' - } + }, } } diff --git a/website/src/ui/Loader.js b/website/src/ui/Loader.js index a703b51..8851444 100644 --- a/website/src/ui/Loader.js +++ b/website/src/ui/Loader.js @@ -1,6 +1,8 @@ import React from 'react' import Radium from 'radium' import PropTypes from 'prop-types' +import { colorInfo } from 'ui/style' +import anime from 'animejs' class Loader extends React.Component { static propTypes = { @@ -15,26 +17,38 @@ class Loader extends React.Component { margin: '2px' } - style(i) { - return { - backgroundColor: `${this.props.color}`, - width: `${this.props.size}px`, - height: `${this.props.size}px`, - margin: `${this.props.margin}`, - borderRadius: '100%', - display: 'inline-block', - // 0% {transform: scale(1); opacity: 1} 45% {transform: scale(0.1); opacity: 0.7} 80% {transform: scale(1); opacity: 1} 0.75s ${i * 0.12}s infinite cubic-bezier(.2,.68,.18,1.08) - animation: ``, - animationFillMode: 'both' - } - } - render() { + const size = 20 + const spacing = 5 + + const addAnimation = (elem, i) => { + anime({ + targets: elem, + scale: [ + { value: 0.2, duration: 800, easing: 'easeOutSine', delay: 200 * i }, + { value: 1.0, duration: 800, easing: 'easeOutSine' }, + { value: 1.0, duration: 200 * (2 - i) } + ], + loop: true + }) + } + return ( -
-
-
-
+
+ { + [0, 1, 2].map((i) => ( + addAnimation(elem, i)} + style={{ + display: 'inline-block', + marginLeft: i > 0 ? spacing : 0, + width: size, + height: size, + background: colorInfo.textInverse, + borderSize: 0, + borderRadius: '100%' + }} /> + )) + }
) } diff --git a/website/src/ui/Text.js b/website/src/ui/Text.js index d426b20..a780c7f 100644 --- a/website/src/ui/Text.js +++ b/website/src/ui/Text.js @@ -5,10 +5,10 @@ import { fontInfo } from './style' class Text extends Component { static propTypes = { - size: PropTypes.string, + size: PropTypes.oneOf(['small', 'medium', 'large', 'huge']), + color: PropTypes.oneOf(['normal', 'inverse', 'alert', 'dimmed']), margin: PropTypes.number, children: PropTypes.node, - color: PropTypes.oneOf(['normal', 'alert', 'dimmed']), width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), align: PropTypes.string, } diff --git a/website/src/ui/index.js b/website/src/ui/index.js index 78e8545..cf6195d 100644 --- a/website/src/ui/index.js +++ b/website/src/ui/index.js @@ -1,3 +1,4 @@ +export { default as Anime } from './Anime' export { default as Box } from './Box' export { default as Button } from './Button' export { default as HeaderButton } from './HeaderButton' diff --git a/website/src/ui/style.js b/website/src/ui/style.js index 3f086a0..8528c70 100644 --- a/website/src/ui/style.js +++ b/website/src/ui/style.js @@ -1,5 +1,7 @@ export const colorInfo = { text: '#000000', + textInverse: '#FFFFFF', + textPlaceholder: '#EEEEEE', alertText: '#FF0000', grayText: '#B0B0B0', buttonBackground: '#3498DB', @@ -28,10 +30,12 @@ export const fontInfo = { size: { small: '10pt', medium: '12pt', - large: '14pt' + large: '14pt', + huge: '26pt', }, color: { 'normal': colorInfo.text, + 'inverse': colorInfo.textInverse, 'alert': colorInfo.alertText, 'dimmed': colorInfo.grayText, }