Button submit indicator

main
Ashelyn Dawn 4 years ago
parent aa8562a1a1
commit 48fede9e06

@ -1,7 +1,9 @@
// TODO: Enable exportDefaultFrom in Babel syntax
import React, { useReducer } from 'react'
import React, { useState, useReducer } from 'react'
import axios from 'axios'
import Spinner from '~/components/spinner'
import styles from './styles.module.css'
export const Input = require('./input.js').default
export const IntegerInput = require('./integerInput.js').default
@ -74,7 +76,7 @@ const formReducer = errorDispatch => (state, action)=>{
}
export const FormController = function FormController({children, className, url, method = 'POST', afterSubmit = ()=>null}){
export const FormController = function FormController({children, className, url, method = 'POST', afterSubmit = ()=>null}){
const initialState = {
fields: {}
}
@ -95,9 +97,10 @@ export const FormController = function FormController({children, className, url
}
})
// Create reducers
// Create state
const [errors, errorDispatch] = useReducer(errorReducer, {})
const [state, dispatch] = useReducer(formReducer(errorDispatch), initialState)
const [submitting, setSubmitting] = useState(false)
// Handle submitting form
const handleSubmit = async (ev) => {
@ -114,6 +117,7 @@ export const FormController = function FormController({children, className, url
if(url)
try {
setSubmitting(true)
const {data: response} = await axios({ method, url, data })
return afterSubmit(response)
} catch (err) {
@ -123,6 +127,8 @@ export const FormController = function FormController({children, className, url
type: 'set_errors',
errors: err.response.data.errors
})
} finally {
setTimeout(()=>setSubmitting(false), 200)
}
afterSubmit(data)
@ -133,8 +139,11 @@ export const FormController = function FormController({children, className, url
if(child.type === Button && child.props.type.toLowerCase() === 'submit')
return React.cloneElement(child, {
// Allow enabled prop to disable, but not solely enable
enabled: child.props.enabled !== false && !Object.values(state.fields).some(field=>!field.isValid),
onClick: handleSubmit
enabled: child.props.enabled !== false && !submitting && !Object.values(state.fields).some(field=>!field.isValid),
onClick: handleSubmit,
children: submitting
? <Spinner />
: child.props.children
})
const {name} = child.props;

@ -0,0 +1,11 @@
import styles from './spinner.module.css'
export default function Spinner(){
return (
<div className={styles.spinner}>
<div className={styles.bounce1}></div>
<div className={styles.bounce2}></div>
<div className={styles.bounce3}></div>
</div>
)
}

@ -0,0 +1,48 @@
.spinner {
height: 16px;
font-size: 35px;
margin: 0px auto;
width: 100%;
text-align: center;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.spinner > div {
width: .25em;
height: .25em;
background-color: currentColor;
margin: 0 .06em;
border-radius: 100%;
display: inline-block;
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
}
.spinner .bounce1 {
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.spinner .bounce2 {
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
@-webkit-keyframes sk-bouncedelay {
0%, 80%, 100% { -webkit-transform: scale(0) }
40% { -webkit-transform: scale(1.0) }
}
@keyframes sk-bouncedelay {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
} 40% {
-webkit-transform: scale(1.0);
transform: scale(1.0);
}
}
Loading…
Cancel
Save