Skip to content

Commit

Permalink
✨ Use react-number-format
Browse files Browse the repository at this point in the history
  • Loading branch information
bjlaa committed Aug 29, 2024
1 parent 9404852 commit e853c21
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 45 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"react-hook-form": "^7.51.2",
"react-i18next": "^14.0.5",
"react-modal": "^3.16.1",
"react-number-format": "^5.4.1",
"react-select": "^5.8.0",
"react-toastify": "^10.0.5",
"react-tooltip": "^5.26.3",
Expand Down
66 changes: 21 additions & 45 deletions src/components/form/question/NumberInput.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use client'

import Trans from '@/components/translation/Trans'
import { useLocale } from '@/hooks/useLocale'
import { HTMLAttributes, useCallback, useEffect, useState } from 'react'
import { forwardRef, HTMLAttributes } from 'react'
import { DebounceInput } from 'react-debounce-input'
import { NumericFormat } from 'react-number-format'
import { twMerge } from 'tailwind-merge'

type Props = {
Expand All @@ -14,77 +12,55 @@ type Props = {
min?: number
id?: string
className?: string
defaultValue?: string | number | null | undefined
}

forwardRef(function DebouncedInputWithForwardRef(
props: React.ComponentProps<typeof DebounceInput>,
ref: React.ForwardedRef<HTMLInputElement>
) {
return <DebounceInput type="number" {...props} inputRef={ref} />
})

export default function NumberInput({
unit,
value = '',
isMissing,
setValue,
min = 0,
className,
id,
...props
}: HTMLAttributes<HTMLInputElement> & Props) {
const [formattedValue, setFormattedValue] = useState('')

const locale = useLocale()

const formatNumberWithSpaces = useCallback(
(number: number) => {
return new Intl.NumberFormat(locale, {
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}).format(number)
},
[locale]
)

const unformatNumber = (formattedNumber: string) => {
return Number(formattedNumber.replace(/\s+/g, '').replace(/,/g, '.'))
}

const handleValueChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const inputValue = event.target.value

if (inputValue === '') {
setValue(undefined)
} else {
setValue(unformatNumber(inputValue.replace(/[^0-9.-]+/g, '')))
setValue(unformatNumber(inputValue))
}
}

useEffect(() => {
setFormattedValue(
formatNumberWithSpaces(Number(`${value}`.replace(/\s+/g, '')))
)
}, [value, formatNumberWithSpaces])

const handleInput = (event: React.FormEvent<HTMLInputElement>) => {
const inputValue = (event.target as HTMLInputElement).value

if (inputValue === '') {
setValue(undefined)
} else {
setValue(unformatNumber(inputValue))
}
function unformatNumber(number: string) {
// Supprimer les séparateurs de milliers
return Number(number.replace(/[^0-9.-]+/g, ''))
}

return (
<div
className={twMerge(`flex items-center justify-start gap-1`, className)}>
<DebounceInput
debounceTimeout={300}
<NumericFormat
value={isMissing ? '' : value}
placeholder={isMissing ? '0' : ''}
className={`focus:ring-primary max-w-[8rem] rounded-xl border-2 border-primary-200 bg-white p-2 text-right transition-colors focus:border-primary-700 focus:ring-2 md:max-w-full`}
inputMode="numeric"
min={min}
value={isMissing ? '' : formattedValue}
placeholder={isMissing ? formattedValue ?? '0' : '0'}
customInput={DebounceInput}
thousandSeparator={' '}
allowNegative={false}
onChange={handleValueChange}
onInput={handleInput}
id={id}
{...props}
/>

{unit ? (
<span className="whitespace-nowrap">
&nbsp;
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8735,6 +8735,11 @@ react-move@^2.7.0:
prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4"

react-number-format@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.1.tgz#ca191af06c4618a823874efa486df50a1abbfc18"
integrity sha512-NICOjo/70dcAiwVmH6zMWoZrTQDlBrEXV/f7S0t/ewlpzp4z00pasg5G1yBX6NHLafwOF3QZ+VvK/XApwSKxdA==

react-select@^5.8.0:
version "5.8.0"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.8.0.tgz#bd5c467a4df223f079dd720be9498076a3f085b5"
Expand Down

0 comments on commit e853c21

Please sign in to comment.