Skip to content

Commit

Permalink
319 overlay accessibility reworked (#391)
Browse files Browse the repository at this point in the history
* Make overlay and handbook accessible
* Add click-outside handling to overlay

---------
Co-authored-by: Chris Wilton-Magras <[email protected]>
Co-authored-by: George Sproston <[email protected]>
Co-authored-by: Heather Logan <[email protected]>
  • Loading branch information
chriswilty authored Oct 17, 2023
1 parent 46def3d commit 028f29f
Show file tree
Hide file tree
Showing 20 changed files with 177 additions and 222 deletions.
3 changes: 0 additions & 3 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@
border: 1px solid transparent;
color: var(--main-button-inactive-text-colour);
padding: 0;

height: 100%;

display: flex;
align-items: center;
justify-content: center;
Expand Down
20 changes: 8 additions & 12 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import MainBody from "./components/MainComponent/MainBody";
import { useEffect, useState } from "react";
import { LEVEL_NAMES } from "./models/level";
import {
getChatHistory,
clearChat,
addMessageToChatHistory,
clearChat,
getChatHistory,
} from "./service/chatService";
import { EmailInfo } from "./models/email";
import { clearEmails, getSentEmails } from "./service/emailService";
Expand All @@ -32,17 +32,12 @@ function App({ isNewUser }: { isNewUser: boolean }) {
);
const [numCompletedLevels, setNumCompletedLevels] = useState<number>(0);

const [showOverlay, setShowOverlay] = useState<boolean>(isNewUser);

const [defencesToShow, setDefencesToShow] =
useState<DefenceInfo[]>(DEFENCE_DETAILS_ALL);

const [emails, setEmails] = useState<EmailInfo[]>([]);
const [messages, setMessages] = useState<ChatMessage[]>([]);

const [overlayType, setOverlayType] = useState<OVERLAY_TYPE>(
OVERLAY_TYPE.WELCOME
);
const [overlayType, setOverlayType] = useState<OVERLAY_TYPE | null>(null);

function loadCurrentLevel() {
// get current level from local storage
Expand All @@ -66,6 +61,9 @@ function App({ isNewUser }: { isNewUser: boolean }) {
console.error(err);
});
void setNewLevel(currentLevel);
if (isNewUser) {
setOverlayType(OVERLAY_TYPE.WELCOME);
}
}, []);

