Newer
Older
import styled from 'styled-components'
// TODO: match the width of the container to the width of the widest option?
const Root = styled.div`
font-size: 1em;
`
const Label = styled.span`
display: block;
font-size: 1em;
margin-bottom: 0.5em;
`
const OpenerContainer = styled.div``
const Opener = styled.button.attrs({
type: 'button',
})`
background: transparent;
border: none;
cursor: pointer;
font-family: inherit;
font-size: 1.2em;
border-left: 2px solid
${props => (props.open ? 'var(--color-primary)' : 'lightgrey')};
color: ${props => (props.open ? 'var(--color-primary)' : 'inherit')};
&:hover {
border-left: 2px solid var(--color-primary);
color: var(--color-primary);
}
`
const Placeholder = styled.span`
font-family: var(--font-interface);
font-style: italic;
font-weight: 400;
text-transform: normal;
color: #aaa;
&:hover {
color: var(--color-primary);
}
`
const Arrow = styled.span`
display: inline-block;
font-size: 50%;
margin-left: 10px;
transition: transform 0.2s;
transform: scaleX(2.2) scaleY(${props => (props.open ? -1.2 : 1.2)});
`
const Main = styled.div.attrs({
role: 'listbox',
})`
position: relative;
`
const OptionsContainer = styled.div`
position: absolute;
`
const Options = styled.div`
background-color: white;
border-bottom: 2px solid var(--color-primary);
border-left: 2px solid var(--color-primary);
left: 0;
padding-bottom: 0.5em;
padding-top: 0.5em;
position: absolute;
top: 0;
transition: opacity 2s;
width: 0;
z-index: 10;
min-width: ${props => (props.open ? '10em' : '0')};
opacity: ${props => (props.open ? '1' : '0')};
`
const Option = styled.div.attrs({
role: 'option',
tabIndex: '0',
'aria-selected': props => props.active,
})`
color: ${props => (props.active ? 'black' : '#444')};
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
font-weight: ${props => (props.active ? '600' : 'inherit')};
cursor: pointer;
font-family: var(--font-author);
padding: 10px;
white-space: nowrap;
&:hover {
color: var(--color-primary);
}
`
/* Not used for now
.inline {
align-items: flex-end;
display: flex;
flex-direction: row;
justify-content: flex-start;
margin-right: 0.5em;
}
.inline .label {
margin-right: 0.5em;
}
.inline .opener {
margin-bottom: -4px;
}
.root .inline {
flex-direction: columns;
}
.root.author {
font-family: var(--font-author);
}
*/
class Menu extends React.Component {
super(props)
this.state = {
open: false,
handleKeyPress = (event, selected) => {
if (event.which === 13) {
this.handleSelect(selected)
}
}
const { options } = this.props
return options.find(option => option.value === value).label
}
const { label, options, placeholder = 'Choose in the list' } = this.props
const { open, selected } = this.state
return (
<Root open={open}>
{label && <Label>{label}</Label>}
<Main>
<OpenerContainer>
<Opener onClick={this.toggleMenu} open={open}>
{selected ? (
<span>{this.optionLabel(selected)}</span>
) : (
<Placeholder>{placeholder}</Placeholder>
</Opener>
</OpenerContainer>
<Option
active={option.value === selected}
onClick={() => this.handleSelect(option.value)}
onKeyPress={event =>
this.handleKeyPress(event, option.value)
}
</OptionsContainer>
</Main>
</Root>