InputField.tsx 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import { InputVariants } from '@ui/components/shadcn/ui/input'
  2. import { HelpCircle } from 'lucide-react'
  3. import Link from 'next/link'
  4. import type { Control, FieldPath, FieldValues } from 'react-hook-form'
  5. import { cn, FormControl, FormField, Input, Textarea } from 'ui'
  6. import { Input as PasswordInput } from 'ui-patterns/DataInputs/Input'
  7. import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
  8. import type { ServerOption } from './Wrappers.types'
  9. interface InputFieldProps<TFieldValues extends FieldValues = FieldValues> {
  10. option: ServerOption
  11. control: Control<TFieldValues>
  12. loading?: boolean
  13. }
  14. const InputField = <
  15. TFieldValues extends FieldValues = FieldValues,
  16. TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
  17. >({
  18. control,
  19. option,
  20. loading = false,
  21. }: InputFieldProps<TFieldValues>) => {
  22. return (
  23. <FormField
  24. control={control}
  25. name={option.name as TName}
  26. defaultValue={(option.defaultValue ?? '') as any}
  27. render={({ field }) => (
  28. <FormItemLayout
  29. name={option.name}
  30. layout="vertical"
  31. label={
  32. <div className="flex items-center space-x-2">
  33. <p>{option.label}</p>
  34. {option.urlHelper !== undefined && (
  35. <Link href={option.urlHelper} target="_blank" rel="noreferrer">
  36. <span className="sr-only">Documentation</span>
  37. <HelpCircle
  38. strokeWidth={2}
  39. size={14}
  40. className="text-foreground-light hover:text-foreground cursor-pointer transition"
  41. />
  42. </Link>
  43. )}
  44. </div>
  45. }
  46. labelOptional={!option.required ? 'Optional' : undefined}
  47. description={option.description}
  48. >
  49. <FormControl>
  50. {loading ? (
  51. <span className={cn(InputVariants({ size: 'small' }))}>
  52. Fetching value from Vault...
  53. </span>
  54. ) : option.isTextArea ? (
  55. <Textarea {...field} id={option.name} rows={6} className="input-mono resize-none" />
  56. ) : option.secureEntry ? (
  57. <PasswordInput copy reveal {...field} id={option.name} />
  58. ) : (
  59. <Input {...field} id={option.name} />
  60. )}
  61. </FormControl>
  62. </FormItemLayout>
  63. )}
  64. />
  65. )
  66. }
  67. export default InputField