add menu variant of Radio

This commit is contained in:
Artur Bień
2020-02-21 21:06:04 +01:00
parent 847f058e1d
commit 615637eabf
3 changed files with 118 additions and 9 deletions

View File

@@ -5,7 +5,7 @@ import styled from 'styled-components';
import { createDisabledTextStyles } from '../common';
import { padding, blockSizes } from '../common/system';
const StyledListItem = styled.li`
export const StyledListItem = styled.li`
box-sizing: border-box;
display: flex;

View File

@@ -5,6 +5,7 @@ import styled, { css } from 'styled-components';
import { createDisabledTextStyles, createFlatBoxStyles } from '../common';
import { padding, fontSizes } from '../common/system';
import Cutout from '../Cutout/Cutout';
import { StyledListItem } from '../ListItem/ListItem';
const radioSize = '20px';
const StyledLabel = styled.label`
@@ -19,6 +20,11 @@ const StyledLabel = styled.label`
user-select: none;
font-size: ${fontSizes.md};
${props => props.isDisabled && createDisabledTextStyles()}
${StyledListItem}:hover & {
margin: 0;
height: 100%;
}
`;
const StyledInput = styled.input`
@@ -75,6 +81,15 @@ const StyledFlatCheckbox = styled.div`
border-radius: 50%;
}
`;
const StyledMenuCheckbox = styled.div`
${sharedCheckboxStyles}
position: relative;
display: inline-block;
box-sizing: border-box;
border: none;
outline: none;
background: none;
`;
const Icon = styled.span.attrs(() => ({
'data-testid': 'checkmarkIcon'
}))`
@@ -87,8 +102,25 @@ const Icon = styled.span.attrs(() => ({
height: 6px;
transform: translate(-50%, -50%);
border-radius: 50%;
background: ${({ theme, isDisabled }) =>
isDisabled ? theme.checkmarkDisabled : theme.checkmark};
${({ variant, theme, isDisabled }) =>
variant === 'menu'
? css`
background: ${isDisabled ? theme.textDisabled : theme.text};
filter: drop-shadow(
1px 1px 0px ${isDisabled ? theme.textDisabledShadow : 'transparent'}
);
`
: css`
background: ${isDisabled ? theme.checkmarkDisabled : theme.checkmark};
`}
${StyledListItem}:hover & {
${({ theme, isDisabled, variant }) =>
!isDisabled &&
variant === 'menu' &&
css`
background: ${theme.textInvert};
`};
}
`;
const LabelText = styled.span`
display: inline-block;
@@ -108,8 +140,12 @@ const Radio = React.forwardRef(function Radio(props, ref) {
style,
...otherProps
} = props;
const CheckboxComponent =
variant === 'flat' ? StyledFlatCheckbox : StyledCheckbox;
const CheckboxComponent = {
flat: StyledFlatCheckbox,
default: StyledCheckbox,
menu: StyledMenuCheckbox
}[variant];
return (
<StyledLabel isDisabled={disabled} className={className} style={style}>
@@ -118,7 +154,7 @@ const Radio = React.forwardRef(function Radio(props, ref) {
isDisabled={disabled}
role='presentation'
>
{checked && <Icon isDisabled={disabled} />}
{checked && <Icon isDisabled={disabled} variant={variant} />}
</CheckboxComponent>
{label && <LabelText>{label}</LabelText>}
<StyledInput
@@ -159,7 +195,7 @@ Radio.propTypes = {
label: propTypes.oneOfType([propTypes.string, propTypes.number]),
checked: propTypes.bool,
disabled: propTypes.bool,
variant: propTypes.oneOf(['default', 'flat']),
variant: propTypes.oneOf(['default', 'flat', 'menu']),
style: propTypes.shape([propTypes.string, propTypes.number]),
className: propTypes.string
};

View File

@@ -1,7 +1,16 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import styled from 'styled-components';
import { Radio, Cutout, Fieldset, Window, WindowContent } from '..';
import {
Radio,
Cutout,
Fieldset,
Window,
WindowContent,
List,
ListItem,
Divider
} from '..';
storiesOf('Radio', module)
.addDecorator(story => (
@@ -15,7 +24,8 @@ storiesOf('Radio', module)
</div>
))
.add('default', () => <RadioGroup />)
.add('flat', () => <FlatRadioGroup />);
.add('flat', () => <FlatRadioGroup />)
.add('menu', () => <MenuRadioGroup />);
class RadioGroup extends React.Component {
state = {
@@ -136,6 +146,69 @@ class FlatRadioGroup extends React.Component {
}
}
class MenuRadioGroup extends React.Component {
state = {
tool: 'Brush',
color: 'Black'
};
handleToolChange = e => this.setState({ tool: e.target.value });
handleColorChange = e => this.setState({ color: e.target.value });
render() {
const { tool, color } = this.state;
return (
<List>
<ListItem size='sm'>
<Radio
variant='menu'
checked={tool === 'Brush'}
onChange={this.handleToolChange}
value='Brush'
label='Brush'
name='tool'
/>
</ListItem>
<ListItem size='sm'>
<Radio
variant='menu'
checked={tool === 'Pencil'}
onChange={this.handleToolChange}
value='Pencil'
label='Pencil'
name='tool'
/>
</ListItem>
<Divider />
<ListItem size='sm' disabled>
<Radio
disabled
variant='menu'
checked={color === 'Black'}
onChange={this.handleColorChange}
value='Black'
label='Black'
name='color'
/>
</ListItem>
<ListItem size='sm' disabled>
<Radio
disabled
variant='menu'
checked={color === 'Red'}
onChange={this.handleColorChange}
value='Red'
label='Red'
name='color'
/>
</ListItem>
</List>
);
}
}
const StyledCutout = styled(Cutout)`
background: ${({ theme }) => theme.canvas};
color: ${({ theme }) => theme.text};