/
Machine.tsx
63 lines (57 loc) · 1.75 KB
/
Machine.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import React, { useState, forwardRef, useMemo, useEffect } from 'react';
import { isString, isDef, usePrevious } from '@mantine/utils';
import { MachineNumber } from './MachineNumber';
import useStyles from './Machine.styles';
interface MachineNumberProps {
value: number | string;
max: number;
}
export const Machine = forwardRef<HTMLDivElement, MachineNumberProps>(({ value = 0, max }, ref) => {
const [oldValue, setOldValue] = useState<number>();
const [newValue, setNewValue] = useState<number>();
const prevValueRef = usePrevious(value);
useEffect(() => {
if (isString(value)) {
setOldValue(undefined);
setNewValue(undefined);
} else if (isString(prevValueRef)) {
setOldValue(undefined);
setNewValue(value);
} else {
setOldValue(prevValueRef);
setNewValue(value);
}
}, [value, prevValueRef]);
const numbers = useMemo(() => {
if (isString(value)) return [];
if (value < 1) return [0];
const result: number[] = [];
let currentValue = value;
if (isDef(max)) {
currentValue = Math.min(max, currentValue);
}
while (currentValue >= 1) {
result.push(currentValue % 10);
currentValue /= 10;
currentValue = Math.floor(currentValue);
}
result.reverse();
return result;
}, [value, max]);
const { classes } = useStyles(null, { name: 'machine' });
return isString(value) ? (
<span ref={ref}>{value}</span>
) : (
<span ref={ref} className={classes.base}>
{numbers.map((number, i) => (
<MachineNumber
key={numbers.length - i - 1}
value={number}
oldOriginalNumber={oldValue}
newOriginalNumber={newValue}
/>
))}
{isDef(max) && value > max && <span>+</span>}
</span>
);
});