dify/web/app/components/base/form/components/field/number-input.tsx
yyh 3db1ba36e0
refactor(web): number inputs to use Base UI NumberField (#33539)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-03-17 18:45:02 +08:00

93 lines
2.4 KiB
TypeScript

import type { ReactNode } from 'react'
import type { NumberFieldInputProps, NumberFieldRootProps, NumberFieldSize } from '../../../ui/number-field'
import type { LabelProps } from '../label'
import * as React from 'react'
import { cn } from '@/utils/classnames'
import { useFieldContext } from '../..'
import {
NumberField,
NumberFieldControls,
NumberFieldDecrement,
NumberFieldGroup,
NumberFieldIncrement,
NumberFieldInput,
NumberFieldUnit,
} from '../../../ui/number-field'
import Label from '../label'
type NumberInputFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
inputClassName?: string
unit?: ReactNode
size?: NumberFieldSize
} & Omit<NumberFieldRootProps, 'children' | 'className' | 'id' | 'value' | 'defaultValue' | 'onValueChange'> & Omit<NumberFieldInputProps, 'children' | 'size' | 'onBlur' | 'className' | 'onChange'>
const NumberInputField = ({
label,
labelOptions,
className,
inputClassName,
unit,
size = 'regular',
...props
}: NumberInputFieldProps) => {
const field = useFieldContext<number>()
const {
value: _value,
min,
max,
step,
disabled,
readOnly,
required,
name: _name,
id: _id,
...inputProps
} = props
const emptyValue = min ?? 0
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<NumberField
id={field.name}
name={field.name}
value={field.state.value}
min={min}
max={max}
step={step}
disabled={disabled}
readOnly={readOnly}
required={required}
onValueChange={value => field.handleChange(value ?? emptyValue)}
>
<NumberFieldGroup size={size}>
<NumberFieldInput
{...inputProps}
size={size}
className={inputClassName}
onBlur={field.handleBlur}
/>
{Boolean(unit) && (
<NumberFieldUnit size={size}>
{unit}
</NumberFieldUnit>
)}
<NumberFieldControls>
<NumberFieldIncrement size={size} />
<NumberFieldDecrement size={size} />
</NumberFieldControls>
</NumberFieldGroup>
</NumberField>
</div>
)
}
export default NumberInputField