Skip to content

Commit

Permalink
Optmize accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
hstandaert committed Apr 12, 2024
1 parent a182090 commit ecddbf9
Show file tree
Hide file tree
Showing 18 changed files with 259 additions and 65 deletions.
33 changes: 20 additions & 13 deletions src/assets/content/newsItems.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type NewsItem = {
key: string;
image: string;
altText: string;
title: string;
summary: string;
href: string;
Expand All @@ -9,38 +10,44 @@ export type NewsItem = {
const newsItems: NewsItem[] = [
{
key: "0",
title: "Distinguishing between ARIA and native HTML attributes",
title:
"TinyMCE 7 - Revision History, Document Converters, Markdown and more!",
summary:
"As a developer, you want to create more inclusive and accessible digital experiences for your users. Great! It’s possible, however, that you might be feeling a bit confused or overwhelmed by the element attributes that can affect the usability for users of assistive technology.",
href: "https://www.deque.com/blog/distinguishing-between-aria-and-native-html-attributes/",
"The latest version of TinyMCE is out and we have several highly requested features including Markdown, Revision History, and Document Converters.",
href: "https://dev.to/tinymce/tinymce-7-revision-history-document-converters-markdown-and-more-551n",
image:
"https://images.unsplash.com/photo-1556484687-30636164638b?q=80&w=3474&auto=format&fit=crop",
altText: "Hands of multiple people",
},
{
key: "1",
title:
"Uber Must Pay Wheelchair User $35,000, Provide Accessible Rides: B.C. Human Rights Tribunal",
title: "Accessibility tips from an accessibility engineer",
summary:
"It was the first time a ride-hailing app in Canada has been the subject of a human rights tribunal, the ruling said Author of the article:Susan Lazaruk",
href: "https://www.accessibilitynewsinternational.com/uber-must-pay-wheelchair-user-35000-provide-accessible-rides-b-c-human-rights-tribunal/",
"I am a blind accessibility engineer and programmer and I thought I would write an article detailing some of the common things I see in my day job.",
href: "https://dev.to/westbrookc16/accessibility-tips-from-an-accessibility-engineer-4kl8",
image:
"https://images.unsplash.com/photo-1505243542579-da5adfe8338f?q=80&w=3540&auto=format&fit=crop",
altText: "Two people giving each other a handshake",
},
{
key: "2",
title: "E-inclusion demo",
summary: "This is a demo of the E-inclusion project.",
href: "",
title: "Using Aria States To Toggle Tailwind Classes",
summary:
"I maintain an internal UI library for a number of large sites. It's got a number of JavaScript interactions for menus, search buttons and similar.",
href: "https://dev.to/endymion1818/using-aria-states-to-toggle-tailwind-classes-1lef",
image:
"https://images.unsplash.com/photo-1522071820081-009f0129c71c?q=80&w=1740&auto=format&fit=crop",
altText: "A group of people sitting at a table with laptops and notebooks",
},
{
key: "3",
title: "E-inclusion demo",
summary: "This is a demo of the E-inclusion project.",
href: "",
title: "Responsive design and cross-device testing",
summary:
'The so-called "browser wars" long before current web standards like HTML 5 made some web developers add badges like "best viewed with Netscape" or "best viewed with Internet Explorer"',
href: "https://dev.to/ingosteinke/responsive-design-and-cross-device-testing-1hoe",
image:
"https://images.unsplash.com/photo-1476703993599-0035a21b17a9?q=80&w=1740&auto=format&fit=crop",
altText: "A mother with her 2 kids",
},
];

Expand Down
1 change: 1 addition & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as ArrowRight } from "./arrowRight.tsx";
export { default as IcappsLogo } from "./icappsLogo.tsx";
export { default as Exclamation } from "./exclamation.tsx";
export { default as LinkedIn } from "./linkedin.tsx";
36 changes: 36 additions & 0 deletions src/assets/icons/linkedin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { SvgIcon } from "./types";

function exclamation({ title, width = 24, height = 24, ...props }: SvgIcon) {
return (
<svg
width={width}
height={height}
viewBox="0 0 24 24"
fill="none"
{...props}
>
<title>{title}</title>

<path
d="M6.5 8C7.32843 8 8 7.32843 8 6.5C8 5.67157 7.32843 5 6.5 5C5.67157 5 5 5.67157 5 6.5C5 7.32843 5.67157 8 6.5 8Z"
fill="currentColor"
/>
<path
d="M5 10C5 9.44772 5.44772 9 6 9H7C7.55228 9 8 9.44771 8 10V18C8 18.5523 7.55228 19 7 19H6C5.44772 19 5 18.5523 5 18V10Z"
fill="currentColor"
/>
<path
d="M11 19H12C12.5523 19 13 18.5523 13 18V13.5C13 12 16 11 16 13V18.0004C16 18.5527 16.4477 19 17 19H18C18.5523 19 19 18.5523 19 18V12C19 10 17.5 9 15.5 9C13.5 9 13 10.5 13 10.5V10C13 9.44771 12.5523 9 12 9H11C10.4477 9 10 9.44772 10 10V18C10 18.5523 10.4477 19 11 19Z"
fill="currentColor"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M20 1C21.6569 1 23 2.34315 23 4V20C23 21.6569 21.6569 23 20 23H4C2.34315 23 1 21.6569 1 20V4C1 2.34315 2.34315 1 4 1H20ZM20 3C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20Z"
fill="currentColor"
/>
</svg>
);
}

export default exclamation;
3 changes: 2 additions & 1 deletion src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { twMerge } from "tailwind-merge";
export type ButtonProps = PropsWithChildren &
ButtonHTMLAttributes<HTMLButtonElement>;

function Button({ type = "button", ...props }: ButtonProps) {
function Button({ type = "button", className, ...props }: ButtonProps) {
return (
<button
className={twMerge(
Expand All @@ -16,6 +16,7 @@ function Button({ type = "button", ...props }: ButtonProps) {
"py-2",
"px-4",
"rounded",
className,
)}
type={type}
{...props}
Expand Down
6 changes: 5 additions & 1 deletion src/components/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useAppState } from "@/providers";
import type { HTMLAttributes, PropsWithChildren } from "react";
import { twMerge } from "tailwind-merge";

Expand All @@ -7,8 +8,11 @@ export type ContainerProps = PropsWithChildren &
};

function Container({ className, narrow, ...props }: ContainerProps) {
const { isCompliant } = useAppState();
const Element = isCompliant ? "section" : "div";

return (
<div
<Element
className={twMerge(
"container",
"mx-auto",
Expand Down
46 changes: 42 additions & 4 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
import { Container } from ".";
import { LinkedIn } from "@/assets/icons";
import { useAppState } from "@/providers";
import { Container, Typography } from ".";

const ADDRESS = "Hangar 26/27, Rijnkaai 100 B16, 2000 Antwerp Belgium";

function footer() {
const { isCompliant } = useAppState();

return (
<Container className="my-0 md:my-0 lg:my-0 xl:my-0">
<div className="py-6 flex border-t border-opacity-50">
<h5 className="font-bold mr-3">Adres</h5>
<p>Hangar 26/27, Rijnkaai 100 B16, 2000 Antwerp Belgium</p>
<div className="py-6 border-t border-opacity-50 lg:flex items-end">
<div>
{isCompliant && (
<Typography variant="h6" as="h2" className="mr-2">
Adres
<span className="sr-only">: </span>
</Typography>
)}
<p>
{isCompliant ? (
<a
target="_blank"
href="https://www.google.com/maps/dir/?api=1&destination=icapps"
rel="noreferrer"
>
{ADDRESS}
</a>
) : (
ADDRESS
)}
</p>
</div>
<div className="ml-auto mt-4 lg:mt-0">
<a
href="https://www.linkedin.com/company/icapps"
target="_blank"
rel="noreferrer"
className="block lg:p-2 lg:-mr-2"
>
<LinkedIn title="LinkedIn" />
{isCompliant && (
<span className="sr-only">Go to icapps' LinkedIn page</span>
)}
</a>
</div>
</div>
</Container>
);
Expand Down
6 changes: 6 additions & 0 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ function Header() {

<div className="mt-12 grow flex items-center">
<h1 className="uppercase text-4xl lg:text-7xl/normal">
{isCompliant && (
<span className="block uppercase text-xl font-bold">
E-inclusion demo
<span className="sr-only">: </span>
</span>
)}
The only <strong>disability</strong> is when people cannot see{" "}
<strong>human potential</strong>.
</h1>
Expand Down
12 changes: 10 additions & 2 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ function Input({ label, className, multiline, error, ...props }: InputProps) {

return (
<div className="mb-4">
<label htmlFor={id} className="block mb-1 uppercase font-light text-sm">
<label htmlFor={id} className="block mb-1 font-light text-sm">
{label}
</label>

<Element
id={id}
className={twMerge([
"block",
"w-full",
"max-w-[80ch]",
"p-3",
Expand All @@ -31,12 +33,18 @@ function Input({ label, className, multiline, error, ...props }: InputProps) {
error ? "border-red" : "border-black",
className,
])}
{...(error
? { "aria-invalid": true, "aria-describedby": `${id}-error` }
: {})}
{...(multiline ? { rows: 5 } : {})} // Only add rows attribute if multiline
{...props}
/>

{error && (
<span className="text-red text-sm mt-1 flex items-center">
<span
id={`${id}-error`}
className="bg-red p-2 rounded-md text-sm inline-flex mt-2 items-center"
>
<Exclamation title="Error: " className="mr-2" />
{error}
</span>
Expand Down
10 changes: 9 additions & 1 deletion src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ function Layout({ children }: Layout) {
useEffect(() => {
document.title = isCompliant ? "E-inclusion demo" : "";
document.documentElement.lang = isCompliant ? "en" : "";
});

const viewportElement = document.querySelector("meta[name=viewport]");
viewportElement?.setAttribute(
"content",
isCompliant
? "width=device-width, initial-scale=1.0"
: "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0",
);
}, [isCompliant]);

return (
<div className={twMerge(["flex", "flex-col", "size-full"])}>
Expand Down
38 changes: 21 additions & 17 deletions src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { twMerge } from "tailwind-merge";
function Navigation() {
const [isNavOpen, setIsNavOpen] = useState(false);
const { isCompliant, toggleCompliancy } = useAppState();
const NavElement = isCompliant ? "nav" : "div";

const toggleNavigation = () => {
setIsNavOpen((prev) => !prev);
Expand All @@ -17,7 +18,7 @@ function Navigation() {
<div className="w-full sm:flex sm:items-center sm:justify-between my-4 sm:my-6 lg:my-8">
<div className="flex items-center justify-between">
<a
className="flex-none text-xl font-semibold focus:outline-none focus:ring-1 focus:ring-gray-600"
className="flex-none text-xl font-semibold"
title={isCompliant ? "Icapps" : ""}
href="#!"
>
Expand All @@ -31,12 +32,19 @@ function Navigation() {
)}
</a>
<div className="sm:hidden">
{/* biome-ignore lint/a11y/useButtonType: <explanation> */}
<button
aria-hidden={isCompliant}
type="button"
onClick={toggleNavigation}
className="p-2 inline-flex justify-center items-center gap-2 rounded-lg border border-gray-700 hover:border-gray-600 font-medium text-congress-blue-600 hover:text-congress-blue-400 shadow-sm align-middle focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-900 focus:ring-blue-600 transition-all text-sm"
className="p-2 inline-flex justify-center items-center gap-2 rounded-lg border border-gray-700 hover:border-gray-600 font-medium text-congress-blue-600 hover:text-congress-blue-400 shadow-sm align-middle transition-all text-sm"
{...(isCompliant
? {
"aria-expanded": isNavOpen,
"aria-haspopup": "true",
"aria-controls": "menu",
}
: {})}
>
{isCompliant && <span className="sr-only">Toggle navigation</span>}
<svg
className="flex-shrink-0 size-4"
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -67,27 +75,21 @@ function Navigation() {
</div>
</div>
<div
id="menu"
className={twMerge(
"overflow-hidden transition-all duration-300 basis-full grow sm:block",
"overflow-hidden sm:overflow-visible transition-all duration-300 basis-full grow sm:block",
isNavOpen ? "max-h-screen" : "max-h-0 sm:max-h-none",
)}
>
<div className="flex flex-col gap-5 mt-5 sm:flex-row sm:items-center sm:justify-end sm:mt-0 sm:ps-5 py-2">
<NavElement className="flex flex-col items-start gap-5 mt-5 sm:flex-row sm:items-center sm:justify-end sm:mt-0 sm:ps-5 py-2">
{navigationItems.map((item) => (
<a
key={item.title}
href={item.href}
className={twMerge(
"relative",
"block",
"font-medium",
"focus:outline-none",
isCompliant && [
"focus:ring-1",
"focus:ring-white",
"focus:ring-offset-4",
"focus:ring-offset-blueZodiac",
"pb-1",
'before:content-[""]',
"before:absolute",
"before:w-full",
Expand All @@ -102,20 +104,22 @@ function Navigation() {
"before:hover:scale-x-100",
"before:hover:origin-left",
],
item.isActive && ["font-bold", "text-white/30"],
item.isActive &&
(isCompliant
? ["font-bold", "underline underline-offset-4"]
: ["font-bold", "text-white/30"]),
)}
>
{item.title}
</a>
))}

<Switch
label="WCAG"
label={isCompliant ? "Undo compliancy" : "Make compliant"}
value={isCompliant}
onChange={toggleCompliancy}
className="ml-8"
/>
</div>
</NavElement>
</div>
</div>
);
Expand Down
Loading

0 comments on commit ecddbf9

Please sign in to comment.