2025-12-23 02:20:57 +01:00

125 lines
2.6 KiB
TypeScript

import React from 'react'
interface ArticleFieldProps {
id: string
label: string
value: string | number
onChange: (value: string | number) => void
required?: boolean
type?: 'text' | 'textarea' | 'number'
rows?: number
placeholder?: string
helpText?: string
min?: number
}
function NumberOrTextInput({
id,
type,
value,
placeholder,
required,
min,
onChange,
className,
}: {
id: string
type: 'text' | 'number'
value: string | number
placeholder?: string
required: boolean
min?: number
className: string
onChange: (value: string | number) => void
}) {
const inputProps = {
id,
type,
value,
className,
required,
...(placeholder ? { placeholder } : {}),
...(typeof min === 'number' ? { min } : {}),
}
return (
<input
{...inputProps}
onChange={(e) => onChange(type === 'number' ? Number(e.target.value) || 0 : e.target.value)}
/>
)
}
function TextAreaInput({
id,
value,
placeholder,
required,
rows,
className,
onChange,
}: {
id: string
value: string | number
placeholder?: string
required: boolean
rows?: number
className: string
onChange: (value: string | number) => void
}) {
const areaProps = {
id,
value,
className,
required,
...(placeholder ? { placeholder } : {}),
...(rows ? { rows } : {}),
}
return (
<textarea
{...areaProps}
onChange={(e) => onChange(e.target.value)}
/>
)
}
export function ArticleField(props: ArticleFieldProps) {
const { id, label, value, onChange, required = false, type = 'text', rows, placeholder, helpText, min } =
props
const inputClass =
'w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500'
const input =
type === 'textarea' ? (
<TextAreaInput
id={id}
value={value}
required={required}
className={inputClass}
onChange={onChange}
{...(placeholder ? { placeholder } : {})}
{...(rows ? { rows } : {})}
/>
) : (
<NumberOrTextInput
id={id}
type={type}
value={value}
required={required}
className={inputClass}
onChange={onChange}
{...(placeholder ? { placeholder } : {})}
{...(typeof min === 'number' ? { min } : {})}
/>
)
return (
<div>
<label htmlFor={id} className="block text-sm font-medium text-gray-700 mb-1">
{label} {required && '*'}
</label>
{input}
{helpText && <p className="text-xs text-gray-500 mt-1">{helpText}</p>}
</div>
)
}