Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

319 overlay accessibility reworked #391

Merged
merged 3 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was being applied to all buttons because the css selector is non-specific. Nest styles in top-level classes wherever possible, e.g. this could've been

.export-chat-link > button {

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;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this was being applied universally to the body, and affecting all our content. Always exercise caution when applying styles to an element without any preceding selectors.


.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