useEffect(() => {
Expand All @@ -78,18 +76,16 @@ function App({ isNewUser }: { isNewUser: boolean }) {
if (overlayType === OVERLAY_TYPE.WELCOME) {
openInformationOverlay();
} else {
setShowOverlay(false);
setOverlayType(null);
}
}

function openHandbook() {
setOverlayType(OVERLAY_TYPE.HANDBOOK);
setShowOverlay(true);
}

function openInformationOverlay() {
setOverlayType(OVERLAY_TYPE.INFORMATION);
setShowOverlay(true);
}

// methods to modify messages
Expand Down Expand Up @@ -228,7 +224,7 @@ function App({ isNewUser }: { isNewUser: boolean }) {

return (
<div id="app-content">
{showOverlay && (
{overlayType !== null && (
<Overlay
currentLevel={currentLevel}
overlayType={overlayType}
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/Theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@
);
--control-body-background-colour: #3a3a3a;

--overlay-hidden-colour: #0008;
--overlay-background-colour: #8ad5da;
--overlay-closed-tab-colour: #c7e8f4;
--overlay-tab-colour: #c7e8f4;
--overlay-attack-background-colour: #d6d6ff;
--overlay-text-colour: #313131;

Expand All @@ -66,3 +65,7 @@
--email-divider-colour: var(--email-text-colour);
--email-text-colour: #000;
}

::backdrop {
--overlay-hidden-colour: #0008;
}
7 changes: 4 additions & 3 deletions frontend/src/components/DocumentViewer/DocumentViewBox.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@

.document-popup-inner .close-button {
color: var(--main-accent-colour);
float: right;
position: absolute;
top: 2rem;
right: 2rem;
padding: 0.25rem 0.75rem;
font-size: 1.75rem;
font-weight: bold;

max-width: 40px;
}

.document-popup-inner .close-button:hover {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/DocumentViewer/DocumentViewBox.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useState } from "react";
import DocViewer, { DocViewerRenderers } from "@cyntler/react-doc-viewer";
import { RemoteDocument } from "../../models/document";
import { getDocumentUris } from "../../service/documentService";

import "./DocumentViewBox.css";
import { RemoteDocument } from "../../models/document";

function DocumentViewBox({
show,
Expand Down
9 changes: 1 addition & 8 deletions frontend/src/components/ExportChat/ExportPDFLink.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
#export-chat-box a {
.export-chat-link {
color: var(--main-button-inactive-text-colour);
text-decoration: none;
/* fill the entire space */
height: 100%;
width: 100%;
/* vertically centre text */
display: flex;
justify-content: center;
align-items: center;
}
9 changes: 5 additions & 4 deletions frontend/src/components/ExportChat/ExportPDFLink.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import ExportContent from "./ExportContent";
import { PDFDownloadLink } from "@react-pdf/renderer";
import { ChatMessage } from "../../models/chat";
import { EmailInfo } from "../../models/email";
import { PDFDownloadLink } from "@react-pdf/renderer";
import { LEVEL_NAMES } from "../../models/level";
import ExportContent from "./ExportContent";

import "./ExportPDFLink.css";
import { LEVEL_NAMES } from "../../models/level";

function ExportPDFLink({
messages,
Expand Down Expand Up @@ -33,10 +33,11 @@ function ExportPDFLink({
currentLevel={currentLevel}
/>
}
className="export-chat-link"
fileName={getFileName()}
>
Export
</PDFDownloadLink>{" "}
</PDFDownloadLink>
</div>
);
}
Expand Down
13 changes: 7 additions & 6 deletions frontend/src/components/HandbookOverlay/HandbookAttacks.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#handbook-attacks {
.handbook-attacks {
display: grid;
gap: 1rem 0.5rem;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.handbook-attack {
.handbook-attacks .attack {
background-color: var(--overlay-attack-background-colour);
border-radius: 10px;
padding: 0 10px;
margin: 5px;
font-size: 0.8rem;
margin: 0 0.25rem;
border-radius: 0.5rem;
padding: 0 0.625rem;
font-size: 0.875rem;
}
32 changes: 9 additions & 23 deletions frontend/src/components/HandbookOverlay/HandbookAttacks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,17 @@ import { LEVEL_NAMES } from "../../models/level";
import "./HandbookAttacks.css";

function HandbookAttacks({ currentLevel }: { currentLevel: LEVEL_NAMES }) {
function getAttacks(): AttackInfo[] {
// what attacks to show depends on the level
switch (currentLevel) {
case LEVEL_NAMES.LEVEL_1:
// fallthrough
case LEVEL_NAMES.LEVEL_2:
return ATTACKS_LEVEL_2;
default:
return ATTACKS_ALL;
}
}
const attacks: AttackInfo[] =
currentLevel === LEVEL_NAMES.LEVEL_2 ? ATTACKS_LEVEL_2 : ATTACKS_ALL;

return (
<div>
<h2>Attacks</h2>
<div id="handbook-attacks">
{getAttacks().map((attack) => {
return (
<span className="handbook-attack" key={attack.id}>
<h3>{attack.name}</h3>
<p>{attack.info}</p>
</span>
);
})}
</div>
<div className="handbook-attacks">
{attacks.map((attack) => (
<span className="attack" key={attack.id}>
<h3>{attack.name}</h3>
<p>{attack.info}</p>
</span>
))}
</div>
);
}
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/components/HandbookOverlay/HandbookOverlay.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#handbook-overlay-content {
.handbook-overlay {
display: flex;
flex-direction: column;
gap: 1rem;
height: 100%;
}

.handbook-overlay .content {
flex: 0 1 auto;
text-align: center;
overflow-y: auto;
}
34 changes: 15 additions & 19 deletions frontend/src/components/HandbookOverlay/HandbookOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,34 @@ import { LEVEL_NAMES } from "../../models/level";
import MissionInformation from "../Overlay/MissionInformation";
import HandbookAttacks from "./HandbookAttacks";
import HandbookOverlayTabs from "./HandbookOverlayTabs";
import { HANDBOOK_PAGES } from "../../models/handbook";
import { HANDBOOK_PAGES, handbookPageNames } from "../../models/handbook";
import "./HandbookOverlay.css";

function HandbookOverlay({ currentLevel }: { currentLevel: LEVEL_NAMES }) {
const [selectedPage, setSelectedPage] = useState<HANDBOOK_PAGES>(
HANDBOOK_PAGES.MISSION_INFO
);

function setPageContent(handbookPage: HANDBOOK_PAGES) {
switch (handbookPage) {
case HANDBOOK_PAGES.ATTACKS:
return <HandbookAttacks currentLevel={currentLevel} />;
case HANDBOOK_PAGES.TOOLS:
return (
<div>
<h2> Placeholder </h2>
</div>
);
case HANDBOOK_PAGES.MISSION_INFO:
default:
return <MissionInformation currentLevel={currentLevel} />;
}
}
const pageContent = {
[HANDBOOK_PAGES.MISSION_INFO]: (
<MissionInformation currentLevel={currentLevel} />
),
[HANDBOOK_PAGES.ATTACKS]: <HandbookAttacks currentLevel={currentLevel} />,
}[selectedPage];

return (
<div className="handbook-overlay">
<HandbookOverlayTabs
currentLevel={currentLevel}
setSelectedPage={setSelectedPage}
currentPage={selectedPage}
selectPage={setSelectedPage}
/>
<div className="handbook-overlay-content">
{setPageContent(selectedPage)}
<div
className="content"
role="tabpanel"
aria-label={handbookPageNames[selectedPage]}
>
{pageContent}
</div>
</div>
);
Expand Down
52 changes: 9 additions & 43 deletions frontend/src/components/HandbookOverlay/HandbookOverlayTabs.css
Original file line number Diff line number Diff line change
@@ -1,57 +1,23 @@
.handbook-tabs {
display: flex;
flex-wrap: wrap;
width: 100%;
position: absolute;
top: -50px; /* position above overlay */
left: 2rem;
z-index: -1;
gap: 0.5rem;
}

.handbook-tabs label {
.handbook-tabs button {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--overlay-tab-colour);
border-radius: 0.5rem;
padding: 1rem 2rem;
margin-right: 0.0625rem;
cursor: pointer;
background-color: var(--overlay-closed-tab-colour);
background-color: var(--overlay-background-colour);
font-size: 1rem;
font-weight: 700;
line-height: 1;
transition: ease 0.1s;
border-radius: 10px 10px 0 0;
}

.handbook-tabs label:not(:first-child):not(:last-child) {
border-right: 2px solid #000;
}

.handbook-tabs [type="radio"] {
display: none;
}

.handbook-tabs [type="radio"]:checked + label {
background-color: var(--overlay-background-colour);
}

.handbook-tabs [type="radio"]:checked + label + .tab {
display: block;
}

@media (min-width: 768px) {
body {
font-size: 1.125rem;
}

.handbook-tabs-container {
padding: 4rem 4rem;
}

.handbook-tabs label {
order: 1;
width: auto;
}

.handbook-tabs .tab {
order: 9;
}
.handbook-tabs button[aria-selected="true"] {
background-color: var(--overlay-tab-colour);
}
Loading

0 comments on commit 028f29f

Please sign in to comment.