diff --git a/src/components/Checkbox/Checkbox.spec.js b/src/components/Checkbox/Checkbox.spec.js index 445f0a42..27f4d79f 100644 --- a/src/components/Checkbox/Checkbox.spec.js +++ b/src/components/Checkbox/Checkbox.spec.js @@ -17,13 +17,24 @@ describe('Checkbox', () => { expect(screen.getByRole('checkbox')).toHaveAttribute('data-custom', customAttribute); }); - it('should call onChange function', () => { - const handleOnChange = jest.fn(); - render( handleOnChange(event)}/>); + it('should call onChange function with checked status', () => { + const handleOnChange = jest.fn((_, value, checked) => [value, checked]); + render(); const checkbox = screen.getByTestId('moonstone-checkbox'); userEvent.click(checkbox); expect(handleOnChange).toHaveBeenCalled(); + expect(handleOnChange).toHaveReturnedWith(['my-value', true]); // Checkbox has been checked + }); + + it('should call onChange function with checked status for controlled', () => { + const handleOnChange = jest.fn((_, value, checked) => [value, checked]); + render(); + const checkbox = screen.getByTestId('moonstone-checkbox'); + + userEvent.click(checkbox); + expect(handleOnChange).toHaveBeenCalled(); + expect(handleOnChange).toHaveReturnedWith([undefined, false]); // Checkbox has been unchecked, no value specified }); it('should check off when clicked on', () => { diff --git a/src/components/Checkbox/Checkbox.types.ts b/src/components/Checkbox/Checkbox.types.ts index 995b8a27..56489db5 100644 --- a/src/components/Checkbox/Checkbox.types.ts +++ b/src/components/Checkbox/Checkbox.types.ts @@ -54,7 +54,7 @@ export type CheckboxProps = { /** * Function triggered on change of the checkbox value */ - onChange?: (event: React.ChangeEvent) => void; + onChange?: (event: React.ChangeEvent, value: string, checked: boolean) => void; /** * Function triggered on focus of the checkbox value diff --git a/src/components/Checkbox/ControlledCheckbox.tsx b/src/components/Checkbox/ControlledCheckbox.tsx index e1b7bb09..8b8f4a6b 100644 --- a/src/components/Checkbox/ControlledCheckbox.tsx +++ b/src/components/Checkbox/ControlledCheckbox.tsx @@ -4,7 +4,7 @@ import {capitalize} from '~/utils/helpers'; import {CheckboxProps} from './Checkbox.types'; import './Checkbox.scss'; -export const ControlledCheckbox: React.FC = ({className, checked = false, indeterminate = false, size = 'default', isDisabled, isReadOnly, ...props}) => { +export const ControlledCheckbox: React.FC = ({className, checked = false, indeterminate = false, size = 'default', isDisabled, isReadOnly, onChange, value, ...props}) => { const inputRef = useRef(null); return ( @@ -14,10 +14,12 @@ export const ControlledCheckbox: React.FC = ({className, checked ref={inputRef} className={clsx('moonstone-checkbox_input', `moonstone-checkbox_size${capitalize(size)}`)} type="checkbox" + value={value} checked={checked} disabled={isDisabled} aria-readonly={isReadOnly} aria-checked={indeterminate ? 'mixed' : checked} + onChange={ev => (typeof onChange === 'function') && onChange(ev, value, inputRef.current?.checked)} /> { indeterminate ? diff --git a/src/components/Checkbox/UncontrolledCheckbox.tsx b/src/components/Checkbox/UncontrolledCheckbox.tsx index 163899d2..4567ec01 100644 --- a/src/components/Checkbox/UncontrolledCheckbox.tsx +++ b/src/components/Checkbox/UncontrolledCheckbox.tsx @@ -3,17 +3,19 @@ import './Checkbox.scss'; import {CheckboxProps} from './Checkbox.types'; import {ControlledCheckbox} from '~/components/Checkbox/ControlledCheckbox'; -export const UncontrolledCheckbox: React.FC = ({defaultChecked = false, onChange, ...props}) => { +export const UncontrolledCheckbox: React.FC = ({defaultChecked = false, onChange, value, ...props}) => { const [checked, setChecked] = useState(defaultChecked); return ( ) => { - setChecked(!checked); - if (typeof onChange !== 'undefined') { - onChange(event); + const toggleChecked = !checked; + setChecked(toggleChecked); + if (typeof onChange === 'function') { + onChange(event, value, toggleChecked); } }} /> diff --git a/src/components/CheckboxGroup/CheckboxGroup.spec.tsx b/src/components/CheckboxGroup/CheckboxGroup.spec.tsx index 1b110277..5ed92269 100644 --- a/src/components/CheckboxGroup/CheckboxGroup.spec.tsx +++ b/src/components/CheckboxGroup/CheckboxGroup.spec.tsx @@ -75,15 +75,21 @@ describe('CheckboxGroup', () => { }); it('should call onChange function', () => { - const handleOnChange = jest.fn(); + const handleOnChange = jest.fn((ev, value, checked) => [value, checked]); render( - handleOnChange()}> + - + ); userEvent.click(screen.getByLabelText('checkbox 01')); + expect(handleOnChange).toHaveBeenCalled(); + expect(handleOnChange).toHaveReturnedWith(['01', true]); + userEvent.click(screen.getByLabelText('checkbox 02')); + expect(handleOnChange).toHaveBeenCalled(); + expect(handleOnChange).toHaveReturnedWith(['02', false]); + expect(handleOnChange).toHaveBeenCalledTimes(2); }); }); diff --git a/src/components/CheckboxGroup/CheckboxGroup.types.ts b/src/components/CheckboxGroup/CheckboxGroup.types.ts index 1bb39abd..46df2cac 100644 --- a/src/components/CheckboxGroup/CheckboxGroup.types.ts +++ b/src/components/CheckboxGroup/CheckboxGroup.types.ts @@ -20,7 +20,7 @@ export type CheckboxGroupProps = { /** * Function triggered on change of all CheckboxItems. That function is not replaced the onChange function set on a CheckboxItem, In that case both functions will be executed. */ - onChange?: (event: React.ChangeEvent) => void; + onChange?: (event: React.ChangeEvent, value: string, checked: boolean) => void; /** * Whether the checkboxes should be disabled @@ -42,7 +42,7 @@ export type CheckboxGroupContextProps = { /** * Function triggered on change of the checkboxes */ - onChange?: (event: React.ChangeEvent) => void; + onChange?: (event: React.ChangeEvent, value: string, checked: boolean) => void; /** * Whether all CheckboxItems should be disabled diff --git a/src/components/CheckboxGroup/CheckboxItem/CheckboxItem.types.ts b/src/components/CheckboxGroup/CheckboxItem/CheckboxItem.types.ts index b7a7682c..315903cd 100644 --- a/src/components/CheckboxGroup/CheckboxItem/CheckboxItem.types.ts +++ b/src/components/CheckboxGroup/CheckboxItem/CheckboxItem.types.ts @@ -64,5 +64,5 @@ export type CheckboxItemProps = { /** * Function triggered when the CheckboxItem changes state */ - onChange?: (event: React.ChangeEvent) => void; + onChange?: (event: React.ChangeEvent, value: string, checked: boolean) => void; } diff --git a/src/components/CheckboxGroup/CheckboxItem/ControlledCheckboxItem.tsx b/src/components/CheckboxGroup/CheckboxItem/ControlledCheckboxItem.tsx index c44ef7d1..56b245c9 100644 --- a/src/components/CheckboxGroup/CheckboxItem/ControlledCheckboxItem.tsx +++ b/src/components/CheckboxGroup/CheckboxItem/ControlledCheckboxItem.tsx @@ -30,13 +30,13 @@ export const ControlledCheckboxItem: React.FC = ({className, isReadOnly={isReadOnlyItem} isDisabled={isDisabledItem} name={nameItem} - onChange={event => { - if (typeof context?.onChange !== 'undefined') { - context.onChange(event); + onChange={(event, val, checked) => { + if (typeof context?.onChange === 'function') { + context.onChange(event, val, checked); } - if (typeof onChange !== 'undefined') { - onChange(event); + if (typeof onChange === 'function') { + onChange(event, val, checked); } }} {...props} diff --git a/src/components/CheckboxGroup/CheckboxItem/UncontrolledCheckboxItem.tsx b/src/components/CheckboxGroup/CheckboxItem/UncontrolledCheckboxItem.tsx index 771605ea..256911c0 100644 --- a/src/components/CheckboxGroup/CheckboxItem/UncontrolledCheckboxItem.tsx +++ b/src/components/CheckboxGroup/CheckboxItem/UncontrolledCheckboxItem.tsx @@ -9,11 +9,11 @@ export const UncontrolledCheckboxItem: React.FC = ({defaultCh ) => { - setChecked(!checked); - - if (typeof onChange !== 'undefined') { - onChange(event); + onChange={(event: React.ChangeEvent, value: string) => { + const toggleChecked = !checked; + setChecked(toggleChecked); + if (typeof onChange === 'function') { + onChange(event, value, toggleChecked); } }} /> diff --git a/src/components/CheckboxGroup/index.ts b/src/components/CheckboxGroup/index.ts index 7c00f7bf..fd18dbc2 100644 --- a/src/components/CheckboxGroup/index.ts +++ b/src/components/CheckboxGroup/index.ts @@ -1 +1,2 @@ export * from './CheckboxGroup'; +export * from './CheckboxItem/CheckboxItem';