summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/AppButton.tsx12
-rw-r--r--gui/src/renderer/components/Connect.tsx40
-rw-r--r--gui/src/renderer/components/ErrorBoundary.tsx2
-rw-r--r--gui/src/renderer/components/HeaderBar.tsx8
-rw-r--r--gui/src/renderer/components/ImageView.tsx2
-rw-r--r--gui/src/renderer/components/Launch.tsx2
-rw-r--r--gui/src/renderer/components/NavigationBar.tsx29
-rw-r--r--gui/src/renderer/components/NavigationBarStyles.tsx10
-rw-r--r--gui/src/renderer/components/NotificationArea.tsx4
-rw-r--r--gui/src/renderer/components/NotificationBanner.tsx11
-rw-r--r--gui/src/renderer/components/SecuredLabel.tsx6
-rw-r--r--gui/src/renderer/components/SettingsHeader.tsx2
-rw-r--r--gui/src/renderer/components/Switch.tsx2
-rw-r--r--gui/src/renderer/components/TunnelControl.tsx5
14 files changed, 87 insertions, 48 deletions
diff --git a/gui/src/renderer/components/AppButton.tsx b/gui/src/renderer/components/AppButton.tsx
index c0731917d0..5b2c7fa62e 100644
--- a/gui/src/renderer/components/AppButton.tsx
+++ b/gui/src/renderer/components/AppButton.tsx
@@ -38,7 +38,7 @@ export function Icon(props: IIconProps) {
return <ImageView {...props} tintColor={colors.white} />;
}
-export interface IProps {
+export interface IProps extends React.HTMLAttributes<HTMLButtonElement> {
children?: React.ReactNode;
className?: string;
disabled?: boolean;
@@ -67,19 +67,17 @@ class BaseButton extends React.Component<IProps, IState> {
}
public render() {
+ const { children, ...otherProps } = this.props;
+
return (
<ButtonContext.Provider
value={{
textAdjustment: this.state.textAdjustment,
textRef: this.textRef,
}}>
- <StyledButton
- ref={this.buttonRef}
- disabled={this.props.disabled}
- onClick={this.props.onClick}
- className={this.props.className}>
+ <StyledButton ref={this.buttonRef} {...otherProps}>
<StyledButtonContent>
- {React.Children.map(this.props.children, (child) =>
+ {React.Children.map(children, (child) =>
typeof child === 'string' ? <Label>{child as string}</Label> : child,
)}
</StyledButtonContent>
diff --git a/gui/src/renderer/components/Connect.tsx b/gui/src/renderer/components/Connect.tsx
index 184465bd7d..36b88b81df 100644
--- a/gui/src/renderer/components/Connect.tsx
+++ b/gui/src/renderer/components/Connect.tsx
@@ -61,6 +61,12 @@ const StyledNotificationArea = styled(NotificationArea)({
right: 0,
});
+const StyledMain = styled.main({
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+});
+
interface IState {
isAccountExpired: boolean;
}
@@ -137,24 +143,26 @@ export default class Connect extends React.Component<IProps, IState> {
<>
<StyledMap {...this.getMapProps()} />
<Content>
- {/* show spinner when connecting */}
- {this.showMarkerOrSpinner() === 'spinner' ? (
- <StatusIcon source="icon-spinner" height={60} width={60} />
- ) : null}
+ <StyledNotificationArea />
- <TunnelControl
- tunnelState={this.props.connection.status}
- blockWhenDisconnected={this.props.blockWhenDisconnected}
- selectedRelayName={this.props.selectedRelayName}
- city={this.props.connection.city}
- country={this.props.connection.country}
- onConnect={this.props.onConnect}
- onDisconnect={this.props.onDisconnect}
- onReconnect={this.props.onReconnect}
- onSelectLocation={this.props.onSelectLocation}
- />
+ <StyledMain>
+ {/* show spinner when connecting */}
+ {this.showMarkerOrSpinner() === 'spinner' ? (
+ <StatusIcon source="icon-spinner" height={60} width={60} />
+ ) : null}
- <StyledNotificationArea />
+ <TunnelControl
+ tunnelState={this.props.connection.status}
+ blockWhenDisconnected={this.props.blockWhenDisconnected}
+ selectedRelayName={this.props.selectedRelayName}
+ city={this.props.connection.city}
+ country={this.props.connection.country}
+ onConnect={this.props.onConnect}
+ onDisconnect={this.props.onDisconnect}
+ onReconnect={this.props.onReconnect}
+ onSelectLocation={this.props.onSelectLocation}
+ />
+ </StyledMain>
</Content>
</>
);
diff --git a/gui/src/renderer/components/ErrorBoundary.tsx b/gui/src/renderer/components/ErrorBoundary.tsx
index bd20abcbdc..6470a2052d 100644
--- a/gui/src/renderer/components/ErrorBoundary.tsx
+++ b/gui/src/renderer/components/ErrorBoundary.tsx
@@ -23,7 +23,7 @@ const StyledContainer = styled(Container)({
backgroundColor: colors.blue,
});
-const Title = styled.span({
+const Title = styled.h1({
fontFamily: 'DINPro',
fontSize: '24px',
fontWeight: 900,
diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx
index 9569dd187e..20045086be 100644
--- a/gui/src/renderer/components/HeaderBar.tsx
+++ b/gui/src/renderer/components/HeaderBar.tsx
@@ -19,7 +19,7 @@ const headerBarStyleColorMap = {
[HeaderBarStyle.success]: colors.green,
};
-const HeaderBarContainer = styled.div({}, (props: { barStyle?: HeaderBarStyle }) => ({
+const HeaderBarContainer = styled.header({}, (props: { barStyle?: HeaderBarStyle }) => ({
padding: '12px 16px',
paddingTop: process.platform === 'darwin' ? '24px' : '12px',
backgroundColor: headerBarStyleColorMap[props.barStyle ?? HeaderBarStyle.default],
@@ -53,7 +53,7 @@ const BrandContainer = styled.div({
alignItems: 'center',
});
-const Title = styled.span({
+const Title = styled.h1({
fontFamily: 'DINPro',
fontSize: '24px',
fontWeight: 900,
@@ -91,7 +91,9 @@ export function HeaderBarSettingsButton() {
}, [history]);
return (
- <HeaderBarSettingsButtonContainer onClick={openSettings}>
+ <HeaderBarSettingsButtonContainer
+ onClick={openSettings}
+ aria-label={messages.gettext('Settings')}>
<ImageView
height={24}
width={24}
diff --git a/gui/src/renderer/components/ImageView.tsx b/gui/src/renderer/components/ImageView.tsx
index 6765b89a53..0414f8f1ff 100644
--- a/gui/src/renderer/components/ImageView.tsx
+++ b/gui/src/renderer/components/ImageView.tsx
@@ -55,7 +55,7 @@ export default function ImageView(props: IImageViewProps) {
} else {
return (
<Wrapper onClick={props.onClick} className={props.className}>
- <img src={url} width={props.width} height={props.height} />
+ <img src={url} width={props.width} height={props.height} aria-hidden={true} />
</Wrapper>
);
}
diff --git a/gui/src/renderer/components/Launch.tsx b/gui/src/renderer/components/Launch.tsx
index 9cb7a23d44..fec3ab68ba 100644
--- a/gui/src/renderer/components/Launch.tsx
+++ b/gui/src/renderer/components/Launch.tsx
@@ -14,7 +14,7 @@ const StyledContainer = styled(Container)({
marginTop: '-150px',
});
-const Title = styled.span({
+const Title = styled.h1({
fontFamily: 'DINPro',
fontSize: '24px',
fontWeight: 900,
diff --git a/gui/src/renderer/components/NavigationBar.tsx b/gui/src/renderer/components/NavigationBar.tsx
index 7d6e5a0714..28b6178397 100644
--- a/gui/src/renderer/components/NavigationBar.tsx
+++ b/gui/src/renderer/components/NavigationBar.tsx
@@ -1,10 +1,12 @@
import React, { useCallback, useContext, useLayoutEffect, useRef, useState } from 'react';
import { colors } from '../../config.json';
+import { messages } from '../../shared/gettext';
import CustomScrollbars, { IScrollEvent } from './CustomScrollbars';
import {
StyledBackBarItemButton,
StyledBackBarItemIcon,
StyledBackBarItemLabel,
+ StyledCloseBarItemButton,
StyledCloseBarItemIcon,
StyledNavigationBar,
StyledNavigationBarSeparator,
@@ -213,11 +215,17 @@ export const TitleBarItem = React.memo(function TitleBarItemT(props: ITitleBarIt
return (
<StyledTitleBarItemContainer ref={titleContainerRef}>
- <StyledTitleBarItemLabel titleAdjustment={titleAdjustment} visible={visible}>
+ <StyledTitleBarItemLabel
+ titleAdjustment={titleAdjustment}
+ visible={visible}
+ aria-hidden={!visible}>
{props.children}
</StyledTitleBarItemLabel>
- <StyledTitleBarItemMeasuringLabel titleAdjustment={0} ref={measuringTitleRef}>
+ <StyledTitleBarItemMeasuringLabel
+ titleAdjustment={0}
+ ref={measuringTitleRef}
+ aria-hidden={true}>
{props.children}
</StyledTitleBarItemMeasuringLabel>
</StyledTitleBarItemContainer>
@@ -233,14 +241,15 @@ export function CloseBarItem(props: ICloseBarItemProps) {
// title bar.
const iconName = process.platform === 'linux' ? 'icon-close-down' : 'icon-close';
return (
- <StyledCloseBarItemIcon
- height={24}
- width={24}
- source={iconName}
- onClick={props.action}
- tintColor={colors.white60}
- tintHoverColor={colors.white80}
- />
+ <StyledCloseBarItemButton aria-label={messages.gettext('Close')} onClick={props.action}>
+ <StyledCloseBarItemIcon
+ height={24}
+ width={24}
+ source={iconName}
+ tintColor={colors.white60}
+ tintHoverColor={colors.white80}
+ />
+ </StyledCloseBarItemButton>
);
}
diff --git a/gui/src/renderer/components/NavigationBarStyles.tsx b/gui/src/renderer/components/NavigationBarStyles.tsx
index 2f785f14e4..c141f4cfed 100644
--- a/gui/src/renderer/components/NavigationBarStyles.tsx
+++ b/gui/src/renderer/components/NavigationBarStyles.tsx
@@ -17,7 +17,7 @@ export const StyledNavigationItems = styled.div({
flexDirection: 'row',
});
-export const StyledNavigationBar = styled.div({
+export const StyledNavigationBar = styled.nav({
flex: 0,
padding: '12px',
paddingTop: process.platform === 'darwin' ? '24px' : '12px',
@@ -65,6 +65,14 @@ export const StyledTitleBarItemMeasuringLabel = styled(StyledTitleBarItemLabel)(
opacity: 0,
});
+export const StyledCloseBarItemButton = styled.button({
+ borderWidth: 0,
+ padding: 0,
+ margin: 0,
+ cursor: 'default',
+ backgroundColor: 'transparent',
+});
+
export const StyledCloseBarItemIcon = styled(ImageView)({
flex: 0,
});
diff --git a/gui/src/renderer/components/NotificationArea.tsx b/gui/src/renderer/components/NotificationArea.tsx
index 8cbee0df0f..9c5d8f13f6 100644
--- a/gui/src/renderer/components/NotificationArea.tsx
+++ b/gui/src/renderer/components/NotificationArea.tsx
@@ -66,7 +66,7 @@ export default function NotificationArea(props: IProps) {
return (
<NotificationBanner className={props.className} visible>
<NotificationIndicator type={notification.indicator} />
- <NotificationContent>
+ <NotificationContent role="alert" aria-live="assertive">
<NotificationTitle>{notification.title}</NotificationTitle>
<NotificationSubtitle>{notification.subtitle}</NotificationSubtitle>
</NotificationContent>
@@ -80,7 +80,7 @@ export default function NotificationArea(props: IProps) {
}
}
- return <NotificationBanner className={props.className} visible={false} />;
+ return <NotificationBanner className={props.className} visible={false} aria-hidden={true} />;
}
interface INotificationActionWrapperProps {
diff --git a/gui/src/renderer/components/NotificationBanner.tsx b/gui/src/renderer/components/NotificationBanner.tsx
index 5a9948b8bd..235ab6de2e 100644
--- a/gui/src/renderer/components/NotificationBanner.tsx
+++ b/gui/src/renderer/components/NotificationBanner.tsx
@@ -1,10 +1,13 @@
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { colors } from '../../config.json';
+import { messages } from '../../shared/gettext';
import { InAppNotificationIndicatorType } from '../../shared/notifications/notification';
import { BlockingButton } from './AppButton';
import ImageView from './ImageView';
+const NOTIFICATION_AREA_ID = 'notification-area';
+
export const NotificationTitle = styled.span({
fontFamily: 'Open Sans',
fontSize: '13px',
@@ -52,7 +55,9 @@ interface INotifcationOpenLinkActionProps {
export function NotificationOpenLinkAction(props: INotifcationOpenLinkActionProps) {
return (
<BlockingButton onClick={props.onClick}>
- <NotificationOpenLinkActionButton>
+ <NotificationOpenLinkActionButton
+ aria-describedby={NOTIFICATION_AREA_ID}
+ aria-label={messages.gettext('Open URL')}>
<NotificationOpenLinkActionIcon
height={12}
width={12}
@@ -64,7 +69,7 @@ export function NotificationOpenLinkAction(props: INotifcationOpenLinkActionProp
);
}
-export const NotificationContent = styled.div({
+export const NotificationContent = styled.div.attrs({ id: NOTIFICATION_AREA_ID })({
display: 'flex',
flexDirection: 'column',
flex: 1,
@@ -125,7 +130,7 @@ const Collapsible = styled.div({}, (props: ICollapsibleProps) => {
};
});
-const Content = styled.div({
+const Content = styled.section({
display: 'flex',
flexDirection: 'row',
padding: '8px 12px 8px 16px',
diff --git a/gui/src/renderer/components/SecuredLabel.tsx b/gui/src/renderer/components/SecuredLabel.tsx
index 7f68b100ae..36cee2db18 100644
--- a/gui/src/renderer/components/SecuredLabel.tsx
+++ b/gui/src/renderer/components/SecuredLabel.tsx
@@ -29,7 +29,11 @@ interface ISecuredLabelProps {
}
export default function SecuredLabel(props: ISecuredLabelProps) {
- return <StyledSecuredLabel {...props}>{getLabelText(props.displayStyle)}</StyledSecuredLabel>;
+ return (
+ <StyledSecuredLabel {...props} role="alert" aria-live="polite">
+ {getLabelText(props.displayStyle)}
+ </StyledSecuredLabel>
+ );
}
function getLabelText(displayStyle: SecuredDisplayStyle) {
diff --git a/gui/src/renderer/components/SettingsHeader.tsx b/gui/src/renderer/components/SettingsHeader.tsx
index 808b6f80c7..c0223461e0 100644
--- a/gui/src/renderer/components/SettingsHeader.tsx
+++ b/gui/src/renderer/components/SettingsHeader.tsx
@@ -13,7 +13,7 @@ export const ContentWrapper = styled.div({
},
});
-export const HeaderTitle = styled.span(bigText);
+export const HeaderTitle = styled.h1(bigText);
export const HeaderSubTitle = styled.span(smallText);
interface ISettingsHeaderProps {
diff --git a/gui/src/renderer/components/Switch.tsx b/gui/src/renderer/components/Switch.tsx
index ff56843e79..0578064e71 100644
--- a/gui/src/renderer/components/Switch.tsx
+++ b/gui/src/renderer/components/Switch.tsx
@@ -80,6 +80,8 @@ export default class Switch extends React.Component<IProps, IState> {
public render() {
return (
<SwitchContainer
+ role="checkbox"
+ aria-checked={this.state.isOn}
ref={this.containerRef}
onClick={this.handleClick}
disabled={this.props.disabled ?? false}
diff --git a/gui/src/renderer/components/TunnelControl.tsx b/gui/src/renderer/components/TunnelControl.tsx
index a36e5b9486..e5f674d7c4 100644
--- a/gui/src/renderer/components/TunnelControl.tsx
+++ b/gui/src/renderer/components/TunnelControl.tsx
@@ -114,7 +114,10 @@ export default class TunnelControl extends React.Component<ITunnelControlProps>
);
const Reconnect = (props: React.ComponentProps<typeof AppButton.RedTransparentButton>) => (
- <AppButton.RedTransparentButton onClick={this.props.onReconnect} {...props}>
+ <AppButton.RedTransparentButton
+ onClick={this.props.onReconnect}
+ aria-label={messages.gettext('Reconnect')}
+ {...props}>
<ImageView height={22} width={22} source="icon-reload" tintColor="white" />
</AppButton.RedTransparentButton>
);