Skip to content

Commit a434c9b

Browse files
author
Luke Bowerman
authored
Remove readOnly from Radio
1 parent e4510d9 commit a434c9b

File tree

7 files changed

+11
-106
lines changed

7 files changed

+11
-106
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3636

3737
### Changed
3838

39+
- `Radio` only sends `onChange` when state actually changes
3940
- `Field*` components no longer have a bottom margin by default (see `Form` update)
4041
- `Form` now acts as `SpaceVertical` component automatically putting a gap between each child item
4142
- `InputText` will now show red error icon when validation fails
4243

4344
### Removed
4445

46+
- `Radio` no longer supports `readOnly` (was nice to know you, albeit briefly)
4547
- `FieldInline` no longer supports `labelFontWeight`
4648

4749
## [0.7.27] - 2020-04-15

packages/components/src/Form/Fields/FieldRadio/__snapshots__/FieldRadio.test.tsx.snap

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,11 @@ exports[`A FieldRadio 1`] = `
120120
>
121121
<input
122122
aria-describedby="FieldRadioID-describedby"
123-
checked={false}
124123
id="FieldRadioID"
125124
name="thumbsUp"
126-
onChange={[Function]}
127-
onClick={[Function]}
128125
type="radio"
129126
/>
130127
<div
131-
checked={false}
132128
className="c5 c6"
133129
/>
134130
</div>
@@ -260,15 +256,12 @@ exports[`A FieldRadio checked 1`] = `
260256
>
261257
<input
262258
aria-describedby="FieldRadioID-describedby"
263-
checked={false}
259+
checked={true}
264260
id="FieldRadioID"
265261
name="thumbsUp"
266-
onChange={[Function]}
267-
onClick={[Function]}
268262
type="radio"
269263
/>
270264
<div
271-
checked={false}
272265
className="c5 c6"
273266
/>
274267
</div>

packages/components/src/Form/Inputs/Radio/FauxRadio.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,7 @@ import { reset } from '@looker/design-tokens'
2929

3030
const dotSize = 6
3131

32-
interface FauxRadioProps {
33-
checked: boolean
34-
}
35-
36-
export const FauxRadio = styled.div<FauxRadioProps>`
32+
export const FauxRadio = styled.div`
3733
${reset}
3834
position: relative;
3935
width: 100%;

packages/components/src/Form/Inputs/Radio/Radio.test.tsx

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import 'jest-styled-components'
2828
import React from 'react'
2929
import { assertSnapshot, renderWithTheme } from '@looker/components-test-utils'
3030
import { fireEvent } from '@testing-library/react'
31-
import { Radio, RadioProps } from './Radio'
31+
import { Radio } from './Radio'
3232

