Added a Loader module

Signed-off-by: Florian BOUILLON <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2021-03-15 14:54:27 +01:00
parent d898dc2f5b
commit 67a4825cda
3 changed files with 97 additions and 10 deletions

View File

@ -0,0 +1,18 @@
@import '../config'
.div
position fixed
left 0
width 100%
height 7px
pointer-events none
top 0
&.hide
transition top .5s ease-in-out
top -7px
div
&:not([style="width: 0px;"])
transition width 50ms ease-in-out
background rgba($main, .7)
height 100%

View File

@ -0,0 +1,79 @@
import { Router } from 'next/router'
import React from 'react'
import { buildClassName } from '../Util'
import css from './Loader.module.styl'
interface Props {
percent?: number
auto?: {
interval: [number, number]
increment: [number, number]
}
}
interface State {
percent?: number
}
export default class Loader extends React.Component<Props, State> {
public state: State = {}
private interval?: NodeJS.Timeout
public componentDidMount() {
if (this.props.auto) {
Router.events.on('routeChangeComplete', this.routeChangeComplete)
Router.events.on('routeChangeStart', this.routeChangeStart)
}
}
public componentWillUnmount() {
if (this.props.auto) {
Router.events.off('routechangeComplete', this.routeChangeComplete)
Router.events.off('routechangeStart', this.routeChangeStart)
}
}
public render = () => (
<div className={buildClassName(css.div, [css.hide, (this.props.percent || this.state.percent) === 100])}>
<div style={{width: (this.props.percent || this.state.percent) ? `${(this.props.percent || this.state.percent)}%` : 0}}></div>
</div>
)
private routeChangeComplete = () => {
if (this.interval) {
clearTimeout(this.interval)
this.interval = undefined
}
this.setState({percent: 100})
}
private routeChangeStart = () => {
if (this.interval) {
clearTimeout(this.interval)
}
this.setState({percent: 0}, () => {
if (!this.props.auto) {return}
this.interval = setTimeout(this.timeoutFn, this.randomInt(this.props.auto.interval[0], this.props.auto.interval[1]))
})
}
private timeoutFn = () => {
if (!this.props.auto) {return}
const p = this.state.percent || 0
this.setState({
percent: Math.min(
99,
p >= 80 ? p + Math.random() : p + this.randomInt(this.props.auto.increment[0], this.props.auto.increment[1])
)
})
this.interval = setTimeout(this.timeoutFn, this.randomInt(this.props.auto.interval[0], this.props.auto.interval[1]))
}
private randomInt(min = 0, max = 10) {
min = Math.ceil(min)
max = Math.floor(max)
return Math.floor(Math.random() * (max - min + 1)) + min
}
}

View File

@ -24,13 +24,3 @@ export function buildClassName(...classes: Array<Array<any> | string | undefined
}
return classesFinal.join(' ')
}
export const colors = {
default: '#3949AB', // This color should never appear
primary: '#3949AB',
secondary: '#FCFCFC',
info: '#03A9F4',
success: '#2DCE89',
danger: '#F5365C',
warning: '#FB6340'
}