diff --git a/uui-components/src/inputs/Checkbox.tsx b/uui-components/src/inputs/Checkbox.tsx index 3498dd947b..560e524935 100644 --- a/uui-components/src/inputs/Checkbox.tsx +++ b/uui-components/src/inputs/Checkbox.tsx @@ -1,10 +1,8 @@ import * as React from 'react'; -import { cx, IHasTabIndex, uuiMarkers } from '@epam/uui-core'; +import { cx, IHasTabIndex, useUuiContext, uuiMarkers } from '@epam/uui-core'; +import { Icon, uuiMod, uuiElement, isEventTargetInsideClickable, CheckboxCoreProps } from '@epam/uui-core'; +import { IconContainer } from '../layout'; import css from './Checkbox.module.scss'; -import { - Icon, uuiMod, uuiElement, isEventTargetInsideClickable, CheckboxCoreProps, UuiContexts, UuiContext, -} from '@epam/uui-core'; -import { IconContainer } from '../layout/IconContainer'; export interface CheckboxProps extends CheckboxCoreProps, IHasTabIndex { /** Render callback for checkbox label. @@ -26,20 +24,19 @@ export interface CheckboxProps extends CheckboxCoreProps, IHasTabIndex { indeterminateIcon?: Icon; } -export class Checkbox extends React.Component { - static contextType = UuiContext; - context: UuiContexts; +export const Checkbox = React.forwardRef((props, ref) => { + const context = useUuiContext(); - handleChange = (e: React.SyntheticEvent) => { - !isEventTargetInsideClickable(e) && this.props.onValueChange(!this.props.value); + const handleChange = (e: React.SyntheticEvent) => { + !isEventTargetInsideClickable(e) && props.onValueChange(!props.value); - if (this.props.getValueChangeAnalyticsEvent) { - const event = this.props.getValueChangeAnalyticsEvent(!this.props.value, this.props.value); - this.context.uuiAnalytics.sendEvent(event); + if (props.getValueChangeAnalyticsEvent) { + const event = props.getValueChangeAnalyticsEvent(!props.value, props.value); + context.uuiAnalytics.sendEvent(event); } }; - handleAriaCheckedValue = (indeterminate: boolean, value: boolean): boolean | 'mixed' => { + const handleAriaCheckedValue = (indeterminate: boolean, value: boolean): boolean | 'mixed' => { if (indeterminate) { return 'mixed'; } @@ -47,51 +44,46 @@ export class Checkbox extends React.Component { return value == null ? false : value; }; - render() { - let label = this.props.label; - if (this.props.renderLabel) { - label = this.props.renderLabel(); - } - const ariaCheckedValue = this.handleAriaCheckedValue(this.props.indeterminate, this.props.value); + const label = props.renderLabel ? props.renderLabel() : props.label; + const ariaCheckedValue = handleAriaCheckedValue(props.indeterminate, props.value); - return ( - + ); +}); diff --git a/uui-components/src/inputs/__tests__/Checkbox.test.tsx b/uui-components/src/inputs/__tests__/Checkbox.test.tsx index f45995b7da..54e210b629 100644 --- a/uui-components/src/inputs/__tests__/Checkbox.test.tsx +++ b/uui-components/src/inputs/__tests__/Checkbox.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Checkbox, CheckboxProps } from '../Checkbox'; -import { render, screen, fireEvent, setupComponentForTest, userEvent } from '@epam/uui-test-utils'; +import { screen, fireEvent, setupComponentForTest, userEvent } from '@epam/uui-test-utils'; async function setupCheckbox(params: Partial) { const { mocks, setProps } = await setupComponentForTest( @@ -71,18 +71,29 @@ describe('Checkbox', () => { expect(getValueChangeAnalyticsEvent).toHaveBeenCalled(); }); - it('should not handle change event when readonly', () => { + it('should not handle change event when readonly', async () => { const onValueChange = jest.fn(); - render(); + await setupCheckbox({ + value: false, + onValueChange, + isReadonly: true, + label: 'Label', + }); const input = screen.getByRole('checkbox'); fireEvent.click(input); expect(onValueChange).not.toHaveBeenCalled(); }); - it('should handle focus event', () => { + it('should handle focus event', async () => { const onFocus = jest.fn(); - render(); + const onValueChange = jest.fn(); + await setupCheckbox({ + value: false, + onValueChange, + label: 'Label', + onFocus, + }); const input = screen.getByRole('checkbox'); input.focus(); @@ -91,9 +102,15 @@ describe('Checkbox', () => { expect(input).toHaveFocus(); }); - it('should handle blur event', () => { + it('should handle blur event', async () => { const onBlur = jest.fn(); - render(); + const onValueChange = jest.fn(); + await setupCheckbox({ + value: false, + onValueChange, + label: 'Label', + onBlur, + }); const input = screen.getByRole('checkbox'); input.focus(); diff --git a/uui/components/inputs/__tests__/Checkbox.test.tsx b/uui/components/inputs/__tests__/Checkbox.test.tsx index 10a0483bc4..d9cfe60687 100644 --- a/uui/components/inputs/__tests__/Checkbox.test.tsx +++ b/uui/components/inputs/__tests__/Checkbox.test.tsx @@ -1,15 +1,30 @@ import React from 'react'; -import { Checkbox } from '../Checkbox'; -import { renderer } from '@epam/uui-test-utils'; +import { renderSnapshotWithContextAsync } from '@epam/uui-test-utils'; +import { Checkbox } from '@epam/uui'; +import { ReactComponent as ActionAccountFillIcon } from '@epam/assets/icons/action-account-fill.svg'; -describe('Checkbox', () => { - it('should be rendered correctly', () => { - const tree = renderer.create().toJSON(); +describe('TestComponent', () => { + it('should render with minimum props', async () => { + const tree = await renderSnapshotWithContextAsync(); expect(tree).toMatchSnapshot(); }); - it('should be rendered correctly', () => { - const tree = renderer.create().toJSON(); + it('should be rendered with maximum props', async () => { + const tree = await renderSnapshotWithContextAsync( + , + ); expect(tree).toMatchSnapshot(); }); }); diff --git a/uui/components/inputs/__tests__/__snapshots__/Checkbox.test.tsx.snap b/uui/components/inputs/__tests__/__snapshots__/Checkbox.test.tsx.snap index 77a3dcd8ab..c1df800019 100644 --- a/uui/components/inputs/__tests__/__snapshots__/Checkbox.test.tsx.snap +++ b/uui/components/inputs/__tests__/__snapshots__/Checkbox.test.tsx.snap @@ -1,37 +1,63 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Checkbox should be rendered correctly 1`] = ` +exports[`TestComponent should be rendered with maximum props 1`] = ` `; -exports[`Checkbox should be rendered correctly 2`] = ` +exports[`TestComponent should render with minimum props 1`] = ` `; diff --git a/uui/components/layout/__tests__/CheckboxGroup.test.tsx b/uui/components/layout/__tests__/CheckboxGroup.test.tsx index c05a15f977..ec5c76d607 100644 --- a/uui/components/layout/__tests__/CheckboxGroup.test.tsx +++ b/uui/components/layout/__tests__/CheckboxGroup.test.tsx @@ -1,33 +1,30 @@ import React from 'react'; import { CheckboxGroup } from '../CheckboxGroup'; -import { renderer } from '@epam/uui-test-utils'; +import { renderSnapshotWithContextAsync } from '@epam/uui-test-utils'; describe('CheckboxGroup', () => { - it('should be rendered correctly', () => { - const tree = renderer - .create( - {} } - items={ [{ id: 1, name: 'Test1' }, { id: 2, name: 'Test2' }] } - />, - ) - .toJSON(); + it('should be rendered correctly', async () => { + const tree = await renderSnapshotWithContextAsync( + {} } + items={ [{ id: 1, name: 'Test1' }, { id: 2, name: 'Test2' }] } + />, + ); expect(tree).toMatchSnapshot(); }); - it('should be rendered correctly with props', () => { - const tree = renderer - .create( - {} } - items={ [{ id: 1, name: 'Test1' }, { id: 2, name: 'Test2' }] } - direction="horizontal" - isDisabled - />, - ) - .toJSON(); + it('should be rendered correctly with props', async () => { + const tree = await renderSnapshotWithContextAsync( + {} } + items={ [{ id: 1, name: 'Test1' }, { id: 2, name: 'Test2' }] } + direction="horizontal" + isDisabled + />, + ); + expect(tree).toMatchSnapshot(); }); });