Browse Source

Added the FadeInOut animation component and tested on the toggle.

Snow 8 years ago
parent
commit
1925f5650b

+ 14 - 0
src/__test__/Toggle.test.js

@@ -0,0 +1,14 @@
+import React from 'react';
+import Toggle from '../components/Toggle';
+import FadeInOut from '../components/Animation/FadeInOut'
+import { mount, shallow } from 'enzyme';
+
+describe('Toggle', () => {
+  it('Clicking the toggle shows the FadeInOut element', () => {
+    const toggoleWindow = mount(<Toggle/>)
+    toggoleWindow.find('button').simulate('click')
+    expect(toggoleWindow.find('FadeInOut')).toBeTruthy()
+    toggoleWindow.find('button').simulate('click')
+    expect(toggoleWindow.contains(<FadeInOut/>)).toBeFalsy()
+  })
+})

+ 29 - 0
src/components/Animation/FadeInOut.js

@@ -0,0 +1,29 @@
+import React from 'react'
+import {TransitionMotion, spring} from 'react-motion'
+
+export default class FadeInOut extends React.Component {
+  willEnter = () => ({opacity: 0.01})
+  willLeave = () => ({opacity: spring(0)})
+  render() {
+    return (
+      <TransitionMotion
+        styles={this.props.content ? this.props.content.map(({key    ,data,...rest}) => ({
+      key: key,
+          data: data,
+      style: rest
+    })) : []}
+    willEnter={this.willEnter}
+    willLeave={this.willLeave}
+    >
+        {(styles) => {
+          return (
+      <div>
+        { styles.map(({ key, data, style}) => (
+          <div key={key} style={{...style}}>{ data }</div>
+        ))}
+            </div>)
+        }}
+  </TransitionMotion>
+    )
+  }
+}

+ 56 - 53
src/components/Form/index.js

