Skip to content

Commit

Permalink
Merge branch 'develop' into MOON-407
Browse files Browse the repository at this point in the history
  • Loading branch information
ffffffelix authored Dec 7, 2023
2 parents c34a619 + 9023b7f commit cb24f71
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 25 deletions.
17 changes: 14 additions & 3 deletions src/components/Checkbox/Checkbox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,24 @@ describe('Checkbox', () => {
expect(screen.getByRole('checkbox')).toHaveAttribute('data-custom', customAttribute);
});

it('should call onChange function', () => {
const handleOnChange = jest.fn();
render(<Checkbox data-testid="moonstone-checkbox" onChange={event => handleOnChange(event)}/>);
it('should call onChange function with checked status', () => {
const handleOnChange = jest.fn((_, value, checked) => [value, checked]);
render(<Checkbox data-testid="moonstone-checkbox" value="my-value" onChange={handleOnChange}/>);
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(<Checkbox checked data-testid="moonstone-checkbox" onChange={handleOnChange}/>);
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', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Checkbox/Checkbox.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export type CheckboxProps = {
/**
* Function triggered on change of the checkbox value
*/
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string, checked: boolean) => void;

/**
* Function triggered on focus of the checkbox value
Expand Down
4 changes: 3 additions & 1 deletion src/components/Checkbox/ControlledCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {capitalize} from '~/utils/helpers';
import {CheckboxProps} from './Checkbox.types';
import './Checkbox.scss';

export const ControlledCheckbox: React.FC<CheckboxProps> = ({className, checked = false, indeterminate = false, size = 'default', isDisabled, isReadOnly, ...props}) => {
export const ControlledCheckbox: React.FC<CheckboxProps> = ({className, checked = false, indeterminate = false, size = 'default', isDisabled, isReadOnly, onChange, value, ...props}) => {
const inputRef = useRef<HTMLInputElement>(null);

return (
Expand All @@ -14,10 +14,12 @@ export const ControlledCheckbox: React.FC<CheckboxProps> = ({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)}
/>
<svg className={clsx('moonstone-checkbox_icon', `moonstone-checkbox_size${capitalize(size)}`)} viewBox="0 0 21 21">
{ indeterminate ?
Expand Down
10 changes: 6 additions & 4 deletions src/components/Checkbox/UncontrolledCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import './Checkbox.scss';
import {CheckboxProps} from './Checkbox.types';
import {ControlledCheckbox} from '~/components/Checkbox/ControlledCheckbox';

export const UncontrolledCheckbox: React.FC<CheckboxProps> = ({defaultChecked = false, onChange, ...props}) => {
export const UncontrolledCheckbox: React.FC<CheckboxProps> = ({defaultChecked = false, onChange, value, ...props}) => {
const [checked, setChecked] = useState(defaultChecked);

return (
<ControlledCheckbox
{...props}
value={value}
checked={checked}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(!checked);
if (typeof onChange !== 'undefined') {
onChange(event);
const toggleChecked = !checked;
setChecked(toggleChecked);
if (typeof onChange === 'function') {
onChange(event, value, toggleChecked);
}
}}
/>
Expand Down
12 changes: 9 additions & 3 deletions src/components/CheckboxGroup/CheckboxGroup.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<CheckboxGroup name="test-grouped-checkboxes" onChange={() => handleOnChange()}>
<CheckboxGroup name="test-grouped-checkboxes" onChange={handleOnChange}>
<CheckboxItem id="checkbox-01" label="checkbox 01" value="01"/>
<CheckboxItem id="checkbox-02" label="checkbox 02" value="02"/>
<CheckboxItem checked id="checkbox-02" label="checkbox 02" value="02"/>
</CheckboxGroup>
);
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);
});
});
4 changes: 2 additions & 2 deletions src/components/CheckboxGroup/CheckboxGroup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLInputElement>) => void;
onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string, checked: boolean) => void;

/**
* Whether the checkboxes should be disabled
Expand All @@ -42,7 +42,7 @@ export type CheckboxGroupContextProps = {
/**
* Function triggered on change of the checkboxes
*/
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string, checked: boolean) => void;

/**
* Whether all CheckboxItems should be disabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@ export type CheckboxItemProps = {
/**
* Function triggered when the CheckboxItem changes state
*/
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string, checked: boolean) => void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ export const ControlledCheckboxItem: React.FC<CheckboxItemProps> = ({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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ export const UncontrolledCheckboxItem: React.FC<CheckboxItemProps> = ({defaultCh
<ControlledCheckboxItem
{...props}
checked={checked}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(!checked);

if (typeof onChange !== 'undefined') {
onChange(event);
onChange={(event: React.ChangeEvent<HTMLInputElement>, value: string) => {
const toggleChecked = !checked;
setChecked(toggleChecked);
if (typeof onChange === 'function') {
onChange(event, value, toggleChecked);
}
}}
/>
Expand Down
1 change: 1 addition & 0 deletions src/components/CheckboxGroup/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './CheckboxGroup';
export * from './CheckboxItem/CheckboxItem';

0 comments on commit cb24f71

Please sign in to comment.