fix: Focus accessibility (#1536)
* fix: Focus ring appearing on click fix: Focus ring not appearing on sidebar links add: focus-visible polyfill * fix: More visible outlines on keyboard focus fix: Header block should be a button semantically
This commit is contained in:
parent
fc98cf78e6
commit
450d6b7e42
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import { ExpandedIcon } from "outline-icons";
|
||||
import { darken, lighten } from "polished";
|
||||
import { darken } from "polished";
|
||||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
|
@ -19,7 +19,6 @@ const RealButton = styled.button`
|
|||
height: 32px;
|
||||
text-decoration: none;
|
||||
flex-shrink: 0;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
|
@ -36,13 +35,6 @@ const RealButton = styled.button`
|
|||
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 {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
|
@ -70,13 +62,6 @@ const RealButton = styled.button`
|
|||
border: 1px solid ${props.theme.buttonNeutralBorder};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
transition-duration: 0.05s;
|
||||
border: 1px solid ${lighten(0.4, props.theme.buttonBackground)};
|
||||
box-shadow: ${lighten(0.4, props.theme.buttonBackground)} 0px 0px
|
||||
0px 2px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: ${props.theme.textTertiary};
|
||||
}
|
||||
|
@ -89,12 +74,6 @@ const RealButton = styled.button`
|
|||
&:hover {
|
||||
background: ${darken(0.05, props.theme.danger)};
|
||||
}
|
||||
|
||||
&:focus {
|
||||
transition-duration: 0.05s;
|
||||
box-shadow: ${lighten(0.4, props.theme.danger)} 0px 0px
|
||||
0px 3px;
|
||||
}
|
||||
`};
|
||||
`;
|
||||
|
||||
|
|
|
@ -181,7 +181,6 @@ const DocumentLink = styled(Link)`
|
|||
&:active,
|
||||
&:focus {
|
||||
background: ${(props) => props.theme.listItemHoverBackground};
|
||||
outline: none;
|
||||
|
||||
${SecondaryActions} {
|
||||
opacity: 1;
|
||||
|
|
|
@ -80,7 +80,6 @@ const MenuItem = styled.a`
|
|||
&:focus {
|
||||
color: ${props.theme.white};
|
||||
background: ${props.theme.primary};
|
||||
outline: none;
|
||||
}
|
||||
`};
|
||||
`;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// @flow
|
||||
import { lighten } from "polished";
|
||||
import * as React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
|
@ -11,13 +10,6 @@ const Button = styled.button`
|
|||
line-height: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
|
||||
&:focus {
|
||||
transition-duration: 0.05s;
|
||||
box-shadow: ${(props) => lighten(0.4, props.theme.buttonBackground)} 0px 0px
|
||||
0px 3px;
|
||||
outline: none;
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.forwardRef<any, typeof Button>((props, ref) => (
|
||||
|
|
|
@ -57,10 +57,16 @@ const TeamName = styled.div`
|
|||
font-size: 16px;
|
||||
`;
|
||||
|
||||
const Header = styled(Flex)`
|
||||
const Header = styled.button`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
padding: 16px 24px;
|
||||
position: relative;
|
||||
background: none;
|
||||
line-height: inherit;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
|
||||
|
|
|
@ -143,7 +143,6 @@ const StyledNavLink = styled(NavLink)`
|
|||
&:focus {
|
||||
color: ${(props) => props.theme.text};
|
||||
background: ${(props) => props.theme.black05};
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// @flow
|
||||
import { lighten } from "polished";
|
||||
import * as React from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
import styled, { withTheme } from "styled-components";
|
||||
|
@ -23,13 +22,6 @@ const StyledNavLink = styled(NavLink)`
|
|||
border-bottom: 3px solid ${(props) => props.theme.divider};
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-bottom: 3px solid
|
||||
${(props) => lighten(0.4, props.theme.buttonBackground)};
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
`;
|
||||
|
||||
function Tab({ theme, ...rest }: Props) {
|
||||
|
|
|
@ -6,7 +6,7 @@ const TeamLogo = styled.img`
|
|||
height: 38px;
|
||||
border-radius: 4px;
|
||||
background: ${(props) => props.theme.background};
|
||||
border: 1px solid ${(props) => props.theme.divider};
|
||||
outline: 1px solid ${(props) => props.theme.divider};
|
||||
`;
|
||||
|
||||
export default TeamLogo;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import "mobx-react-lite/batchingForReactDom";
|
||||
import "focus-visible";
|
||||
import { Provider } from "mobx-react";
|
||||
import * as React from "react";
|
||||
import { render } from "react-dom";
|
||||
|
|
|
@ -38,6 +38,7 @@ type Props = {
|
|||
showPrint?: boolean,
|
||||
showToggleEmbeds?: boolean,
|
||||
showPin?: boolean,
|
||||
label?: React.Node,
|
||||
onOpen?: () => void,
|
||||
onClose?: () => void,
|
||||
};
|
||||
|
@ -163,6 +164,7 @@ class DocumentMenu extends React.Component<Props> {
|
|||
showPin,
|
||||
auth,
|
||||
collections,
|
||||
label,
|
||||
onOpen,
|
||||
onClose,
|
||||
} = this.props;
|
||||
|
@ -179,6 +181,7 @@ class DocumentMenu extends React.Component<Props> {
|
|||
position={position}
|
||||
onOpen={onOpen}
|
||||
onClose={onClose}
|
||||
label={label}
|
||||
>
|
||||
{can.unarchive && (
|
||||
<DropdownMenuItem onClick={this.handleRestore}>
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
EditIcon,
|
||||
GlobeIcon,
|
||||
PlusIcon,
|
||||
MoreIcon,
|
||||
} from "outline-icons";
|
||||
import { transparentize, darken } from "polished";
|
||||
import * as React from "react";
|
||||
|
@ -336,6 +337,15 @@ class Header extends React.Component<Props> {
|
|||
<DocumentMenu
|
||||
document={document}
|
||||
isRevision={isRevision}
|
||||
label={
|
||||
<Button
|
||||
icon={<MoreIcon />}
|
||||
iconColor="currentColor"
|
||||
borderOnHover
|
||||
neutral
|
||||
small
|
||||
/>
|
||||
}
|
||||
showToggleEmbeds={canToggleEmbeds}
|
||||
showPrint
|
||||
/>
|
||||
|
|
|
@ -27,7 +27,6 @@ const DocumentLink = styled(Link)`
|
|||
&:active,
|
||||
&:focus {
|
||||
background: ${(props) => props.theme.listItemHoverBackground};
|
||||
outline: none;
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@
|
|||
"exports-loader": "^0.6.4",
|
||||
"file-loader": "^1.1.6",
|
||||
"flow-typed": "^2.6.2",
|
||||
"focus-visible": "^5.1.0",
|
||||
"fs-extra": "^4.0.2",
|
||||
"google-auth-library": "^5.5.1",
|
||||
"http-errors": "1.4.0",
|
||||
|
|
|
@ -76,4 +76,12 @@ export default createGlobalStyle`
|
|||
height: 0;
|
||||
border-top: 1px solid ${(props) => props.theme.divider};
|
||||
}
|
||||
|
||||
.js-focus-visible :focus:not(.focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.js-focus-visible .focus-visible {
|
||||
outline-color: ${(props) => props.theme.primary};
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -4907,6 +4907,11 @@ flush-write-stream@^1.0.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
focus-visible@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.1.0.tgz#4b9d40143b865f53eafbd93ca66672b3bf9e7b6a"
|
||||
integrity sha512-nPer0rjtzdZ7csVIu233P2cUm/ks/4aVSI+5KUkYrYpgA7ujgC3p6J7FtFU+AIMWwnwYQOB/yeiOITxFeYIXiw==
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
|
Reference in New Issue