Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix radiobutton check issue #587

Merged
merged 4 commits into from
Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/RadioButton/RadioButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ RadioButton.propTypes = {
value: PropTypes.string,
name: PropTypes.string,
disabled: PropTypes.bool,
/** Auto check by default */
defaultChecked: PropTypes.bool,
/** Controlled externally - When used, need to be set for all radio buttons in the same group */
checked: PropTypes.bool,
onSelect: PropTypes.func
};
Expand Down
27 changes: 27 additions & 0 deletions src/components/RadioButton/__stories__/interactions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect } from "@storybook/jest";
import { getByText, getByRole, clickElement, testFunctionWrapper } from "../../../__tests__/interactions-helper";

export const clickRadioButton = testFunctionWrapper(async canvas => {
const radioToClick = getByText(canvas, "I was mentioned");
// Click the radio button
await clickElement(radioToClick);
// check it is selected
const inputElement = radioToClick.parentElement.firstChild.firstChild;
expect(inputElement.checked).toEqual(true);
});

export const controlRadioButton = testFunctionWrapper(async canvas => {
// check first radio is selected
let radioButton = getByText(canvas, "Radio 1");
let inputElement = radioButton.parentElement.firstChild.firstChild;
expect(inputElement.checked).toEqual(true);
const button = getByRole(canvas, "button");
// Click the button
await clickElement(button);
// check first radio is no selected
expect(inputElement.checked).toEqual(false);
// check second radio is selected
radioButton = getByText(canvas, "Radio 2");
inputElement = radioButton.parentElement.firstChild.firstChild;
expect(inputElement.checked).toEqual(true);
});
27 changes: 27 additions & 0 deletions src/components/RadioButton/__stories__/radioButton.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { useCallback, useState } from "react";
import RadioButton from "../RadioButton";
import Button from "../../Button/Button";

const ControlledRadioButton = () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const onClickCB = useCallback(() => {
setSelectedIndex(prev => (prev + 1) % 3);
}, [setSelectedIndex]);
const onChange = useCallback(() => {}, []);

return (
<div className="monday-style-radio-buttons_wrapper-column">
<div>Controlled radio buttons</div>
<Button kind={Button.kinds.SECONDARY} onClick={onClickCB}>{`Select next radio button (Radio ${
((selectedIndex + 1) % 3) + 1
}) `}</Button>
<RadioButton text="Radio 1" name="radio-buttons-group-5" checked={selectedIndex === 0} onSelect={onChange} />
<RadioButton text="Radio 2" name="radio-buttons-group-5" checked={selectedIndex === 1} onSelect={onChange} />
<RadioButton text="Radio 3" name="radio-buttons-group-5" checked={selectedIndex === 2} onSelect={onChange} />
</div>
);
};

export const controlledRadioButton = () => {
return <ControlledRadioButton />;
};
112 changes: 79 additions & 33 deletions src/components/RadioButton/__stories__/radioButton.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import { createComponentTemplate } from "../../../storybook/functions/create-com
import { TOGGLE, CHECKBOX, DROPDOWN } from "../../../storybook/components/related-components/component-description-map";
import DialogContentContainer from "../../DialogContentContainer/DialogContentContainer";
import { Link } from "../../../storybook/components";
import { clickRadioButton, controlRadioButton } from "./interactions";
import { controlledRadioButton } from "./radioButton.stories";
import "./radioButton.stories.scss";

<Meta
title="Inputs/Radio Button"
component={ RadioButton }
/>
<Meta title="Inputs/Radio Button" component={RadioButton} />

<!--- Component template -->

Expand All @@ -18,6 +17,7 @@ export const radioButtonTemplate = createComponentTemplate(RadioButton);
<!--- Component documentation -->

# RadioButton