@@ -18,12 +18,12 @@ export default class Form extends React.Component {
 
   validateRequired = name => {
     const warning = (
-            <Motion defaultStyle={{x:0}} style={{ x: spring(1) }}>
-        {({x}) =>
-          <span className="warning" key="isRequired" style={{opacity:x}}>
-        This field is required.
-      </span>}
-           </Motion>
+      <Motion defaultStyle={{ x: 0 }} style={{ x: spring(1) }}>
+        {({ x }) =>
+          <span className="warning" style={{ opacity: x }}>
+            This field is required.
+          </span>}
+      </Motion>
     );
     const color = this.state[name].color;
     return this.state[name].message.length > 0 && color !== 'grey'
@@ -33,11 +33,11 @@ export default class Form extends React.Component {
 
   validateLength = (name, length) => {
     const warning = (
-      <Motion defaultStyle={{x:0}} style={{ x: spring(1) }}>
-        {({x}) =>
-          <span className="warning" key="minLength" style={{opacity: x}}>
-        This field should at least have {length} characters.
-      </span>}
+      <Motion defaultStyle={{ x: 0 }} style={{ x: spring(1) }}>
+        {({ x }) =>
+          <span className="warning"  style={{ opacity: x }}>
+            This field should at least have {length} characters.
+          </span>}
       </Motion>
     );
     const color = this.state[name].color;
@@ -50,7 +50,7 @@ export default class Form extends React.Component {
     const password1 = this.state[name1].message;
     const password2 = this.state[name2].message;
     const warning = (
-      <span className="warning" key="pwdMatch">
+      <span className="warning">
         Password don't match.
       </span>
     );
@@ -62,36 +62,34 @@ export default class Form extends React.Component {
     // force validate all fields
     const keys = Object.keys(this.state);
     keys.forEach(name => {
-       const warnings = this.validateItem(name);
-if (name === 'password' || name === 'password2') {
-      // match two password input behavior
-      this.setState({
-        password: Object.assign({}, this.state.password, {
-          warnings
-        }),
-        password2: Object.assign({}, this.state.password2, {
-          warnings
-        })
-      });
-    } else {
-      this.setState({
-        [name]: Object.assign({}, this.state[name], {
-          warnings
-        })
-      });
-    }
+      const warnings = this.validateItem(name);
+      if (name === 'password' || name === 'password2') {
+        // match two password input behavior
+        this.setState({
+          password: Object.assign({}, this.state.password, {
+            warnings
+          }),
+          password2: Object.assign({}, this.state.password2, {
+            warnings
+          })
+        });
+      } else {
+        this.setState({
+          [name]: Object.assign({}, this.state[name], {
+            warnings
+          })
+        });
+      }
     });
 
     const inValidFields = keys.filter(
       name => this.state[name].warnings.length !== 0
     );
-    if (inValidFields.length !== 0 || this.state.password.color === 'grey') {event.preventDefault()};
+    if (inValidFields.length !== 0 || this.state.password.color === 'grey') {
+      event.preventDefault();
+    }
   };
 
-  wrapWarnings = (...theArgs) => {
-    const validWarnings = theArgs.filter(arg => arg !== null);
-    return validWarnings;
-  };
   handleFocus = event => {
     const target = event.target;
     const name = target.name;
@@ -110,22 +108,28 @@ if (name === 'password' || name === 'password2') {
     let warnings;
     switch (name) {
       case 'name':
-        warnings = this.wrapWarnings(
-          this.validateLength(name, 5),
-          this.validateRequired(name)
+        warnings = (
+          <div>
+            {this.validateLength(name, 5)}
+            {this.validateRequired(name)}
+          </div>
         );
         break;
       case 'password':
       case 'password2':
-        warnings = this.wrapWarnings(
-          this.validatePasswordMatch('password', 'password2'),
-          this.validateRequired(name)
+        warnings = (
+          <div>
+            {this.validatePasswordMatch('password', 'password2')}
+            {this.validateRequired(name)}
+          </div>
         );
         break;
       case 'comments':
-        warnings = this.wrapWarnings(
-          this.validateLength(name, 20),
-          this.validateRequired(name)
+        warnings = (
+          <div>
+            {this.validateLength(name, 20)}
+            {this.validateRequired(name)}
+          </div>
         );
         break;
       default:
@@ -133,11 +137,11 @@ if (name === 'password' || name === 'password2') {
     }
     return warnings;
   };
+
   handleBlur = event => {
     const target = event.target;
     const name = target.name;
     const message = this.constructor.placeHolder[name].message;
-
     const warnings = this.validateItem(name);
     if (target.value.length === 0) {
       this.setState({
@@ -148,20 +152,20 @@ if (name === 'password' || name === 'password2') {
         })
       });
     } else if (name === 'password' || name === 'password2') {
-      // match two password input behavior
+      // match two password inputs behavior
       this.setState({
-        password: Object.assign({}, this.state.password, {
+        password: {...this.state.password, 
           warnings
-        }),
-        password2: Object.assign({}, this.state.password2, {
+        },
+        password2:{ ...this.state.password2, 
           warnings
-        })
+        }
       });
     } else {
       this.setState({
-        [name]: Object.assign({}, this.state[name], {
+        [name]: {...this.state[name], 
           warnings
-        })
+        }
       });
     }
   };
@@ -192,7 +196,6 @@ if (name === 'password' || name === 'password2') {
     if (type === 'textarea') {
       return <textarea {...props} />;
     }
-
     return <input {...props} />;
   };
 

+ 3 - 0
src/components/Toggle/index.js

@@ -1,5 +1,6 @@
 import React from 'react';
 import { Motion, spring } from 'react-motion';
+import FadeInOut from '../Animation/FadeInOut'
 
 import './style.css';
 
@@ -13,6 +14,7 @@ export default class Toggle extends React.Component {
   };
 
   render() {
+    const animatedContent = this.state.open ? [{key: 'FadeInOut',data:'FadeInOut', opacity: spring(1)}] : null
     return (
       <div>
         <p>
@@ -35,6 +37,7 @@ export default class Toggle extends React.Component {
               />
             </div>}
         </Motion>
+        <FadeInOut content={animatedContent}/>
       </div>
     );
   }