Skip to content

Commit

Permalink
feat: add autoFocus to RadioButton (#2057)
Browse files Browse the repository at this point in the history
  • Loading branch information
chensara authored Apr 10, 2024
1 parent 7c35041 commit d40b49e
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 50 deletions.
5 changes: 5 additions & 0 deletions packages/core/src/components/RadioButton/RadioButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface RadioButtonProps extends VibeComponentProps {
value?: string;
/** A string specifying a name for the input control. This name is submitted along with the control's value when the form data is submitted. */
name?: string;
/** is autoFocus */
autoFocus?: boolean;
/** is disabled */
disabled?: boolean;
/** why the input is disabled */
Expand Down Expand Up @@ -64,6 +66,7 @@ const RadioButton: VibeComponent<RadioButtonProps, HTMLElement> & object = forwa
*/
radioButtonClassName,
disabled = false,
autoFocus,
disabledReason,
defaultChecked = false,
children,
Expand All @@ -80,6 +83,7 @@ const RadioButton: VibeComponent<RadioButtonProps, HTMLElement> & object = forwa
const inputRef = useRef<HTMLInputElement | null>();
const mergedRef = useMergeRef(ref, inputRef);
const overrideClassName = backwardCompatibilityForProperties([className, componentClassName]);

const onChildClick = useCallback(() => {
if (disabled || !retainChildClick) return;
if (inputRef.current) {
Expand Down Expand Up @@ -114,6 +118,7 @@ const RadioButton: VibeComponent<RadioButtonProps, HTMLElement> & object = forwa
type="radio"
value={value}
name={name}
autoFocus={autoFocus}
disabled={disabled}
{...checkedProps}
onChange={onSelect}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`RadioButton renders correctly when autoFocus 1`] = `
<label
className="radioButton"
data-testid="radio-button"
>
<span
className="inputContainer"
>
<input
autoFocus={true}
className="input"
defaultChecked={false}
disabled={false}
name=""
type="radio"
value=""
/>
<span
className="control labelAnimation"
data-testid="radio-button-control"
/>
</span>
</label>
`;

exports[`RadioButton renders correctly when checked 1`] = `
<label
className="radioButton"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import renderer from "react-test-renderer";
import RadioButton from "../RadioButton";

Expand Down Expand Up @@ -33,6 +32,11 @@ describe("RadioButton renders correctly", () => {
expect(tree).toMatchSnapshot();
});

it("when autoFocus", () => {
const tree = renderer.create(<RadioButton autoFocus />).toJSON();
expect(tree).toMatchSnapshot();
});

it("when unchecked", () => {
const tree = renderer.create(<RadioButton checked={false} />).toJSON();
expect(tree).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import "@testing-library/jest-dom";
import { fireEvent, render, cleanup, screen } from "@testing-library/react";
import RadioButton from "../RadioButton";

Expand All @@ -17,60 +17,81 @@ describe("RadioButton tests", () => {
let onChangeMock2: jest.Mock;
let onChangeMock3: jest.Mock;

beforeEach(() => {
onChangeMock1 = jest.fn();
onChangeMock2 = jest.fn();
onChangeMock3 = jest.fn();
describe("With one of the radio buttons is checked by default", () => {
beforeEach(() => {
onChangeMock1 = jest.fn();
onChangeMock2 = jest.fn();
onChangeMock3 = jest.fn();

render(
<form name={formName}>
<RadioButton
name={radiosName}
value={option1Value}
text={option1Text}
onSelect={onChangeMock1}
defaultChecked={true}
/>
<RadioButton name={radiosName} value={option2Value} text={option2Text} onSelect={onChangeMock2} />
<RadioButton name={radiosName} value={option3Value} text={option3Text} onSelect={onChangeMock3} />
</form>
);
});
render(
<form name={formName}>
<RadioButton
name={radiosName}
value={option1Value}
text={option1Text}
onSelect={onChangeMock1}
defaultChecked
/>
<RadioButton name={radiosName} value={option2Value} text={option2Text} onSelect={onChangeMock2} />
<RadioButton name={radiosName} value={option3Value} text={option3Text} onSelect={onChangeMock3} />
</form>
);
});

afterEach(() => {
cleanup();
});
afterEach(() => {
cleanup();
});

it("should default select 1st option", () => {
const option1: HTMLInputElement = screen.getByLabelText(option1Text);
const option2: HTMLInputElement = screen.getByLabelText(option2Text);
const option3: HTMLInputElement = screen.getByLabelText(option3Text);
expect(option1.checked).toBeTruthy();
expect(option2.checked).toBeFalsy();
expect(option3.checked).toBeFalsy();
});
it("should default select 1st option", () => {
const option1: HTMLInputElement = screen.getByLabelText(option1Text);
const option2: HTMLInputElement = screen.getByLabelText(option2Text);
const option3: HTMLInputElement = screen.getByLabelText(option3Text);
expect(option1.checked).toBeTruthy();
expect(option2.checked).toBeFalsy();
expect(option3.checked).toBeFalsy();
});

it("should select 2nd option", () => {
const option1: HTMLInputElement = screen.getByLabelText(option1Text);
const option2: HTMLInputElement = screen.getByLabelText(option2Text);
const option3: HTMLInputElement = screen.getByLabelText(option3Text);
fireEvent.click(option2);
expect(option1.checked).toBeFalsy();
expect(option2.checked).toBeTruthy();
expect(option3.checked).toBeFalsy();
});
it("should select 2nd option", () => {
const option1: HTMLInputElement = screen.getByLabelText(option1Text);
const option2: HTMLInputElement = screen.getByLabelText(option2Text);
const option3: HTMLInputElement = screen.getByLabelText(option3Text);
fireEvent.click(option2);
expect(option1.checked).toBeFalsy();
expect(option2.checked).toBeTruthy();
expect(option3.checked).toBeFalsy();
});

it("should call the onChange callback when clicked", () => {
const option2 = screen.getByLabelText(option2Text);
fireEvent.click(option2);
expect(onChangeMock2.mock.calls.length).toBe(1);
expect(onChangeMock2.mock.calls[0]).toBeTruthy();
});

it("should call the onChange callback when clicked", () => {
const option2 = screen.getByLabelText(option2Text);
fireEvent.click(option2);
expect(onChangeMock2.mock.calls.length).toBe(1);
expect(onChangeMock2.mock.calls[0]).toBeTruthy();
it("should be the same text", () => {
const text = "test text";
const { getByText } = render(<RadioButton text={text} />);
const radioButtonComponentText = getByText(text);
expect(radioButtonComponentText).toBeTruthy();
});
});

it("should be the same text", () => {
const text = "test text";
const { getByText } = render(<RadioButton text={text} />);
const radioButtonComponentText = getByText(text);
expect(radioButtonComponentText).toBeTruthy();
describe("When all radio buttons are unchecked", () => {
it("should auto focus 2nd option", () => {
render(
<form name={formName}>
<RadioButton text={option1Text} />
<RadioButton text={option2Text} autoFocus />
<RadioButton text={option3Text} />
</form>
);

const option1: HTMLInputElement = screen.getByLabelText(option1Text);
const option2: HTMLInputElement = screen.getByLabelText(option2Text);
const option3: HTMLInputElement = screen.getByLabelText(option3Text);
expect(option1).not.toHaveFocus();
expect(option2).toHaveFocus();
expect(option3).not.toHaveFocus();
});
});
});

0 comments on commit d40b49e

Please sign in to comment.