Files
supabase/apps/studio/components/interfaces/Integrations/Wrappers/InputField.tsx
T
Gildas Garcia 914677ed4b chore: migrate foreign wrapper forms to react-hook-form (#44512)
## Problem

Foreign wrapper forms still use `formik` but we now use
`react-hook-form` everywhere and we'd like to reduce our dependencies.

## Solution

- [x] Write e2e tests for wrappers
- [x] Migrate to `react-hook-form`

## Notes

I tried to cover the 3 cases I identified for foreign wrappers with e2e
tests:
- Add all available tables to a new schema (stripe)
- Add selected tables to a new table (stripe)
- Create dynamic columns (s3 wrapper)

However, they are not exhaustive as I can't test the integration
actually works, only that it was created successfully. Besides, I can't
test the Iceberg wrapper case as it needs actual S3 buckets.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced column-type selector with searchable combobox, enum support,
icons, and optional recommendation prompts.

* **Refactor**
* Migrated many wrapper/table/editor forms to a schema-driven form
system with stronger validation, dynamic field arrays, and consistent
form controls.
* Updated input field integration to work with the new form control
model.

* **Bug Fixes**
* Improved handling of missing wrapper/error states during wrapper
loading.

* **Tests**
* Added unit tests for form schemas and end-to-end tests for wrapper
creation flows.

* **Chores**
  * Removed legacy dynamic-columns component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-09 09:20:27 +02:00

65 lines
2.2 KiB
TypeScript

import { InputVariants } from '@ui/components/shadcn/ui/input'
import { HelpCircle } from 'lucide-react'
import Link from 'next/link'
import type { Control } from 'react-hook-form'
import { cn, FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_, Textarea } from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import type { ServerOption } from './Wrappers.types'
interface InputFieldProps {
option: ServerOption
control: Control<any>
loading?: boolean
}
const InputField = ({ control, option, loading = false }: InputFieldProps) => {
return (
<FormField_Shadcn_
control={control}
name={option.name}
defaultValue={option.defaultValue ?? ''}
render={({ field }) => (
<FormItemLayout
name={option.name}
layout="vertical"
label={
<div className="flex items-center space-x-2">
<p>{option.label}</p>
{option.urlHelper !== undefined && (
<Link href={option.urlHelper} target="_blank" rel="noreferrer">
<span className="sr-only">Documentation</span>
<HelpCircle
strokeWidth={2}
size={14}
className="text-foreground-light hover:text-foreground cursor-pointer transition"
/>
</Link>
)}
</div>
}
labelOptional={!option.required ? 'Optional' : undefined}
description={option.description}
>
<FormControl_Shadcn_>
{loading ? (
<span className={cn(InputVariants({ size: 'small' }))}>
Fetching value from Vault...
</span>
) : option.isTextArea ? (
<Textarea {...field} id={option.name} rows={6} className="input-mono resize-none" />
) : option.secureEntry ? (
<Input copy reveal {...field} id={option.name} />
) : (
<Input_Shadcn_ {...field} id={option.name} />
)}
</FormControl_Shadcn_>
</FormItemLayout>
)}
/>
)
}
export default InputField