refactor, aria props

This commit is contained in:
Tom Moor
2019-10-12 21:08:04 -07:00
parent 8ea1323a7c
commit 5eb384b2c8
2 changed files with 25 additions and 7 deletions

View File

@ -11,6 +11,7 @@ import { fadeAndScaleIn } from 'shared/styles/animations';
import NudeButton from 'components/NudeButton'; import NudeButton from 'components/NudeButton';
let previousClosePortal; let previousClosePortal;
let counter = 0;
type Children = type Children =
| React.Node | React.Node
@ -28,6 +29,8 @@ type Props = {
@observer @observer
class DropdownMenu extends React.Component<Props> { class DropdownMenu extends React.Component<Props> {
id: number = `menu${counter++}`;
@observable top: ?number; @observable top: ?number;
@observable bottom: ?number; @observable bottom: ?number;
@observable right: ?number; @observable right: ?number;
@ -37,6 +40,7 @@ class DropdownMenu extends React.Component<Props> {
@observable bodyRect: ClientRect; @observable bodyRect: ClientRect;
@observable labelRect: ClientRect; @observable labelRect: ClientRect;
@observable dropdownRef: { current: null | HTMLElement } = React.createRef(); @observable dropdownRef: { current: null | HTMLElement } = React.createRef();
@observable menuRef: { current: null | HTMLElement } = React.createRef();
handleOpen = ( handleOpen = (
openPortal: (SyntheticEvent<>) => void, openPortal: (SyntheticEvent<>) => void,
@ -88,12 +92,12 @@ class DropdownMenu extends React.Component<Props> {
} }
} }
onOpen(originalFunction?: () => void) { onOpen = () => {
if (typeof originalFunction === 'function') { if (typeof this.props.onOpen === 'function') {
originalFunction(); this.props.onOpen();
} }
this.fitOnTheScreen(); this.fitOnTheScreen();
} };
fitOnTheScreen() { fitOnTheScreen() {
if (!this.dropdownRef || !this.dropdownRef.current) return; if (!this.dropdownRef || !this.dropdownRef.current) return;
@ -135,16 +139,21 @@ class DropdownMenu extends React.Component<Props> {
return ( return (
<div className={className}> <div className={className}>
<PortalWithState <PortalWithState
onOpen={this.onOpen.bind(this, this.props.onOpen)} onOpen={this.onOpen}
onClose={this.props.onClose} onClose={this.props.onClose}
closeOnOutsideClick closeOnOutsideClick
closeOnEsc closeOnEsc
> >
{({ closePortal, openPortal, portal }) => ( {({ closePortal, openPortal, isOpen, portal }) => (
<React.Fragment> <React.Fragment>
<Label onClick={this.handleOpen(openPortal, closePortal)}> <Label onClick={this.handleOpen(openPortal, closePortal)}>
{label || ( {label || (
<NudeButton> <NudeButton
id={`${this.id}button`}
aria-haspopup="true"
aria-expanded={isOpen ? 'true' : 'false'}
aria-controls={this.id}
>
<MoreIcon /> <MoreIcon />
</NudeButton> </NudeButton>
)} )}
@ -160,6 +169,7 @@ class DropdownMenu extends React.Component<Props> {
right={this.right} right={this.right}
> >
<Menu <Menu
ref={this.menuRef}
onClick={ onClick={
typeof children === 'function' typeof children === 'function'
? undefined ? undefined
@ -169,6 +179,9 @@ class DropdownMenu extends React.Component<Props> {
} }
} }
style={this.props.style} style={this.props.style}
id={this.id}
aria-labelledby={`${this.id}button`}
role="menu"
> >
{typeof children === 'function' {typeof children === 'function'
? children({ closePortal }) ? children({ closePortal })

View File

@ -1,6 +1,7 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { lighten } from 'polished';
type Props = { type Props = {
onClick?: (SyntheticEvent<>) => void | Promise<void>, onClick?: (SyntheticEvent<>) => void | Promise<void>,
@ -13,6 +14,8 @@ const DropdownMenuItem = ({ onClick, children, disabled, ...rest }: Props) => {
<MenuItem <MenuItem
onClick={disabled ? undefined : onClick} onClick={disabled ? undefined : onClick}
disabled={disabled} disabled={disabled}
role="menuitem"
tabIndex="-1"
{...rest} {...rest}
> >
{children} {children}
@ -32,6 +35,7 @@ const MenuItem = styled.a`
align-items: center; align-items: center;
font-size: 15px; font-size: 15px;
cursor: default; cursor: default;
user-select: none;
svg:not(:last-child) { svg:not(:last-child) {
margin-right: 8px; margin-right: 8px;
@ -49,6 +53,7 @@ const MenuItem = styled.a`
&:hover { &:hover {
color: ${props.theme.white}; color: ${props.theme.white};
background: ${props.theme.primary}; background: ${props.theme.primary};
box-shadow: none;
cursor: pointer; cursor: pointer;
svg { svg {