Files
Joshen Lim 09a1f431bc Mass update for all lucide icon imports to use the component with Icon suffix (#51659)
## Context

This is largely just a mechanical change here:
Opting to use lucide icons with the `Icon` suffix across all icon
imports within `studio`
- so that it’s clearer which components are icons + reduces the
possibility of name collision with our own components
- e.g <User /> vs <UserIcon />

Also added a eslint rule for this:
<img width="1069" height="167" alt="image"
src="https://github.com/user-attachments/assets/7f36f443-5ca2-4bf6-8d22-86e774513bfc"
/>

And updated `AGENTS.md` as such:
```
Icons come from `lucide-react`, always imported with the `Icon` suffix (`import { CheckIcon, Trash2Icon } from 'lucide-react'`) — never the bare names (`Check`) or `Check as CheckIcon` aliases (lint-enforced).
```
2026-10-14 12:56:55 +02:00

72 lines
2.4 KiB
TypeScript

import { HelpCircleIcon } from 'lucide-react'
import Link from 'next/link'
import type { Control, FieldPath, FieldValues } from 'react-hook-form'
import { cn, FormControl, FormField, Input, InputVariants, Textarea } from 'ui'
import { Input as PasswordInput } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import type { ServerOption } from './Wrappers.types'
interface InputFieldProps<TFieldValues extends FieldValues = FieldValues> {
option: ServerOption
control: Control<TFieldValues>
loading?: boolean
placeholder?: string
layout?: 'vertical' | 'horizontal'
}
export const InputField = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
>({
control,
option,
loading = false,
layout = 'horizontal',
placeholder,
}: InputFieldProps<TFieldValues>) => {
return (
<FormField
control={control}
name={option.name as TName}
defaultValue={(option.defaultValue ?? '') as any}
render={({ field }) => (
<FormItemLayout
layout={layout}
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>
<HelpCircleIcon
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>
{loading ? (
<span className={cn(InputVariants({ size: 'small' }))}>
Fetching value from Vault...
</span>
) : option.isTextArea ? (
<Textarea {...field} rows={6} className="input-mono resize-none" />
) : option.secureEntry ? (
<PasswordInput copy reveal {...field} />
) : (
<Input {...field} placeholder={placeholder} />
)}
</FormControl>
</FormItemLayout>
)}
/>
)
}