@xyo-network/react-shared 4.4.5 → 4.4.7

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,108 @@
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
+ defaultFixedPoint?: number
15
+ hideAdornment?: boolean
16
+ onChangeFixedPoint?: (value: bigint) => void
17
+ }
18
+
19
+ export const BigIntTextField: React.FC<BigIntTextFieldProps> = ({
20
+ defaultFixedPoint = 18, helperText, hideAdornment, onChangeFixedPoint, onChange, ...props
21
+ }) => {
22
+ const [value, setValue] = useState<number>(0)
23
+ const [rawValue, setRawValue] = useState<string>('')
24
+ const [fixedPoint, setFixedPoint] = useState(defaultFixedPoint)
25
+ const [error, setError] = useState<Error>()
26
+
27
+ const handleChange: FocusEventHandler<HTMLTextAreaElement> = (event) => {
28
+ // run standard callback
29
+ onChange?.(event)
30
+ // remove all alpha characters but allow decimals
31
+ const filteredValue = event.target.value.replaceAll(/[^\d.]/g, '')
32
+ // only allow one decimal point
33
+ if (filteredValue.split('.').length > 2) return
34
+ setRawValue(filteredValue)
35
+
36
+ // parse the raw filtered raw value
37
+ const value = Number.parseFloat(filteredValue || '0')
38
+ // if the value is NaN set it to 0
39
+ if (Number.isNaN(value)) setValue(0)
40
+ setValue(value)
41
+ }
42
+
43
+ const onFixedPointChange = (fixedPoint: number) => setFixedPoint(fixedPoint)
44
+
45
+ // on value or point changes, run the bigInt callback
46
+ const bigIntValue = useMemo(() => {
47
+ const fixedValue = value * (10 ** fixedPoint)
48
+ setError(undefined)
49
+ try {
50
+ return BigInt(fixedValue)
51
+ } catch (e) {
52
+ console.error(e)
53
+ setError(e as Error)
54
+ }
55
+ // run bigInt callback
56
+ }, [value, fixedPoint])
57
+
58
+ useEffect(() => {
59
+ if (bigIntValue) onChangeFixedPoint?.(bigIntValue)
60
+ }, [bigIntValue])
61
+
62
+ // prevent the fixed point from being less than the number of decimal places
63
+ const minFixedPoint = rawValue.split('.')[1]?.length
64
+
65
+ const resolvedHelperText = useMemo(() => {
66
+ if (error) return 'Cannot convert to BigInt'
67
+ return helperText ?? 'Enter a number'
68
+ }, [helperText, error])
69
+
70
+ return (
71
+ <>
72
+ <TextField
73
+ onChange={handleChange}
74
+ type="string"
75
+ error={Boolean(error)}
76
+ slotProps={{
77
+ htmlInput: { pattern: '[0-9]*[.]?[0-9]*' },
78
+ input: {
79
+ startAdornment: (hideAdornment
80
+ ? null
81
+ : (
82
+ <FixedPointInputAdornment
83
+ position="start"
84
+ fixedPoint={fixedPoint}
85
+ minFixedPoint={minFixedPoint}
86
+ onFixedPointChange={onFixedPointChange}
87
+ />
88
+ )
89
+ ),
90
+ },
91
+ }}
92
+ value={rawValue}
93
+ {...props}
94
+ />
95
+ <FormHelperText>{resolvedHelperText}</FormHelperText>
96
+ </>
97
+ )
98
+ }
99
+
100
+ export interface InputWithFormControlProps extends FormControlProps {
101
+ textFieldProps?: BigIntTextFieldProps
102
+ }
103
+
104
+ export const WithFormControl: React.FC<InputWithFormControlProps> = ({ textFieldProps, ...props }) => (
105
+ <FormControl {...props}>
106
+ <BigIntTextField {...textFieldProps} />
107
+ </FormControl>
108
+ )
@@ -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'