@xyo-network/react-shared 4.4.5 → 4.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,103 @@
1
+ import type { FormControlProps, StandardTextFieldProps } from '@mui/material'
2
+ import {
3
+ FormControl, FormHelperText, TextField,
4
+ } from '@mui/material'
5
+ import type { FocusEventHandler } from 'react'
6
+ import React, {
7
+ useEffect, useMemo,
8
+ useState,
9
+ } from 'react'
10
+
11
+ import { FixedPointInputAdornment } from './InputAdornment.tsx'
12
+
13
+ export interface BigIntTextFieldProps extends StandardTextFieldProps {
14
+ onChangeFixedPoint?: (value: bigint) => void
15
+ }
16
+
17
+ export const BigIntTextField: React.FC<BigIntTextFieldProps> = ({
18
+ helperText, onChangeFixedPoint, onChange, ...props
19
+ }) => {
20
+ const [value, setValue] = useState<number>(0)
21
+ const [rawValue, setRawValue] = useState<string>('')
22
+ const [fixedPoint, setFixedPoint] = useState(18)
23
+ const [error, setError] = useState<Error>()
24
+
25
+ const handleChange: FocusEventHandler<HTMLTextAreaElement> = (event) => {
26
+ // run standard callback
27
+ onChange?.(event)
28
+ // remove all alpha characters but allow decimals
29
+ const filteredValue = event.target.value.replaceAll(/[^\d.]/g, '')
30
+ // only allow one decimal point
31
+ if (filteredValue.split('.').length > 2) return
32
+ setRawValue(filteredValue)
33
+
34
+ // parse the raw filtered raw value
35
+ const value = Number.parseFloat(filteredValue || '0')
36
+ // if the value is NaN set it to 0
37
+ if (Number.isNaN(value)) setValue(0)
38
+ setValue(value)
39
+ }
40
+
41
+ const onFixedPointChange = (fixedPoint: number) => setFixedPoint(fixedPoint)
42
+
43
+ // on value or point changes, run the bigInt callback
44
+ const bigIntValue = useMemo(() => {
45
+ const fixedValue = value * (10 ** fixedPoint)
46
+ setError(undefined)
47
+ try {
48
+ return BigInt(fixedValue)
49
+ } catch (e) {
50
+ console.error(e)
51
+ setError(e as Error)
52
+ }
53
+ // run bigInt callback
54
+ }, [value, fixedPoint])
55
+
56
+ useEffect(() => {
57
+ if (bigIntValue) onChangeFixedPoint?.(bigIntValue)
58
+ }, [bigIntValue])
59
+
60
+ // prevent the fixed point from being less than the number of decimal places
61
+ const minFixedPoint = rawValue.split('.')[1]?.length
62
+
63
+ const resolvedHelperText = useMemo(() => {
64
+ if (error) return 'Cannot convert to BigInt'
65
+ return helperText ?? 'Enter a number'
66
+ }, [helperText, error])
67
+
68
+ return (
69
+ <>
70
+ <TextField
71
+ onChange={handleChange}
72
+ type="string"
73
+ error={Boolean(error)}
74
+ slotProps={{
75
+ htmlInput: { pattern: '[0-9]*[.]?[0-9]*' },
76
+ input: {
77
+ startAdornment: (
78
+ <FixedPointInputAdornment
79
+ position="start"
80
+ fixedPoint={fixedPoint}
81
+ minFixedPoint={minFixedPoint}
82
+ onFixedPointChange={onFixedPointChange}
83
+ />
84
+ ),
85
+ },
86
+ }}
87
+ value={rawValue}
88
+ {...props}
89
+ />
90
+ <FormHelperText>{resolvedHelperText}</FormHelperText>
91
+ </>
92
+ )
93
+ }
94
+
95
+ export interface InputWithFormControlProps extends FormControlProps {
96
+ textFieldProps?: BigIntTextFieldProps
97
+ }
98
+
99
+ export const WithFormControl: React.FC<InputWithFormControlProps> = ({ textFieldProps, ...props }) => (
100
+ <FormControl {...props}>
101
+ <BigIntTextField {...textFieldProps} />
102
+ </FormControl>
103
+ )
@@ -0,0 +1,4 @@
1
+ export * from './FixedPointPopover.tsx'
2
+ export * from './Input.ts'
3
+ export * from './InputAdornment.tsx'
4
+ export * from './TextField.tsx'
@@ -1,5 +1,6 @@
1
1
  export * from './Ampersand.tsx'
2
2
  export * from './BasicHero/index.ts'
3
+ export * from './bigint/index.ts'
3
4
  export * from './Ellipsize.tsx'
4
5
  export * from './LabeledTextFieldWrapper.tsx'
5
6
  export * from './ListItemButtonEx.tsx'