'use client' import type { KeyboardEvent } from 'react' import { Controller, type Control } from 'react-hook-form' import ConsumerFieldShell from '@/components/consumer/input/ConsumerFieldShell' import type { ConsumerInputRadius, ConsumerInputSize, ConsumerInputTone } from '@/components/consumer/input/consumerInputTypes' import { CONSUMER_FIELD_INPUT_CLASS, buildConsumerFieldWrapper, resolveConsumerTone, withConsumerFieldError, } from '@/components/consumer/input/consumerInputStyles' import { buildConsumerAmountDescription } from '@/components/consumer/input/consumerInputUtils' import { Input } from '@/components/heroui/Input' import { NumberInput } from '@/components/heroui/NumberInput' import { formatNumberInputDisplayValue } from '@/components/formElements/input/inputUtils' import { convertPersianToEnglish } from '@/helpers' import { cn } from '@/lib/cn' interface SharedProps { ariaLabel?: string autoFocus?: boolean className?: string radius: ConsumerInputRadius size: ConsumerInputSize control: Control description?: React.ReactNode direction: 'rtl' | 'ltr' disabled?: boolean englishDigitsOnly: boolean formatOptions?: Intl.NumberFormatOptions iconEnd?: React.ReactNode iconStart?: React.ReactNode inputWrapper?: string inputType?: 'text' | 'email' | 'number' | 'password' | 'tel' isClearable: boolean label?: string labelIcon?: React.ReactNode maxValue?: number minValue?: number name: string placeholder?: string readonly?: boolean required?: boolean tone?: ConsumerInputTone onBlur?: () => void onClear?: () => void onKeyDown?: (event: KeyboardEvent) => void } export function ConsumerTextField(props: SharedProps) { const tone = resolveConsumerTone('input', props.tone) const wrapper = cn( buildConsumerFieldWrapper({ radius: props.radius, size: props.size, tone, }), props.inputWrapper ) return ( { const invalid = !!error const inputWrapper = invalid ? withConsumerFieldError(wrapper) : wrapper const description = buildConsumerAmountDescription(field.value, props.label, props.description) const isTel = props.inputType === 'tel' const canClear = props.isClearable && !props.readonly && props.inputType !== 'password' && !isTel const isRtlLayout = props.direction === 'rtl' && !isTel return ( { field.onBlur() props.onBlur?.() }} onChange={(event) => { let value = event.target.value if (props.englishDigitsOnly || isTel) value = convertPersianToEnglish(value).replace(/\D/g, '') else if (props.inputType === 'number') value = String(Number(value)) field.onChange(value) }} onKeyDown={props.onKeyDown} {...(canClear ? { onClear: () => { if (props.onClear) props.onClear() else field.onChange('') }, } : {})} /> ) }} /> ) } export function ConsumerNumberField(props: SharedProps) { const tone = resolveConsumerTone('numberInput', props.tone) const wrapper = cn( buildConsumerFieldWrapper({ radius: props.radius, size: props.size, tone, }), props.inputWrapper ) return ( { const invalid = !!error const inputWrapper = invalid ? withConsumerFieldError(wrapper) : wrapper const description = buildConsumerAmountDescription(field.value, props.label, props.description) const { onChange, value, ...fieldRest } = field if (props.readonly) { return ( ) } return ( { if (props.onClear) props.onClear() else onChange(undefined) }, } : {})} onValueChange={onChange} /> ) }} /> ) }