feat: Adds Jump to main content functionality

feat: Adds media query for prefers reduced motion

chore: remove <a/> from index.tsx

chore: remove tranisiton for skip link

chore: remove omitted error variable

update translations

chore: update translations

chore: Covert <a/> jump to content from html to Inferno JSX

chore: add translation

feat: add main as a parent to routes so jump to content always skips navigation on every page

chore: Use bootstrap classes

feat: Tidy Jump to content feature with some basic JS

feat: Jump to main content
This commit is contained in:
Sean Spade 2023-06-10 15:39:41 -04:00
parent 4da2438638
commit d3e181222a
4 changed files with 40 additions and 10 deletions

@ -1 +1 @@
Subproject commit f45ddff206adb52ab0ac7555bf14978edac5d2f2 Subproject commit c9a07885f35cf334d3cf167cb57587a8177fc3fb

View file

@ -420,3 +420,18 @@ br.big {
em-emoji-picker { em-emoji-picker {
width: 100%; width: 100%;
} }
.skip-link {
top: -40px;
transition: top 0.3s ease;
}
@media (prefers-reduced-motion: reduce) {
.skip-link {
transition: none;
}
}
.skip-link:focus {
top: 0;
}

View file

@ -1,4 +1,4 @@
import { Component } from "inferno"; import { Component, createRef, linkEvent, RefObject } from "inferno";
import { Provider } from "inferno-i18next-dess"; import { Provider } from "inferno-i18next-dess";
import { Route, Switch } from "inferno-router"; import { Route, Switch } from "inferno-router";
import { i18n } from "../../i18next"; import { i18n } from "../../i18next";
@ -15,8 +15,15 @@ import { Theme } from "./theme";
export class App extends Component<any, any> { export class App extends Component<any, any> {
private isoData: IsoDataOptionalSite = setIsoData(this.context); private isoData: IsoDataOptionalSite = setIsoData(this.context);
private readonly mainContentRef: RefObject<HTMLElement>;
constructor(props: any, context: any) { constructor(props: any, context: any) {
super(props, context); super(props, context);
this.mainContentRef = createRef();
}
handleJumpToContent(event) {
event.preventDefault();
this.mainContentRef.current?.focus();
} }
render() { render() {
const siteRes = this.isoData.site_res; const siteRes = this.isoData.site_res;
@ -26,6 +33,12 @@ export class App extends Component<any, any> {
<> <>
<Provider i18next={i18n}> <Provider i18next={i18n}>
<div id="app"> <div id="app">
<a
className="skip-link bg-light text-dark p-2 text-decoration-none position-absolute start-0 z-3"
onClick={linkEvent(this, this.handleJumpToContent)}
>
${i18n.t("jump_to_content", "Jump to content")}
</a>
{siteView && ( {siteView && (
<Theme defaultTheme={siteView.local_site.default_theme} /> <Theme defaultTheme={siteView.local_site.default_theme} />
)} )}
@ -39,14 +52,16 @@ export class App extends Component<any, any> {
exact exact
component={routeProps => ( component={routeProps => (
<ErrorGuard> <ErrorGuard>
{RouteComponent && <main tabIndex={-1} ref={this.mainContentRef}>
(isAuthPath(path ?? "") ? ( {RouteComponent &&
<AuthGuard> (isAuthPath(path ?? "") ? (
<AuthGuard>
<RouteComponent {...routeProps} />
</AuthGuard>
) : (
<RouteComponent {...routeProps} /> <RouteComponent {...routeProps} />
</AuthGuard> ))}
) : ( </main>
<RouteComponent {...routeProps} />
))}
</ErrorGuard> </ErrorGuard>
)} )}
/> />

View file

@ -330,7 +330,7 @@ export function validURL(str: string) {
try { try {
new URL(str); new URL(str);
return true; return true;
} catch (_) { } catch {
return false; return false;
} }
} }