Skip to content

Commit f451dbf

Browse files
author
chenyueban
committed
feat(Radio): Complete the basic props of the Radio
1 parent 9d43174 commit f451dbf

11 files changed

Lines changed: 317 additions & 1 deletion

File tree

packages/fluent-ui.com/src/docs/components/Checkbox/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ components: Checkbox
2222
## Disabled
2323

2424
```jsx
25-
<Checkbox disabled/>
25+
<>
26+
<Checkbox disabled />
27+
<Checkbox disabled checked/>
28+
</>
2629
```
2730

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: Radio
3+
components: Radio
4+
---
5+
6+
# Radio
7+
8+
## Default
9+
10+
```jsx
11+
() => {
12+
const [checked, set] = React.useState('a')
13+
function handleChange(c) {
14+
set(c)
15+
}
16+
return (
17+
<>
18+
<Radio value='a' checked={checked === 'a'} onChange={handleChange} />
19+
<Radio value='b' checked={checked === 'b'} onChange={handleChange} />
20+
<Radio value='c' checked={checked === 'c'} onChange={handleChange} />
21+
</>
22+
)
23+
}
24+
```
25+
26+
## Disabled
27+
28+
```jsx
29+
<>
30+
<Radio disabled />
31+
<Radio disabled checked />
32+
</>
33+
```
34+

