mirror of
https://github.com/dzeiocom/components.git
synced 2025-06-16 20:49:20 +00:00
97
src/Loader/index.tsx
Normal file
97
src/Loader/index.tsx
Normal file
@ -0,0 +1,97 @@
|
||||
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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user