- [Overview](#overview)
- [Props](#props)
- [Usage](#usage)
Expand All @@ -28,30 +28,44 @@ export const radioButtonTemplate = createComponentTemplate(RadioButton);
- [Feedback](#feedback)

## Overview

A radio represents an item in a single selection list.

<Canvas>
<Story name="Overview"
args={ {text: "Selection" } }>
{ radioButtonTemplate.bind({}) }
<Story name="Overview" args={{ text: "Selection" }}>
{radioButtonTemplate.bind({})}
</Story>
</Canvas>

## Props
<ArgsTable of={ RadioButton } />

<ArgsTable of={RadioButton} />

## Usage
<UsageGuidelines guidelines={[
"A radio lets a user make exactly one selection from a set, which is all visible at the same time.",
"Set one radio group option as default. Select the most likely or convenient option.",
"Ensure both label and input are clickable to select the option.",
"Place radio buttons can be placed vertically or horizontaly, using 16px spacing.",
]}/>

<Tip>When there’s limited space or no default selection, consider using a select <Link href="/?path=/docs/inputs-dropdown--overview" size={Link.sizes.SMALL} withoutSpacing>Dropdown</Link> instead.</Tip>
<UsageGuidelines
guidelines={[
"A radio lets a user make exactly one selection from a set, which is all visible at the same time.",
"Set one radio group option as default. Select the most likely or convenient option.",
"Ensure both label and input are clickable to select the option.",
"Place radio buttons can be placed vertically or horizontaly, using 16px spacing."
]}
/>

<Tip>
When there’s limited space or no default selection, consider using a select{" "}
<Link href="/?path=/docs/inputs-dropdown--overview" size={Link.sizes.SMALL} withoutSpacing>
Dropdown
</Link>{" "}
instead.
</Tip>

## Variants

### States

Radio buttons have 3 states: regular, selected, and disabled.

<Canvas>
<Story name="States">
<RadioButton text="Regular" />
Expand All @@ -61,62 +75,94 @@ Radio buttons have 3 states: regular, selected, and disabled.
</Canvas>

## Do’s and Don’ts

<ComponentRules
rules={[
{
positive: {
component:
component: (
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
<RadioButton text="Item 1" name="radio-buttons-group-1" />
<RadioButton text="Item 2" name="radio-buttons-group-1" checked />
</DialogContentContainer>,
description:"Use radio buttons when only one item can be selected from a list."
<RadioButton text="Item 2" name="radio-buttons-group-1" defaultChecked />
</DialogContentContainer>
),
description: "Use radio buttons when only one item can be selected from a list."
},
negative: {
component:
component: (
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
<RadioButton text="Item 1" checked />
<RadioButton text="Item 2" checked />
</DialogContentContainer>,
description:<>Don't use radio buttons when allowing the user to select more than one item from a list. In this case, use <Link href="/?path=/docs/inputs-checkbox--overview" withoutSpacing>checkboxes</Link> instead.</>
</DialogContentContainer>
),
description: (
<>
Don't use radio buttons when allowing the user to select more than one item from a list. In this case, use{" "}
<Link href="/?path=/docs/inputs-checkbox--overview" withoutSpacing>
checkboxes
</Link>{" "}
instead.
</>
)
}
},
{
positive: {
component:
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
<RadioButton text="Item 1" name="radio-buttons-group-2" checked />
component: (
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
<RadioButton text="Item 1" name="radio-buttons-group-2" defaultChecked />
<RadioButton text="Item 2" name="radio-buttons-group-2" />
<RadioButton text="Item 3" name="radio-buttons-group-2" />
</DialogContentContainer>,
description:"Mark the first item as selected, and make sure it’s the most common or popular action."
</DialogContentContainer>
),
description: "Mark the first item as selected, and make sure it’s the most common or popular action."
},
negative: {
component:
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
component: (
<DialogContentContainer className="monday-style-radio-buttons_wrapper">
<RadioButton text="Item 1" name="radio-buttons-group-3" />
<RadioButton text="Item 2" name="radio-buttons-group-3" />
<RadioButton text="Item 3" name="radio-buttons-group-3" />
</DialogContentContainer>,
description:<>Don’t leave all radio buttons unselcted. If you can’t offer a smart default, consider using the <Link href="/?path=/docs/inputs-dropdown--overview" withoutSpacing>dropdown component.</Link></>
</DialogContentContainer>
),
description: (
<>
Don’t leave all radio buttons unselcted. If you can’t offer a smart default, consider using the{" "}
<Link href="/?path=/docs/inputs-dropdown--overview" withoutSpacing>
dropdown component.
</Link>
</>
)
}
}
]}
/>

## Use cases and examples

### Radio button in items list

The user needs to select only one option.

<Canvas>
<Story name="Radio button in items list">
<Story name="Radio button in items list" play={clickRadioButton}>
<div className="monday-style-radio-buttons_wrapper-column">
<div>Inbox view options</div>
<RadioButton text="Inbox updates" name="radio-buttons-group-4" checked />
<RadioButton text="Inbox updates" name="radio-buttons-group-4" defaultChecked />
<RadioButton text="I was mentioned" name="radio-buttons-group-4" />
<RadioButton text="All updates" name="radio-buttons-group-4" />
</div>
</Story>
</Canvas>

Controled externally.

<Canvas>
<Story name="Controlled Radio buttons" play={controlRadioButton}>
{controlledRadioButton.bind({})}
hadasfa marked this conversation as resolved.
Show resolved Hide resolved
</Story>
</Canvas>

## Related components

<RelatedComponents componentsNames={[CHECKBOX, TOGGLE, DROPDOWN]} />