Skip to content

Commit 615637e

Browse files
committed
add menu variant of Radio
1 parent 847f058 commit 615637e

File tree

3 files changed

+118
-9
lines changed

3 files changed

+118
-9
lines changed

src/components/ListItem/ListItem.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import styled from 'styled-components';
55
import { createDisabledTextStyles } from '../common';
66
import { padding, blockSizes } from '../common/system';
77

8-
const StyledListItem = styled.li`
8+
export const StyledListItem = styled.li`
99
box-sizing: border-box;
1010
1111
display: flex;

src/components/Radio/Radio.js

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import styled, { css } from 'styled-components';
55
import { createDisabledTextStyles, createFlatBoxStyles } from '../common';
66
import { padding, fontSizes } from '../common/system';
77
import Cutout from '../Cutout/Cutout';
8+
import { StyledListItem } from '../ListItem/ListItem';
89

910
const radioSize = '20px';
1011
const StyledLabel = styled.label`
@@ -19,6 +20,11 @@ const StyledLabel = styled.label`
1920
user-select: none;
2021
font-size: ${fontSizes.md};
2122
${props => props.isDisabled && createDisabledTextStyles()}
23+
24+
${StyledListItem}:hover & {
25+
margin: 0;
26+
height: 100%;
27+
}
2228
`;
2329

2430
const StyledInput = styled.input`
@@ -75,6 +81,15 @@ const StyledFlatCheckbox = styled.div`
7581
border-radius: 50%;
7682
}
7783
`;
84+
const StyledMenuCheckbox = styled.div`
85+
${sharedCheckboxStyles}
86+
position: relative;
87+
display: inline-block;
88+
box-sizing: border-box;
89+
border: none;
90+
outline: none;
91+
background: none;
92+
`;
7893
const Icon = styled.span.attrs(() => ({
7994
'data-testid': 'checkmarkIcon'
8095
}))`
@@ -87,8 +102,25 @@ const Icon = styled.span.attrs(() => ({
87102
height: 6px;
88103
transform: translate(-50%, -50%);
89104
border-radius: 50%;
90-
background: ${({ theme, isDisabled }) =>
91-
isDisabled ? theme.checkmarkDisabled : theme.checkmark};
105+
${({ variant, theme, isDisabled }) =>
106+
variant === 'menu'
107+
? css`
108+
background: ${isDisabled ? theme.textDisabled : theme.text};
109+
filter: drop-shadow(
110+
1px 1px 0px ${isDisabled ? theme.textDisabledShadow : 'transparent'}
111+
);
112+
`
113+
: css`
114+
background: ${isDisabled ? theme.checkmarkDisabled : theme.checkmark};
115+
`}
116+
${StyledListItem}:hover & {
117+
${({ theme, isDisabled, variant }) =>
118+
!isDisabled &&
119+
variant === 'menu' &&
120+
css`
121+
background: ${theme.textInvert};
122+
`};
123+
}
92124
`;
93125
const LabelText = styled.span`
94126
display: inline-block;
@@ -108,8 +140,12 @@ const Radio = React.forwardRef(function Radio(props, ref) {
108140
style,
109141
...otherProps
110142
} = props;
111-
const CheckboxComponent =
112-
variant === 'flat' ? StyledFlatCheckbox : StyledCheckbox;
143+
144+
const CheckboxComponent = {
145+
flat: StyledFlatCheckbox,
146+
default: StyledCheckbox,
147+
menu: StyledMenuCheckbox
148+
}[variant];
113149

114150
return (
115151
<StyledLabel isDisabled={disabled} className={className} style={style}>
@@ -118,7 +154,7 @@ const Radio = React.forwardRef(function Radio(props, ref) {
118154
isDisabled={disabled}
119155
role='presentation'
120156
>
121-
{checked && <Icon isDisabled={disabled} />}
157+
{checked && <Icon isDisabled={disabled} variant={variant} />}
122158
</CheckboxComponent>
123159
{label && <LabelText>{label}</LabelText>}
124160
<StyledInput
@@ -159,7 +195,7 @@ Radio.propTypes = {
159195
label: propTypes.oneOfType([propTypes.string, propTypes.number]),
160196
checked: propTypes.bool,
161197
disabled: propTypes.bool,
162-
variant: propTypes.oneOf(['default', 'flat']),
198+
variant: propTypes.oneOf(['default', 'flat', 'menu']),
163199
style: propTypes.shape([propTypes.string, propTypes.number]),
164200
className: propTypes.string
165201
};

src/components/Radio/Radio.stories.js

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import React from 'react';
22
import { storiesOf } from '@storybook/react';
33
import styled from 'styled-components';
4-
import { Radio, Cutout, Fieldset, Window, WindowContent } from '..';
4+
import {
5+
Radio,
6+
Cutout,
7+
Fieldset,
8+
Window,
9+
WindowContent,
10+
List,
11+
ListItem,
12+
Divider
13+
} from '..';
514

615
storiesOf('Radio', module)
716
.addDecorator(story => (
@@ -15,7 +24,8 @@ storiesOf('Radio', module)
1524
</div>
1625
))
1726
.add('default', () => <RadioGroup />)
18-
.add('flat', () => <FlatRadioGroup />);
27+
.add('flat', () => <FlatRadioGroup />)
28+
.add('menu', () => <MenuRadioGroup />);
1929

2030
class RadioGroup extends React.Component {
2131
state = {
@@ -136,6 +146,69 @@ class FlatRadioGroup extends React.Component {
136146
}
137147
}
138148

149+
class MenuRadioGroup extends React.Component {
150+
state = {
151+
tool: 'Brush',
152+
color: 'Black'
153+
};
154+
155+
handleToolChange = e => this.setState({ tool: e.target.value });
156+
157+
handleColorChange = e => this.setState({ color: e.target.value });
158+
159+
render() {
160+
const { tool, color } = this.state;
161+
162+
return (
163+
<List>
164+
<ListItem size='sm'>
165+
<Radio
166+
variant='menu'
167+
checked={tool === 'Brush'}
168+
onChange={this.handleToolChange}
169+
value='Brush'
170+
label='Brush'
171+
name='tool'
172+
/>
173+
</ListItem>
174+
<ListItem size='sm'>
175+
<Radio
176+
variant='menu'
177+
checked={tool === 'Pencil'}
178+
onChange={this.handleToolChange}
179+
value='Pencil'
180+
label='Pencil'
181+
name='tool'
182+
/>
183+
</ListItem>
184+
<Divider />
185+
<ListItem size='sm' disabled>
186+
<Radio
187+
disabled
188+
variant='menu'
189+
checked={color === 'Black'}
190+
onChange={this.handleColorChange}
191+
value='Black'
192+
label='Black'
193+
name='color'
194+
/>
195+
</ListItem>
196+
<ListItem size='sm' disabled>
197+
<Radio
198+
disabled
199+
variant='menu'
200+
checked={color === 'Red'}
201+
onChange={this.handleColorChange}
202+
value='Red'
203+
label='Red'
204+
name='color'
205+
/>
206+
</ListItem>
207+
</List>
208+
);
209+
}
210+
}
211+
139212
const StyledCutout = styled(Cutout)`
140213
background: ${({ theme }) => theme.canvas};
141214
color: ${({ theme }) => theme.text};

0 commit comments

Comments
 (0)