-
-
Notifications
You must be signed in to change notification settings - Fork 478
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(console): implement environment variables input field (1/2) (#…
…5471) * refactor(console): extract the KeyValueInput ds component extract the KeyValueInput ds component * fix(console): remove unused styles remove unused styles * refactor(console): extract the FormField from KeyValueInput extract the FormField from KeyValueInput * fix(console): refactor some code based on code review comment refactor some code based the code review comment
- Loading branch information
Showing
4 changed files
with
178 additions
and
84 deletions.
There are no files selected for viewing
File renamed without changes.
118 changes: 118 additions & 0 deletions
118
packages/console/src/ds-components/KeyValueInputField/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { type FieldError } from 'react-hook-form'; | ||
|
||
import CirclePlus from '@/assets/icons/circle-plus.svg'; | ||
import Minus from '@/assets/icons/minus.svg'; | ||
import Button from '@/ds-components/Button'; | ||
import IconButton from '@/ds-components/IconButton'; | ||
import TextInput, { type Props as TextInputProps } from '@/ds-components/TextInput'; | ||
|
||
import * as styles from './index.module.scss'; | ||
|
||
type FieldType = { | ||
key: string; | ||
value: string; | ||
}; | ||
|
||
type ErrorType = { | ||
[K in keyof FieldType]?: FieldError | string | undefined; | ||
}; | ||
|
||
// TextInput props getter | ||
type InputFieldPropsGetter = { | ||
[K in keyof FieldType]: (index: number) => Omit<TextInputProps, 'ref'>; | ||
}; | ||
|
||
type ErrorProps = { | ||
error?: FieldError | string | undefined; | ||
}; | ||
function Error({ error }: ErrorProps) { | ||
if (!error) { | ||
return null; | ||
} | ||
|
||
if (typeof error === 'string') { | ||
return <div className={styles.error}>{error}</div>; | ||
} | ||
|
||
return <div className={styles.error}>{error.message}</div>; | ||
} | ||
|
||
type Props = { | ||
className?: string; | ||
fields: Array<FieldType & { id: string }>; // Id is required to uniquely identify each field | ||
errors?: Array<ErrorType | undefined>; | ||
getInputFieldProps: InputFieldPropsGetter; | ||
onRemove: (index: number) => void; | ||
onAppend: (field: FieldType) => void; | ||
}; | ||
|
||
/** | ||
* UI component for key-value input field. | ||
* | ||
* This component is used to add multiple key-value pairs. | ||
* For most of the cases, it is designed to be used along with react-hook-form. | ||
* All the input properties are registered with react-hook-form. | ||
* @param {Props} props - The props for the component. | ||
* @param {string} [props.className] - The class name for the container. | ||
* @param {FieldType} props.fields - The array of key-value pairs. @see {@link https://react-hook-form.com/docs/usefieldarray} | ||
* @param {ErrorType[]} [props.errors] - The array of errors for each field. Accepts both string and FieldError from RHF. | ||
* @param {Function} props.onRemove - The function to remove a field. @see {@link https://react-hook-form.com/docs/usefieldarray} | ||
* @param {Function} props.onAppend - The function to append a new field. @see {@link https://react-hook-form.com/docs/usefieldarray} | ||
* @param {InputFieldPropsGetter} getInputFieldProps - The function bundle to get the input field props for each field. e.g. Use React Hook Form's register method to register the input field. | ||
*/ | ||
function KeyValueInputField({ | ||
className, | ||
fields, | ||
errors, | ||
getInputFieldProps, | ||
onRemove, | ||
onAppend, | ||
}: Props) { | ||
return ( | ||
<div className={className}> | ||
{fields.map((field, index) => { | ||
return ( | ||
// Use id as the element key if it exists (generated by react-hook-form useFieldArray method), otherwise use the key | ||
<div key={field.id} className={styles.field}> | ||
<div className={styles.input}> | ||
<TextInput | ||
className={styles.keyInput} | ||
placeholder="Key" | ||
error={Boolean(errors?.[index]?.key)} | ||
{...getInputFieldProps.key(index)} | ||
/> | ||
<TextInput | ||
className={styles.valueInput} | ||
placeholder="Value" | ||
error={Boolean(errors?.[index]?.value)} | ||
{...getInputFieldProps.value(index)} | ||
/> | ||
{fields.length > 1 && ( | ||
<IconButton | ||
onClick={() => { | ||
onRemove(index); | ||
}} | ||
> | ||
<Minus /> | ||
</IconButton> | ||
)} | ||
</div> | ||
<Error error={errors?.[index]?.key} /> | ||
<Error error={errors?.[index]?.value} /> | ||
</div> | ||
); | ||
})} | ||
<Button | ||
size="small" | ||
type="text" | ||
title="general.add_another" | ||
icon={<CirclePlus />} | ||
onClick={() => { | ||
onAppend({ key: '', value: '' }); | ||
}} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
export default KeyValueInputField; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters