fix: Improve accessibility of buttons / tab indexes with tooltips

This commit is contained in:
Tom Moor
2019-08-29 00:06:21 -07:00
parent 579eaf325b
commit 140f009b4d
4 changed files with 43 additions and 27 deletions

View File

@ -1,7 +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 { darken } from 'polished'; import { darken, lighten } from 'polished';
import { ExpandedIcon } from 'outline-icons'; import { ExpandedIcon } from 'outline-icons';
const RealButton = styled.button` const RealButton = styled.button`
@ -35,6 +35,13 @@ const RealButton = styled.button`
background: ${props => darken(0.05, props.theme.buttonBackground)}; background: ${props => darken(0.05, props.theme.buttonBackground)};
} }
&:focus {
transition-duration: 0.05s;
box-shadow: ${props => lighten(0.4, props.theme.buttonBackground)} 0px 0px
0px 3px;
outline: none;
}
&:disabled { &:disabled {
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
@ -98,22 +105,24 @@ export type Props = {
icon?: React.Node, icon?: React.Node,
className?: string, className?: string,
children?: React.Node, children?: React.Node,
innerRef?: React.ElementRef<any>,
disclosure?: boolean, disclosure?: boolean,
}; };
export default function Button({ function Button({
type = 'text', type = 'text',
icon, icon,
children, children,
value, value,
disclosure, disclosure,
innerRef,
...rest ...rest
}: Props) { }: Props) {
const hasText = children !== undefined || value !== undefined; const hasText = children !== undefined || value !== undefined;
const hasIcon = icon !== undefined; const hasIcon = icon !== undefined;
return ( return (
<RealButton type={type} {...rest}> <RealButton type={type} ref={innerRef} {...rest}>
<Inner hasIcon={hasIcon} disclosure={disclosure}> <Inner hasIcon={hasIcon} disclosure={disclosure}>
{hasIcon && icon} {hasIcon && icon}
{hasText && <Label hasIcon={hasIcon}>{children || value}</Label>} {hasText && <Label hasIcon={hasIcon}>{children || value}</Label>}
@ -122,3 +131,8 @@ export default function Button({
</RealButton> </RealButton>
); );
} }
// $FlowFixMe - need to upgrade to get forwardRef
export default React.forwardRef((props, ref) => (
<Button {...props} innerRef={ref} />
));

View File

@ -140,6 +140,12 @@ const StyledNavLink = styled(NavLink)`
color: ${props => props.theme.text}; color: ${props => props.theme.text};
} }
&:focus {
color: ${props => props.theme.text};
background: ${props => props.theme.sidebarItemBackground};
outline: none;
}
&:hover { &:hover {
> ${Action} { > ${Action} {
display: inline; display: inline;

View File

@ -10,7 +10,6 @@ type Props = {
children: React.Node, children: React.Node,
delay?: number, delay?: number,
className?: string, className?: string,
block?: boolean,
}; };
class Tooltip extends React.Component<Props> { class Tooltip extends React.Component<Props> {
@ -19,16 +18,7 @@ class Tooltip extends React.Component<Props> {
} }
render() { render() {
const { const { shortcut, tooltip, delay = 50, className, ...rest } = this.props;
shortcut,
tooltip,
delay = 50,
children,
block,
className,
...rest
} = this.props;
const Component = block ? 'div' : 'span';
let content = tooltip; let content = tooltip;
@ -50,9 +40,7 @@ class Tooltip extends React.Component<Props> {
duration={[200, 150]} duration={[200, 150]}
inertia inertia
{...rest} {...rest}
> />
<Component className={className}>{children}</Component>
</StyledTippy>
); );
} }
} }

View File

@ -2,6 +2,7 @@
import * as React from 'react'; import * as React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import breakpoint from 'styled-components-breakpoint'; import breakpoint from 'styled-components-breakpoint';
import { lighten } from 'polished';
import { observable } from 'mobx'; import { observable } from 'mobx';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { KeyboardIcon } from 'outline-icons'; import { KeyboardIcon } from 'outline-icons';
@ -33,17 +34,16 @@ class KeyboardShortcutsButton extends React.Component<Props> {
> >
<KeyboardShortcuts /> <KeyboardShortcuts />
</Modal> </Modal>
<Button onClick={this.handleOpenKeyboardShortcuts}>
<Tooltip <Tooltip
tooltip="Keyboard shortcuts" tooltip="Keyboard shortcuts"
shortcut="?" shortcut="?"
placement="left" placement="left"
delay={500} delay={500}
block
> >
<Button onClick={this.handleOpenKeyboardShortcuts}>
<KeyboardIcon /> <KeyboardIcon />
</Tooltip>
</Button> </Button>
</Tooltip>
</React.Fragment> </React.Fragment>
); );
} }
@ -59,6 +59,7 @@ const Button = styled.button`
height: 24px; height: 24px;
opacity: 0.8; opacity: 0.8;
background: none; background: none;
border-radius: 4px;
line-height: 0; line-height: 0;
border: 0; border: 0;
padding: 0; padding: 0;
@ -67,6 +68,13 @@ const Button = styled.button`
opacity: 1; opacity: 1;
} }
&:focus {
transition-duration: 0.05s;
box-shadow: ${props => lighten(0.4, props.theme.buttonBackground)} 0px 0px
0px 3px;
outline: none;
}
${breakpoint('tablet')` ${breakpoint('tablet')`
display: block; display: block;
`}; `};