packages/fluent-ui/src/Checkbox/Checkbox.styled.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ const disabled = variant({
2323
variants: {
2424
true: css`
2525
border-color: ${th.color('primary.dark3')};
26+
background-color: transparent;
27+
color: ${th.color('primary.dark3')};
28+
cursor: not-allowed;
29+
pointer-events: none;
2630
`,
2731
false: css``
2832
}

packages/fluent-ui/src/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ exports[`Checkbox prop disabled 1`] = `
8080
background-color: transparent;
8181
border-color: #cccccc;
8282
border-color: #7a7a7a;
83+
background-color: transparent;
84+
color: #7a7a7a;
85+
cursor: not-allowed;
86+
pointer-events: none;
8387
}
8488
8589
.c0:hover {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { styled, css, th, variant } from '../styles/styled'
2+
3+
const checked = variant({
4+
prop: 'checked',
5+
default: false,
6+
variants: {
7+
true: css`
8+
color: ${th.color('white.default')};
9+
border-color: ${th.color('accent.default')};
10+
&:hover {
11+
border-color: ${th.color('accent.default')};
12+
}
13+
`,
14+
false: css`
15+
color: ${th.color('black.default')};
16+
border-color: ${th.color('primary.default')};
17+
`
18+
}
19+
})
20+
21+
const disabled = variant({
22+
prop: 'disabled',
23+
default: false,
24+
variants: {
25+
true: css`
26+
border-color: ${th.color('primary.dark3')};
27+
cursor: not-allowed;
28+
pointer-events: none;
29+
`,
30+
false: css``
31+
}
32+
})
33+
34+
export const StyledRadioWrapper = styled.div<{
35+
checked?: boolean
36+
disabled?: boolean
37+
}>`
38+
width: 20px;
39+
height: 20px;
40+
border-radius: 50%;
41+
position: relative;
42+
display: flex;
43+
justify-content: center;
44+
align-items: center;
45+
border: 2px solid;
46+
transition: ${th.transition('radio')};
47+
&:hover {
48+
border-color: ${th.color('primary.dark3')};
49+
}
50+
51+
${checked}
52+
${disabled}
53+
`
54+
55+
export const StyledRadio = styled.input`
56+
width: 100%;
57+
height: 100%;
58+
opacity: 0;
59+
position: absolute;
60+
left: 0;
61+
right: 0;
62+
top: 0;
63+
bottom: 0;
64+
cursor: ${({ disabled }): string => (disabled ? 'not-allowed' : 'pointer')};
65+
`
66+
67+
export const StyledCircle = styled.div<{ disabled?: boolean }>`
68+
width: 12px;
69+
height: 12px;
70+
border-radius: 50%;
71+
transition: ${th.transition('radio')};
72+
background-color: ${({ disabled }): string =>
73+
disabled ? th.color('primary.dark3') : th.color('black.default')};
74+
`
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from 'react'
2+
import { StyledRadioWrapper, StyledRadio, StyledCircle } from './Radio.styled'
3+
4+
interface RadioProps {
5+
checked?: boolean
6+
value?: string
7+
onChange?: (checked: string) => void
8+
disabled?: boolean
9+
}
10+
11+
const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
12+
(
13+
{ checked, value, onChange, disabled }: RadioProps,
14+
ref
15+
): React.ReactElement => {
16+
function handleChange(e: React.ChangeEvent<HTMLInputElement>): void {
17+
onChange && onChange(e.target.value)
18+
}
19+
return (
20+
<StyledRadioWrapper checked={checked} disabled={disabled}>
21+
{checked && <StyledCircle disabled={disabled} />}
22+
<StyledRadio
23+
ref={ref}
24+
type="radio"
25+
checked={checked}
26+
value={value}
27+
onChange={handleChange}
28+
disabled={disabled}
29+
/>
30+
</StyledRadioWrapper>
31+
)
32+
}
33+
)
34+
35+
Radio.displayName = 'FRadio'
36+
37+
export default Radio
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as React from 'react'
2+
import * as renderer from 'react-test-renderer'
3+
import * as ReactTestUtils from 'react-dom/test-utils'
4+
import 'jest-styled-components'
5+
6+
import { ThemeProvider, Radio } from '../..'
7+
8+
describe('Radio', (): void => {
9+
const theme = {}
10+
11+
test('basic', (): void => {
12+
const component = renderer.create(
13+
<ThemeProvider theme={theme}>
14+
<Radio />
15+
</ThemeProvider>
16+
)
17+
const tree = component.toJSON()
18+
expect(tree).toMatchSnapshot()
19+
})
20+
21+
test('controlled', (): void => {
22+
let node = React.createRef<HTMLInputElement>()
23+
let checked = ''
24+
function handleChange(c: string): void {
25+
checked = c
26+
}
27+
ReactTestUtils.renderIntoDocument(
28+
<ThemeProvider theme={theme}>
29+
<Radio ref={node} value="a" onChange={handleChange} />
30+
</ThemeProvider>
31+
)
32+
;(node.current as HTMLInputElement).checked = true
33+
ReactTestUtils.Simulate.change(node.current as HTMLInputElement)
34+
expect(checked).toEqual('a')
35+
})
36+
37+
test('prop disabled', (): void => {
38+
const component = renderer.create(
39+
<ThemeProvider theme={theme}>
40+
<Radio disabled={true} />
41+
</ThemeProvider>
42+
)
43+
const tree = component.toJSON()
44+
expect(tree).toMatchSnapshot()
45+
})
46+
})
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Radio basic 1`] = `
4+
.c0 {
5+
width: 20px;
6+
height: 20px;
7+
border-radius: 50%;
8+
position: relative;
9+
display: -webkit-box;
10+
display: -webkit-flex;
11+
display: -ms-flexbox;
12+
display: flex;
13+
-webkit-box-pack: center;
14+
-webkit-justify-content: center;
15+
-ms-flex-pack: center;
16+
justify-content: center;
17+
-webkit-align-items: center;
18+
-webkit-box-align: center;
19+
-ms-flex-align: center;
20+
align-items: center;
21+
border: 2px solid;
22+
-webkit-transition: all 250ms cubic-bezier(0.4,0,0.2,1) 0ms;
23+
transition: all 250ms cubic-bezier(0.4,0,0.2,1) 0ms;
24+
color: #000000;
25+
border-color: #cccccc;
26+
}
27+
28+
.c0:hover {
29+
border-color: #7a7a7a;
30+
}
31+
32+
.c1 {
33+
width: 100%;
34+
height: 100%;
35+
opacity: 0;
36+
position: absolute;
37+
left: 0;
38+
right: 0;
39+
top: 0;
40+
bottom: 0;
41+
cursor: pointer;
42+
}
43+
44+
<div
45+
className="c0"
46+
>
47+
<input
48+
className="c1"
49+
onChange={[Function]}
50+
type="radio"
51+
/>
52+
</div>
53+
`;
54+
55+
exports[`Radio prop disabled 1`] = `
56+
.c0 {
57+
width: 20px;
58+
height: 20px;
59+
border-radius: 50%;
60+
position: relative;
61+
display: -webkit-box;
62+
display: -webkit-flex;
63+
display: -ms-flexbox;
64+
display: flex;
65+
-webkit-box-pack: center;
66+
-webkit-justify-content: center;
67+
-ms-flex-pack: center;
68+
justify-content: center;
69+
-webkit-align-items: center;
70+
-webkit-box-align: center;
71+
-ms-flex-align: center;
72+
align-items: center;
73+
border: 2px solid;
74+
-webkit-transition: all 250ms cubic-bezier(0.4,0,0.2,1) 0ms;
75+
transition: all 250ms cubic-bezier(0.4,0,0.2,1) 0ms;
76+
color: #000000;
77+
border-color: #cccccc;
78+
border-color: #7a7a7a;
79+
cursor: not-allowed;
80+
pointer-events: none;
81+
}
82+
83+
.c0:hover {
84+
border-color: #7a7a7a;
85+
}
86+
87+
.c1 {
88+
width: 100%;
89+
height: 100%;
90+
opacity: 0;
91+
position: absolute;
92+
left: 0;
93+
right: 0;
94+
top: 0;
95+
bottom: 0;
96+
cursor: not-allowed;
97+
}
98+
99+
<div
100+
className="c0"
101+
disabled={true}
102+
>
103+
<input
104+
className="c1"
105+
disabled={true}
106+
onChange={[Function]}
107+
type="radio"
108+
/>
109+
</div>
110+
`;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Radio'

packages/fluent-ui/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { default as Box } from './Box'
22
export { default as Button } from './Button'
33
export { default as Input } from './Input'
44
export { default as Checkbox } from './Checkbox'
5+
export { default as Radio } from './Radio'
56
export { default as Command } from './Command'
67
export { default as CommandButton } from './CommandButton'
78
export { default as Navigation } from './Navigation'

0 commit comments

Comments
 (0)