mirror of
https://github.com/dzeiocom/components.git
synced 2025-06-07 08:39:55 +00:00
98 lines
2.4 KiB
TypeScript
98 lines
2.4 KiB
TypeScript
import { Router } from 'next/router'
|
|
import React from 'react'
|
|
import { buildClassName } from '../Util'
|
|
import css from './Loader.module.styl'
|
|
|
|
interface Props {
|
|
/**
|
|
* The new Percentage (if you calculate it yourself)
|
|
*/
|
|
percent?: number
|
|
|
|
/**
|
|
* Auto random loader
|
|
*/
|
|
auto?: {
|
|
/**
|
|
* the minimum and maximum interval between two increment
|
|
*/
|
|
interval: [number, number]
|
|
/**
|
|
* the minimum and maximum incrementation (MUST be an integer)
|
|
*/
|
|
increment: [number, number]
|
|
}
|
|
}
|
|
|
|
interface State {
|
|
percent?: number
|
|
}
|
|
|
|
/**
|
|
* Display a simple loading animation at the top of the page
|
|
*
|
|
* @version 1.0.0
|
|
*/
|
|
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
|
|
}
|
|
}
|