Skip to content

Commit

Permalink
[frontend] feat: number input (#55)
Browse files Browse the repository at this point in the history
- Added a `NumberInput` component with formatting,
- Removed the default value of `10,000,000,000` of the inital supply &
set as a placeholder.

@0xChqrles Let me know if I should it differently!
  • Loading branch information
akhercha authored Dec 14, 2023
1 parent f1d401a commit a91eef6
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
60 changes: 60 additions & 0 deletions frontend/src/components/NumberInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import clsx from 'clsx'
import React, { forwardRef, useEffect, useState } from 'react'
import Box, { BoxProps } from 'src/theme/components/Box'

import * as styles from './style.css'

const formatNumber = (value: string) => {
const numericValue = parseFloat(value.replace(/[^0-9.]/g, ''))
if (isNaN(numericValue)) return ''

return new Intl.NumberFormat('en-US', {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}).format(numericValue)
}

type NumberInputProps = {
addon?: React.ReactNode
} & BoxProps

const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(
({ addon, className, value, onChange, onBlur, ...props }, ref) => {
const [inputValue, setInputValue] = useState('')
useEffect(() => {
if (value !== undefined && value !== null) {
setInputValue(formatNumber(value.toString()))
}
}, [value])

const handleInputEvent = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value.replace(/[^0-9.]/g, ''))
onChange && onChange(event)
}
const handleBlurEvent = (event: React.FocusEvent<HTMLInputElement>) => {
setInputValue(formatNumber(event.target.value))
onBlur && onBlur(event)
}

return (
<Box className={clsx(styles.inputContainer, className)}>
{addon}
<Box
as="input"
type="text"
{...props}
ref={ref}
className={styles.input}
value={inputValue}
onChange={handleInputEvent}
onBlur={handleBlurEvent}
/>
</Box>
)
}
)

NumberInput.displayName = 'NumberInput'

export default NumberInput
33 changes: 33 additions & 0 deletions frontend/src/components/NumberInput/style.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { sprinkles } from 'src/theme/css/sprinkles.css'

export const inputContainer = sprinkles({
display: 'flex',
alignItems: 'center',
borderRadius: '10',
borderWidth: '1px',
borderStyle: 'solid',
overflow: 'hidden',
padding: '12',
fontSize: '16',
borderColor: {
default: 'border1',
hover: 'accent',
},
gap: '8',
transitionDuration: '125',
backgroundColor: 'bg1',
})

export const input = sprinkles({
fontSize: '16',
position: 'relative',
whiteSpace: 'nowrap',
outline: 'none',
color: {
default: 'text1',
placeholder: 'text2',
},
background: 'none',
border: 'none',
width: 'full',
})
6 changes: 3 additions & 3 deletions frontend/src/pages/Launch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useCallback, useState } from 'react'
import { useFieldArray, useForm } from 'react-hook-form'
import { IconButton, PrimaryButton, SecondaryButton } from 'src/components/Button'
import Input from 'src/components/Input'
import NumberInput from 'src/components/NumberInput'
import { TOKEN_CLASS_HASH, UDC } from 'src/constants/contracts'
import Box from 'src/theme/components/Box'
import { Column, Row } from 'src/theme/components/Flex'
Expand Down Expand Up @@ -35,7 +36,7 @@ const schema = z.object({
symbol: z.string().min(1),
initialRecipientAddress: address,
ownerAddress: address,
initialSupply: z.number().min(0),
initialSupply: z.number().min(1),
holders: z.array(holder),
})

Expand All @@ -60,7 +61,6 @@ export default function LaunchPage() {
reset: resetForm,
} = useForm<z.infer<typeof schema>>({
resolver: zodResolver(schema),
defaultValues: { initialSupply: 10_000_000_000 },
})

const { fields, append, remove } = useFieldArray({
Expand Down Expand Up @@ -181,7 +181,7 @@ export default function LaunchPage() {

<Column gap="4">
<Text.Body className={styles.inputLabel}>Initial Supply</Text.Body>
<Input {...register('initialSupply', { valueAsNumber: true })} />
<NumberInput placeholder="10,000,000,000.00" {...register('initialSupply', { valueAsNumber: true })} />
<Box className={styles.errorContainer}>
{errors.initialSupply?.message ? <Text.Error>{errors.initialSupply.message}</Text.Error> : null}
</Box>
Expand Down

0 comments on commit a91eef6

Please sign in to comment.