3333
test('Radio default', () => {
3434
assertSnapshot(<Radio id="radioID" />)
@@ -56,7 +56,6 @@ test('Radio with aria-describedby', () => {
5656

5757
test('Radio should trigger onChange handler', () => {
5858
const onChange = jest.fn()
59-
6059
const { getByRole } = renderWithTheme(
6160
<Radio id="radioID" onChange={onChange} />
6261
)
@@ -65,17 +64,3 @@ test('Radio should trigger onChange handler', () => {
6564
fireEvent.click(radioInput)
6665
expect(onChange).toHaveBeenCalledTimes(1)
6766
})
68-
69-
test("Radio readOnly doesn't register onChange events", () => {
70-
const mockProps: RadioProps = {
71-
onChange: jest.fn(),
72-
}
73-
74-
const { getByRole } = renderWithTheme(
75-
<Radio readOnly id="checkboxID" {...mockProps} />
76-
)
77-
78-
const checkboxInput = getByRole('radio')
79-
fireEvent.click(checkboxInput)
80-
expect(mockProps.onChange).toHaveBeenCalledTimes(0)
81-
})

packages/components/src/Form/Inputs/Radio/Radio.tsx

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,62 +24,28 @@
2424
2525
*/
2626

27-
import noop from 'lodash/noop'
2827
import pick from 'lodash/pick'
29-
import isUndefined from 'lodash/isUndefined'
30-
import React, { FormEvent, forwardRef, Ref, useEffect, useState } from 'react'
28+
import React, { forwardRef, Ref } from 'react'
3129
import styled from 'styled-components'
3230
import { reset, space, SpaceProps } from '@looker/design-tokens'
3331
import { InputProps, inputPropKeys } from '../InputProps'
3432
import { FauxRadio } from './FauxRadio'
3533

3634
export interface RadioProps
3735
extends SpaceProps,
38-
Omit<InputProps, 'type' | 'checked' | 'onClick'> {
36+
Omit<InputProps, 'readonly' | 'type' | 'checked' | 'onClick'> {
3937
checked?: boolean
4038
className?: string
4139
}
4240

4341
const RadioLayout = forwardRef(
4442
(props: RadioProps, ref: Ref<HTMLInputElement>) => {
45-
const {
46-
className,
47-
checked,
48-
defaultChecked,
49-
onChange,
50-
readOnly,
51-
...restProps
52-
} = props
53-
const [isChecked, setIsChecked] = useState(!!defaultChecked)
54-
55-
const handleClick = readOnly
56-
? undefined
57-
: (event: FormEvent<HTMLInputElement>) => {
58-
setIsChecked(true)
59-
if (onChange) {
60-
onChange(event)
61-
}
62-
}
63-
64-
// controlled component: update internal state when props.checked changes
65-
useEffect(() => {
66-
if (!isUndefined(checked)) {
67-
setIsChecked(checked)
68-
}
69-
}, [checked])
43+
const { className, ...restProps } = props
7044

7145
return (
7246
<div className={className}>
73-
<input
74-
type="radio"
75-
{...pick(restProps, inputPropKeys)}
76-
checked={isChecked}
77-
onChange={noop}
78-
// suppress read-only error as we rely on click rather than change event here
79-
onClick={handleClick}
80-
ref={ref}
81-
/>
82-
<FauxRadio checked={isChecked} />
47+
<input type="radio" {...pick(restProps, inputPropKeys)} ref={ref} />
48+
<FauxRadio />
8349
</div>
8450
)
8551
}

packages/components/src/Form/Inputs/Radio/__snapshots__/Radio.test.tsx.snap

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,9 @@ exports[`Radio checked set to false 1`] = `
7575
<input
7676
checked={false}
7777
id="radioID"
78-
onChange={[Function]}
79-
onClick={[Function]}
8078
type="radio"
8179
/>
8280
<div
83-
checked={false}
8481
className="c1 c2"
8582
/>
8683
</div>
@@ -159,14 +156,11 @@ exports[`Radio checked set to true 1`] = `
159156
className="c0"
160157
>
161158
<input
162-
checked={false}
159+
checked={true}
163160
id="radioID"
164-
onChange={[Function]}
165-
onClick={[Function]}
166161
type="radio"
167162
/>
168163
<div
169-
checked={false}
170164
className="c1 c2"
171165
/>
172166
</div>
@@ -245,14 +239,10 @@ exports[`Radio default 1`] = `
245239
className="c0"
246240
>
247241
<input
248-
checked={false}
249242
id="radioID"
250-
onChange={[Function]}
251-
onClick={[Function]}
252243
type="radio"
253244
/>
254245
<div
255-
checked={false}
256246
className="c1 c2"
257247
/>
258248
</div>
@@ -359,15 +349,11 @@ exports[`Radio should accept disabled 1`] = `
359349
className="c0"
360350
>
361351
<input
362-
checked={false}
363352
disabled={true}
364353
id="radioID"
365-
onChange={[Function]}
366-
onClick={[Function]}
367354
type="radio"
368355
/>
369356
<div
370-
checked={false}
371357
className="c1 c2"
372358
/>
373359
</div>
@@ -474,14 +460,10 @@ exports[`Radio with aria-describedby 1`] = `
474460
>
475461
<input
476462
aria-describedby="some-id"
477-
checked={false}
478463
id="radioID"
479-
onChange={[Function]}
480-
onClick={[Function]}
481464
type="radio"
482465
/>
483466
<div
484-
checked={false}
485467
className="c1 c2"
486468
/>
487469
</div>
@@ -560,15 +542,11 @@ exports[`Radio with name and id 1`] = `
560542
className="c0"
561543
>
562544
<input
563-
checked={false}
564545
id="Chuck"
565546
name="Chuck"
566-
onChange={[Function]}
567-
onClick={[Function]}
568547
type="radio"
569548
/>
570549
<div
571-
checked={false}
572550
className="c1 c2"
573551
/>
574552
</div>

packages/www/src/documentation/components/forms/radio.mdx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,3 @@ A name and ID can be specified in the `<Radio />` component. Radio buttons of th
4040
<Radio name="someName" id="three" value="three" />
4141
</Space>
4242
```
43-
44-
## ReadOnly property
45-
46-
`Radio` will ignore user-actions when the `readOnly` property is enabled, similar to `disabled` but without greying out the option.
47-
48-
NOTE: In HTML specifying `readonly` on _only_ prevents changes to `value` attribute of the checkbox and therefore allowing the user to still check and uncheck the checkbox.
49-
50-
In most cases we emulate the HTML specification where it has an existing decision or feature. However, the specification's behavior around checkboxes with a `readonly` attribute is rather unintuitive.
51-
52-
```jsx
53-
<Space>
54-
<Radio readOnly />
55-
<Radio readOnly checked />
56-
</Space>
57-
```

0 commit comments

Comments
 (0)