Skip to content

Commit 4603fa1

Browse files
AYS-480 | NumericInput Component Has Been Created and Used In Emergency Evacuation Application Form (#97)
Co-authored-by: Buğra Ercan <bugrasshgercan@gmail.com>
1 parent 102c0de commit 4603fa1

File tree

6 files changed

+65
-20
lines changed

6 files changed

+65
-20
lines changed

package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/EmergencyForm/EvacuationForm.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import PhoneInput from '@/components/ui/PhoneInput'
1313
import { Textarea } from '@/components/ui/textarea'
1414
import { UseFormReturn } from 'react-hook-form'
1515
import { CountryData } from 'react-phone-input-2'
16+
import { NumericInput } from '@/components/NumericInput'
1617

1718
interface EvacuationFormSchema {
1819
firstName: string
@@ -95,20 +96,13 @@ const EvacuationForm: React.FC<EvacuationFormProps> = ({ form }) => {
9596
>
9697
Talep Edilen Koltuk Sayısı:
9798
</Label>
98-
<Input
99-
id="seatingCount"
99+
<NumericInput
100+
id={field.name}
101+
value={field.value}
102+
onValueChange={field.onChange}
103+
onBlur={field.onBlur}
104+
maxLength={3}
100105
placeholder="Talep Edilen Koltuk Sayısı"
101-
type="number"
102-
onWheel={(e: React.WheelEvent<HTMLInputElement>) =>
103-
e.currentTarget.blur()
104-
}
105-
{...field}
106-
onChange={(e) => {
107-
const value = e.target.valueAsNumber
108-
if (value <= 999 && value > -1) {
109-
field.onChange(value)
110-
}
111-
}}
112106
/>
113107
</div>
114108
</FormControl>

src/components/EmergencyForm/ProxyEvacuationForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default function ProxyEvacuationForm(): JSX.Element {
3737
applicantPhoneNumber: { countryCode: '90', lineNumber: '' },
3838
firstName: '',
3939
lastName: '',
40-
seatingCount: 1,
40+
seatingCount: 0,
4141
phoneNumber: { countryCode: '90', lineNumber: '' },
4242
sourceCity: '',
4343
sourceDistrict: '',

src/components/EmergencyForm/SelfEvacuationForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function SelfEvacuationForm(): JSX.Element {
2222
defaultValues: {
2323
firstName: '',
2424
lastName: '',
25-
seatingCount: 1,
25+
seatingCount: 0,
2626
phoneNumber: { countryCode: '90', lineNumber: '' },
2727
sourceCity: '',
2828
sourceDistrict: '',

src/components/EmergencyForm/schema/formSchema.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ const formSchema = z.object({
8181
.max(250, { message: 'Maksimum 250 karakter uzunluğunda olabilir' }),
8282
seatingCount: z
8383
.number({ message: 'Koltuk sayısı belirtmelisin' })
84-
.int({ message: 'Pozitif bir tam sayı olmalıdır' })
85-
.positive({ message: 'Pozitif bir tam sayı olmalıdır' })
84+
.positive({ message: 'Koltuk sayısı belirtmelisin' })
8685
.max(999, { message: 'Maksimum 3 haneli bir sayı olmalıdır' }),
8786
targetCity: requiredFieldValidation(),
8887
targetDistrict: requiredFieldValidation(),

src/components/NumericInput.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import * as React from 'react'
2+
import { Input } from '@/components/ui/input'
3+
4+
type BaseInputProps = React.ComponentPropsWithoutRef<typeof Input>
5+
6+
export interface NumericInputProps
7+
extends Omit<BaseInputProps, 'type' | 'value' | 'onChange'> {
8+
maxLength?: number
9+
value?: number | ''
10+
onValueChange?: (value?: number) => void
11+
}
12+
13+
export const NumericInput = React.forwardRef<
14+
HTMLInputElement,
15+
NumericInputProps
16+
>(function NumericInput(
17+
{ maxLength = 3, value = '', onValueChange, onKeyDown, onBlur, ...rest },
18+
ref
19+
) {
20+
const handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {
21+
if (['e', 'E', '+', '-', '.', ','].includes(e.key)) {
22+
e.preventDefault()
23+
return
24+
}
25+
onKeyDown?.(e)
26+
}
27+
28+
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
29+
const digits = e.target.value.replace(/\D/g, '')
30+
if (digits.length <= maxLength) {
31+
const num = digits === '' ? undefined : parseInt(digits, 10)
32+
onValueChange?.(num)
33+
}
34+
}
35+
36+
return (
37+
<Input
38+
{...rest}
39+
ref={ref}
40+
type="text"
41+
inputMode="numeric"
42+
pattern="[0-9]*"
43+
value={value ?? ''}
44+
onKeyDown={handleKeyDown}
45+
onChange={handleChange}
46+
onBlur={onBlur}
47+
/>
48+
)
49+
})
50+
51+
NumericInput.displayName = 'NumericInput'

0 commit comments

Comments
 (0)