import { computed, observable, action } from 'xmobx/mobx'
import { EMPTY_OBJ } from 'exotic'
interface StateValues {
value?: number
minValue?: number
adaptive?: boolean
delta?: number
size?: number
sizes?: Array<number>
total?: number
// @computed
start?: number
options?: Array<number>
length?: number
maxValue?: number
isFirst?: boolean
isLast?: boolean
}
class State {
@observable
value: number = 1
@observable
minValue: number = 1
@observable
adaptive: boolean = false
@observable
delta: number = 4
@observable
size: number = 20
@observable
sizes: Array<number> = [10, 20, 50, 100, 200]
@observable
total: number = 100
/**
* @note
* 1. now we can get the props to create the state
* 2. we can pass in the state
* 3. or we can default the state
*/
constructor(props: StateValues = EMPTY_OBJ) {
if (props.value) {
this.setValue(props.value)
}
if (props.minValue) {
this.setMinValue(props.minValue)
}
if (props.adaptive) {
this.setAdaptive(props.adaptive)
}
if (props.delta) {
this.setDelta(props.delta)
}
if (props.size) {
this.setSize(props.size)
}
if (props.sizes) {
this.setSizes(props.sizes)
}
if (props.total) {
this.setTotal(props.total)
}
}
@action
setValue(value: number): void {
this.value = parseInt(value, 10)
}
@action
setMinValue(value: number): void {
this.minValue = parseInt(value, 10)
}
@action.bound
nextPage(event?: any): void {
if (this.value < this.maxValue) {
this.value++
}
}
@action.bound
previousPage(event?: any): void {
if (this.value > this.minValue) {
this.value--
}
}
/**
* can do the same with delta
* so all can be configured without changing this code
* externally configurable 1st
*/
@action
setAdaptive(adaptive: boolean | string) {
this.adaptive = adaptive === true || adaptive === 'true'
}
@action
setDelta(delta: number | string) {
this.delta = parseInt(delta, 10)
}
@action
setSize(size: number | string) {
this.size = parseInt(size, 10)
this.value = this.minValue
}
setSizes(sizes: Array<number>) {
this.sizes = sizes
}
@action
setTotal(total: number | string) {
this.total = parseInt(total, 10)
}
/**
* this is so we can
*/
@computed
get start(): number {
const { value, maxValue, minValue, delta } = this
if (!this.adaptive) {
return minValue
}
const offset = value - delta
if (maxValue - value < delta) {
return maxValue - delta * 2
} else {
return offset > 0 ? value - delta : minValue
}
}
@computed
get options(): Array<number> {
const fromIndexToPlusStart = (x: any, index: number) =>
this.start + index || 0
return Array.from({ length: this.length }, fromIndexToPlusStart)
}
@computed
get length(): number {
return this.adaptive
? 1 + this.delta * 2
: this.maxValue - this.minValue + 1
}
@computed
get maxValue(): number {
return Math.ceil(this.total / this.size)
}
@computed
get isFirst(): boolean {
return this.value === this.minValue
}
@computed
get isLast(): boolean {
return this.value === this.maxValue
}
}
export { StateValues, State }
export default State