@@ -4,7 +4,7 @@ import { DeleteIcon, PlusIcon } from '@ultraviolet/icons'
44import { Button , Row , Stack } from '@ultraviolet/ui'
55import type { ComponentProps } from 'react'
66import type { Control , FieldArrayPath , FieldValues } from 'react-hook-form'
7- import { useFieldArray } from 'react-hook-form'
7+ import { useFieldArray , useFormContext } from 'react-hook-form'
88import { TextInputField } from '../TextInputField'
99
1010type InputKeyProps = {
@@ -25,6 +25,11 @@ type AddButtonProps = {
2525 maxSizeReachedTooltip ?: string
2626}
2727
28+ type KeyValuePair = {
29+ key : string
30+ value : string
31+ }
32+
2833type KeyValueFieldProps <
2934 TFieldValues extends FieldValues ,
3035 TFieldArrayName extends FieldArrayPath < TFieldValues > ,
@@ -36,6 +41,8 @@ type KeyValueFieldProps<
3641 maxSize ?: number
3742 readOnly ?: boolean
3843 control ?: Control < TFieldValues >
44+ onChange ?: ( values : KeyValuePair [ ] ) => void
45+ onBlur ?: ( values : KeyValuePair [ ] ) => void
3946}
4047
4148/**
@@ -53,12 +60,24 @@ export const KeyValueField = <
5360 maxSize = 100 ,
5461 readOnly = false ,
5562 control,
63+ onChange,
64+ onBlur,
5665} : KeyValueFieldProps < TFieldValues , TFieldArrayName > ) => {
5766 const { fields, append, remove } = useFieldArray ( {
5867 control,
5968 name,
6069 } )
6170
71+ const { getValues } = useFormContext ( )
72+
73+ const handleFieldChange = ( ) => {
74+ onChange ?.( getValues ( name ) )
75+ }
76+
77+ const handleFieldBlur = ( ) => {
78+ onBlur ?.( getValues ( name ) )
79+ }
80+
6281 const canAdd = fields . length !== undefined && fields . length < maxSize
6382 const maxSizeReachedTooltip =
6483 addButton . maxSizeReachedTooltip ??
@@ -78,6 +97,8 @@ export const KeyValueField = <
7897 < TextInputField
7998 label = { inputKey . label }
8099 name = { `${ name } .${ index } .key` }
100+ onBlur = { handleFieldBlur }
101+ onChange = { handleFieldChange }
81102 readOnly = { readOnly }
82103 regex = { inputKey . regex }
83104 required = { inputKey . required }
@@ -86,6 +107,8 @@ export const KeyValueField = <
86107 autoComplete = "off"
87108 label = { inputValue . label }
88109 name = { `${ name } .${ index } .value` }
110+ onBlur = { handleFieldBlur }
111+ onChange = { handleFieldChange }
89112 placeholder = { inputValue . placeholder }
90113 readOnly = { readOnly }
91114 regex = { inputValue . regex }
@@ -96,7 +119,10 @@ export const KeyValueField = <
96119 < Button
97120 data-testid = { `remove-button-${ index } ` }
98121 disabled = { readOnly }
99- onClick = { ( ) => remove ( index ) }
122+ onClick = { ( ) => {
123+ remove ( index )
124+ handleFieldChange ( )
125+ } }
100126 sentiment = "danger"
101127 size = "large"
102128 variant = "outlined"
@@ -112,8 +138,11 @@ export const KeyValueField = <
112138 data-testid = "add-button"
113139 disabled = { ! canAdd || readOnly }
114140 fullWidth = { addButton . fullWidth }
115- // @ts -expect-error can't infer properly
116- onClick = { ( ) => append ( { key : '' , value : '' } ) }
141+ onClick = { ( ) => {
142+ // @ts -expect-error can't infer properly
143+ append ( { key : '' , value : '' } )
144+ handleFieldChange ( )
145+ } }
117146 sentiment = "primary"
118147 tooltip = { ! canAdd ? maxSizeReachedTooltip : addButton . tooltip }
119148 variant = "outlined"
0 commit comments