Skip to content

Commit

Permalink
add disabled prop to RadioGroup and RadioGroup Option (#401)
Browse files Browse the repository at this point in the history
* add `disabled` prop to RadioGroup and RadioGroup Option

Also did some general cleanup which in turn fixed an issue where the
RadioGroup is unreachable when a value is used that doesn't exist in the
list of options.

Fixes: #378

* update changelog
  • Loading branch information
RobinMalfait committed Apr 20, 2021
1 parent 526dcfb commit ce1d764
Show file tree
Hide file tree
Showing 6 changed files with 451 additions and 83 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixes

- Improve search, make searching case insensitive ([#385](https://github.com/tailwindlabs/headlessui/pull/385))
- Fix unreachable `RadioGroup` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))

### Added

- Add `disabled` prop to `RadioGroup` and `RadioGroup.Option` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))

## [Unreleased - Vue]

- Nothing yet!
### Fixes

- Improve search, make searching case insensitive ([#385](https://github.com/tailwindlabs/headlessui/pull/385))
- Fix unreachable `RadioGroup` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))

### Added

- Add `disabled` prop to `RadioGroup` and `RadioGroupOption` ([#401](https://github.com/tailwindlabs/headlessui/pull/401))

## [@headlessui/react@v1.0.0] - 2021-04-14

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('Safe guards', () => {
})

describe('Rendering', () => {
it('should be possible to render a RadioGroup, where the first element is tabbable', async () => {
it('should be possible to render a RadioGroup, where the first element is tabbable (value is undefined)', async () => {
render(
<RadioGroup value={undefined} onChange={console.log}>
<RadioGroup.Label>Pizza Delivery</RadioGroup.Label>
Expand All @@ -72,6 +72,23 @@ describe('Rendering', () => {
assertNotFocusable(getByText('Dine in'))
})

it('should be possible to render a RadioGroup, where the first element is tabbable (value is null)', async () => {
render(
<RadioGroup value={null} onChange={console.log}>
<RadioGroup.Label>Pizza Delivery</RadioGroup.Label>
<RadioGroup.Option value="pickup">Pickup</RadioGroup.Option>
<RadioGroup.Option value="home-delivery">Home delivery</RadioGroup.Option>
<RadioGroup.Option value="dine-in">Dine in</RadioGroup.Option>
</RadioGroup>
)

expect(getRadioGroupOptions()).toHaveLength(3)

assertFocusable(getByText('Pickup'))
assertNotFocusable(getByText('Home delivery'))
assertNotFocusable(getByText('Dine in'))
})

it('should be possible to render a RadioGroup with an active value', async () => {
render(
<RadioGroup value="home-delivery" onChange={console.log}>
Expand Down Expand Up @@ -120,6 +137,121 @@ describe('Rendering', () => {
await press(Keys.ArrowUp) // Up again
assertActiveElement(getByText('Home delivery'))
})

it('should be possible to disable a RadioGroup', async () => {
let changeFn = jest.fn()

function Example() {
let [disabled, setDisabled] = useState(true)
return (
<>
<button onClick={() => setDisabled(v => !v)}>Toggle</button>
<RadioGroup value={undefined} onChange={changeFn} disabled={disabled}>
<RadioGroup.Label>Pizza Delivery</RadioGroup.Label>
<RadioGroup.Option value="pickup">Pickup</RadioGroup.Option>
<RadioGroup.Option value="home-delivery">Home delivery</RadioGroup.Option>
<RadioGroup.Option value="dine-in">Dine in</RadioGroup.Option>
<RadioGroup.Option value="render-prop" data-value="render-prop">
{JSON.stringify}
</RadioGroup.Option>
</RadioGroup>
</>
)
}

render(<Example />)

// Try to click one a few options
await click(getByText('Pickup'))
await click(getByText('Dine in'))

// Verify that the RadioGroup.Option gets the disabled state
expect(document.querySelector('[data-value="render-prop"]')).toHaveTextContent(
JSON.stringify({
checked: false,
disabled: true,
active: false,
})
)

// Make sure that the onChange handler never got called
expect(changeFn).toHaveBeenCalledTimes(0)

// Toggle the disabled state
await click(getByText('Toggle'))

// Verify that the RadioGroup.Option gets the disabled state
expect(document.querySelector('[data-value="render-prop"]')).toHaveTextContent(
JSON.stringify({
checked: false,
disabled: false,
active: false,
})
)

// Try to click one a few options
await click(getByText('Pickup'))

// Make sure that the onChange handler got called
expect(changeFn).toHaveBeenCalledTimes(1)
})

it('should be possible to disable a RadioGroup.Option', async () => {
let changeFn = jest.fn()

function Example() {
let [disabled, setDisabled] = useState(true)
return (
<>
<button onClick={() => setDisabled(v => !v)}>Toggle</button>
<RadioGroup value={undefined} onChange={changeFn}>
<RadioGroup.Label>Pizza Delivery</RadioGroup.Label>
<RadioGroup.Option value="pickup">Pickup</RadioGroup.Option>
<RadioGroup.Option value="home-delivery">Home delivery</RadioGroup.Option>
<RadioGroup.Option value="dine-in">Dine in</RadioGroup.Option>
<RadioGroup.Option value="render-prop" disabled={disabled} data-value="render-prop">
{JSON.stringify}
</RadioGroup.Option>
</RadioGroup>
</>
)
}

render(<Example />)

// Try to click the disabled option
await click(document.querySelector('[data-value="render-prop"]'))

// Verify that the RadioGroup.Option gets the disabled state
expect(document.querySelector('[data-value="render-prop"]')).toHaveTextContent(
JSON.stringify({
checked: false,
disabled: true,
active: false,
})
)

// Make sure that the onChange handler never got called
expect(changeFn).toHaveBeenCalledTimes(0)

// Toggle the disabled state
await click(getByText('Toggle'))

// Verify that the RadioGroup.Option gets the disabled state
expect(document.querySelector('[data-value="render-prop"]')).toHaveTextContent(
JSON.stringify({
checked: false,
disabled: false,
active: false,
})
)

// Try to click one a few options
await click(document.querySelector('[data-value="render-prop"]'))

// Make sure that the onChange handler got called
expect(changeFn).toHaveBeenCalledTimes(1)
})
})

describe('Keyboard interactions', () => {
Expand Down
Loading

0 comments on commit ce1d764

Please sign in to comment.