-
Notifications
You must be signed in to change notification settings - Fork 99
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add: Add useValueChange hook for form components
All form components should be able to call the onChange handler with the value, name pair. Therefore introduce a generic hook to abstract the event handling.
- Loading branch information
1 parent
cf751df
commit 0d0e5f2
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
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,43 @@ | ||
/* SPDX-FileCopyrightText: 2024 Greenbone AG | ||
* | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import {render, screen, fireEvent} from 'web/utils/testing'; | ||
|
||
import useValueChange from '../useValueChange'; | ||
|
||
const TestComponent = ({value, onChange, name, disabled}) => { | ||
const handleChange = useValueChange({onChange, name, disabled}); | ||
|
||
return ( | ||
<input value={value} name={name} type="text" onChange={handleChange} /> | ||
); | ||
}; | ||
|
||
describe('onValueChange Tests', () => { | ||
test('should call onChange when value changes', () => { | ||
const onChange = jest.fn(); | ||
|
||
render(<TestComponent value="test" onChange={onChange} name="test" />); | ||
|
||
const input = screen.getByRole('textbox'); | ||
|
||
fireEvent.change(input, {target: {value: 'new value'}}); | ||
|
||
expect(onChange).toHaveBeenCalledTimes(1); | ||
expect(onChange).toHaveBeenCalledWith('new value', 'test'); | ||
}); | ||
|
||
test('should not call onChange when disabled', () => { | ||
const onChange = jest.fn(); | ||
|
||
render(<TestComponent value="test" onChange={onChange} name="test" disabled={true}/>); | ||
|
||
const input = screen.getByRole('textbox'); | ||
|
||
fireEvent.change(input, {target: {value: 'new value'}}); | ||
|
||
expect(onChange).not.toHaveBeenCalled(); | ||
}); | ||
}); |
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,52 @@ | ||
/* SPDX-FileCopyrightText: 2024 Greenbone AG | ||
* | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import {useCallback} from 'react'; | ||
|
||
import {isDefined} from 'gmp/utils/identity'; | ||
|
||
const eventTargetValue = event => event.target.value; | ||
const noOpConvert = value => value; | ||
/** | ||
* A hook that handles the change of a value of an input field. | ||
* | ||
* It gets the event target value and optionally converts it. | ||
* value and name are passed to the onChange function. | ||
* | ||
* @param {Object} param0 An object with the following properties: | ||
* - disabled: A boolean that indicates if the value can be changed. | ||
* - name: A string that represents the name of the value. | ||
* - onChange: A function that is called when the value changes. | ||
* - convert: A function that converts the value optionally. | ||
* - valueFunc: A function that gets the value from the event. Defaults to event.target.value. | ||
* @returns A function as a callback that handles the change of a value in an input field. | ||
*/ | ||
const useValueChange = ({ | ||
disabled, | ||
name, | ||
onChange, | ||
convert = noOpConvert, | ||
valueFunc = eventTargetValue, | ||
}) => { | ||
const notifyChange = useCallback( | ||
value => { | ||
if (isDefined(onChange) && !disabled) { | ||
onChange(value, name); | ||
} | ||
}, | ||
[disabled, name, onChange], | ||
); | ||
|
||
const handleChange = useCallback( | ||
event => { | ||
notifyChange(convert(valueFunc(event))); | ||
}, | ||
[notifyChange, convert, valueFunc], | ||
); | ||
|
||
return handleChange; | ||
}; | ||
|
||
export default useValueChange; |