Skip to content

Commit c8785c8

Browse files
authored
fix: add onBlur on keyValueField (#5405)
* fix: add onBlur on keyValueField * Create short-cherries-exist.md
1 parent b144d15 commit c8785c8

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

.changeset/short-cherries-exist.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ultraviolet/form": patch
3+
---
4+
5+
fix: add onBlur on keyValueField

packages/form/src/components/KeyValueField/index.tsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { DeleteIcon, PlusIcon } from '@ultraviolet/icons'
44
import { Button, Row, Stack } from '@ultraviolet/ui'
55
import type { ComponentProps } from 'react'
66
import type { Control, FieldArrayPath, FieldValues } from 'react-hook-form'
7-
import { useFieldArray } from 'react-hook-form'
7+
import { useFieldArray, useFormContext } from 'react-hook-form'
88
import { TextInputField } from '../TextInputField'
99

1010
type InputKeyProps = {
@@ -25,6 +25,11 @@ type AddButtonProps = {
2525
maxSizeReachedTooltip?: string
2626
}
2727

28+
type KeyValuePair = {
29+
key: string
30+
value: string
31+
}
32+
2833
type 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

Comments
 (0)