Skip to content

Commit

Permalink
Responsive/a11y improvements (denoland#699)
Browse files Browse the repository at this point in the history
  • Loading branch information
josh-collinsworth authored Aug 9, 2024
1 parent 139ca9a commit d0e6974
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 74 deletions.
69 changes: 31 additions & 38 deletions _includes/doc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
>
</div>
<div
class="absolute top-16 bottom-0 left-0 right-0 lg:left-74 overflow-y-auto"
class="absolute top-16 bottom-0 left-0 right-0 lg:left-74 overflow-y-auto lg:grid lg:grid-cols-7 lg:gap-8 max-w-screen-2xl mx-auto"
style={{ scrollbarGutter: "stable" }}
>
<main class="mx-auto max-w-screen-xl w-full overflow-x-hidden pt-4 pb-8 flex flex-grow">
<div class="flex-grow px-4 sm:px-5 md:px-8 max-w-full lg:max-w-[75%]">
<article class="max-w-[66ch]">
<main class="mx-auto max-w-screen-xl w-full pt-4 pb-8 flex flex-grow lg:col-span-5">
<div class="flex-grow px-4 sm:px-5 md:px-6 max-w-full">
<article class="max-w-[66ch] mx-auto">
<Breadcrumbs
title={props.title!}
sidebar={sidebar}
Expand Down Expand Up @@ -136,7 +136,7 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
</div>
</article>
{parentNavigation && (
<nav class="grid gap-8 grid-cols-2 max-w-[66ch] items-center justify-between mt-6">
<nav class="grid gap-8 grid-cols-2 max-w-[66ch] items-center justify-between mt-12 mx-auto">
<div>
{parentNavigation[index! - 1] && (
<NavigationButton
Expand All @@ -158,30 +158,29 @@ export default function Page(props: Lume.Data, helpers: Lume.Helpers) {
</nav>
)}
</div>
<div
style={{ "flexBasis": "30%" }}
class="hidden lg:block sticky flex-shrink-0 flex-grow-0 px-8 pb-8"
>
<div>
<div class="py-2 top-0 ">
<ul class="border-l border-gray-200 py-2 pl-2">
{(props.toc as TableOfContentsItem_[]).map((item) => (
<TableOfContentsItem item={item} />
))}
</ul>
</div>
</div>
</div>
</main>
<props.comp.Footer />
<aside class="hidden lg:block pb-8 pr-8 col-span-2">
<div class="py-2 sticky top-4" id="toc">
<ul class="border-l border-gray-200 py-2 pl-2 relative">
{(props.toc as TableOfContentsItem_[]).map((item) => (
<TableOfContentsItem item={item} />
))}
</ul>
</div>
</aside>
<div class="lg:col-span-full">
<props.comp.Footer />
</div>
</div>
</>
);
}

function NavigationButton(
props: { item: SidebarItem; search: Searcher; direction: "prev" | "next" },
) {
function NavigationButton(props: {
item: SidebarItem;
search: Searcher;
direction: "prev" | "next";
}) {
let item: SidebarDoc_ | SidebarLink_;
if (typeof props.item === "string") {
const data = props.search.data(props.item)!;
Expand Down Expand Up @@ -216,24 +215,20 @@ function NavigationButton(
<span className="text-sm text-gray-2">{directionText}</span>
<div className="flex flex-row max-w-full items-center text-blue-500 gap-2">
{props.direction === "prev" && <>&laquo;</>}
<span className="font-semibold flex-shrink truncate">
{item.label}
</span>
<span className="font-semibold flex-shrink truncate">{item.label}</span>
{props.direction === "next" && <>&raquo;</>}
</div>
</a>
);
}

function Breadcrumbs(
props: {
title: string;
sidebar: Sidebar_;
url: string;
sectionTitle: string;
sectionHref: string;
},
) {
function Breadcrumbs(props: {
title: string;
sidebar: Sidebar_;
url: string;
sectionTitle: string;
sectionHref: string;
}) {
const crumbs = [];
outer: for (const section of props.sidebar) {
for (const item of section.items) {
Expand Down Expand Up @@ -275,9 +270,7 @@ function Breadcrumbs(
</svg>
{crumbs.map((crumb, i) => (
<>
<li class="px-2.5 py-1.5">
{crumb}
</li>
<li class="px-2.5 py-1.5">{crumb}</li>
{i < crumbs.length - 1 && (
<svg
class="size-6 rotate-90"
Expand Down
61 changes: 28 additions & 33 deletions index.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -453,31 +453,31 @@ export default function () {
);
}

function DocsCTA(
props: { text: string; href: string; product: "deploy" | "runtime" },
) {
function DocsCTA(props: {
text: string;
href: string;
product: "deploy" | "runtime";
}) {
const productClass = props.product === "deploy"
? "deploy-cta"
: "runtime-cta";
return (
<a
href={props.href}
className={`docs-cta ${productClass}`}
>
{props.text} <span aria-hidden="true">-&gt;</span>
<a href={props.href} className={`docs-cta ${productClass}`}>
{props.text}{" "}
<span aria-hidden="true" class="whitespace-pre">
-&gt;
</span>
</a>
);
}

function ContentItem(
props: {
title: string;
description: string;
linktext: string;
link: string;
product: string;
},
) {
function ContentItem(props: {
title: string;
description: string;
linktext: string;
link: string;
product: string;
}) {
const productClass = props.product === "deploy"
? "deploy-link"
: props.product === "runtime"
Expand All @@ -487,27 +487,22 @@ function ContentItem(
return (
<div>
<h4 className="text-lg font-semibold mb-1">{props.title}</h4>
<p className="mb-3">
{props.description}
{" "}
</p>
<a
className={`homepage-link ${productClass}`}
href={props.link}
>
{props.linktext} <span aria-hidden="true">-&gt;</span>
<p className="mb-3">{props.description}</p>
<a className={`homepage-link ${productClass}`} href={props.link}>
{props.linktext}{" "}
<span aria-hidden="true" class="whitespace-pre">
-&gt;
</span>
</a>
</div>
);
}

function LinkList(
props: {
title: string;
product: string;
links: { text: string; href: string }[];
},
) {
function LinkList(props: {
title: string;
product: string;
links: { text: string; href: string }[];
}) {
const productClass = props.product === "deploy"
? "deploy-link"
: props.product === "runtime"
Expand Down
32 changes: 30 additions & 2 deletions sidebar.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ for (const el of document.querySelectorAll("[data-accordion-trigger]")) {
e.preventDefault();
const parent = el.parentElement!;
const content = parent.querySelector("[data-accordion-content]");
const hidden = content!.classList
.toggle("hidden");
const hidden = content!.classList.toggle("hidden");
el.querySelector("svg")!.style.transform = hidden
? "rotate(90deg)"
: "rotate(180deg)";
Expand Down Expand Up @@ -35,3 +34,32 @@ sidebarCover?.addEventListener("click", () => {
sidebar.dataset.open = "false";
sidebarCover.dataset.open = "false";
});

const toc = document.getElementById("toc");
if (toc !== null) {
const headings = document.querySelectorAll(
".markdown-body :where(h2, h3, h4, h5, h6)",
);

const ACTIVE_CSS = "sidebar__current-item";
let activeId = "";
const observer = new IntersectionObserver(
(entries) => {
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];

if (entry.isIntersecting) {
const id = entry.target.id;
toc
.querySelector(`a[href="#${activeId}"]`)
?.classList.remove(ACTIVE_CSS);
toc.querySelector(`a[href="#${id}"]`)?.classList.add(ACTIVE_CSS);
activeId = id;
}
}
},
{ rootMargin: "0% 0% -70% 0%" },
);

headings.forEach((el) => observer.observe(el));
}
10 changes: 9 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ body:not(:has(.ddoc)) {
/* Global docs CTA button style */

.docs-cta {
@apply border border-gray-800 text-black bg-gray-500 font-bold inline-block py-3.5 px-4 rounded-md w-max hover:text-inherit hover:no-underline transition-colors duration-200;
@apply border text-balance border-gray-800 text-black bg-gray-500 font-bold inline-block py-3.5 px-4 rounded-md w-max hover:text-inherit hover:no-underline transition-colors duration-200;
}

.runtime-cta {
Expand Down Expand Up @@ -168,6 +168,14 @@ body:not(:has(.ddoc)) {
}
}

.sidebar__current-item {
@apply text-blue-500;
}

.sidebar__current-item::before {
@apply content-[""] absolute left-0 w-[0.5em] text-center h-[1.3em] [clip-path:polygon(0%_10%,100%_50%,0%_90%)] bg-gray-200;
}

.markdown-body .admonition a {
@apply text-primary underline underline-offset-2;
}
Expand Down

0 comments on commit d0e6974

Please sign in to comment.