Make track cards, track links, and project filters keyboard-operable
This commit is contained in:
4 files changed
+24
-11
No files matched your search
@@ -6,6 +6,7 @@ interface Props extends HTMLAttributes<"span"> {
|
||||
textColour?: String;
|
||||
size?: String;
|
||||
hover?: String;
|
||||
as?: "span" | "button";
|
||||
}
|
||||
|
||||
const {
|
||||
@@ -14,11 +15,13 @@ const {
|
||||
size = "text-xs",
|
||||
hover = "hover:bg-white hover:text-primary hover:ring-primary hover:ring-2",
|
||||
class: className,
|
||||
as: Tag = "span",
|
||||
...attrs
|
||||
} = Astro.props as Props;
|
||||
---
|
||||
|
||||
<span
|
||||
<Tag
|
||||
type={Tag === "button" ? "button" : undefined}
|
||||
class:list={[
|
||||
"inline-block rounded px-2 py-1 font-bold uppercase",
|
||||
colour,
|
||||
@@ -27,5 +30,5 @@ const {
|
||||
size,
|
||||
hover
|
||||
]}
|
||||
{...attrs}><slot /></span
|
||||
{...attrs}><slot /></Tag
|
||||
>
|
||||
@@ -20,7 +20,9 @@ if (!track.data.card) {
|
||||
}
|
||||
---
|
||||
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
aria-label={`Play ${track.data.card.text.primary}`}
|
||||
class:list={[
|
||||
"relative flex min-h-42 flex-auto hover:cursor-pointer",
|
||||
index < 2 ? "lg:w-1/2" : "sm:w-1/2 md:w-1/3 lg:w-1/4"
|
||||
@@ -33,8 +35,8 @@ if (!track.data.card) {
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="bg-primary absolute inset-0 z-10 flex h-full w-full flex-col items-center justify-center p-16 text-center opacity-0 transition duration-300 hover:opacity-90"
|
||||
<span
|
||||
class="bg-primary absolute inset-0 z-10 flex h-full w-full flex-col items-center justify-center p-16 text-center opacity-0 transition duration-300 hover:opacity-90 focus-visible:opacity-90"
|
||||
>
|
||||
<span class="text-md md:text-l block font-bold text-gray-100"
|
||||
>{track.data.card.text.secondary}</span
|
||||
@@ -42,5 +44,5 @@ if (!track.data.card) {
|
||||
<span class="block text-xl font-extrabold uppercase md:text-2xl"
|
||||
>{track.data.card.text.primary}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
@@ -21,7 +21,9 @@ const fullFilePath = join(process.cwd(), "public", track.data.src);
|
||||
const duration = await getAudioDurationInSeconds(fullFilePath);
|
||||
---
|
||||
|
||||
<div
|
||||
<button
|
||||
type="button"
|
||||
aria-label={`Play ${track.data.metadata.title}`}
|
||||
class:list={[
|
||||
"text-primary flex items-center transition hover:cursor-pointer hover:text-gray-300",
|
||||
className
|
||||
@@ -31,4 +33,4 @@ const duration = await getAudioDurationInSeconds(fullFilePath);
|
||||
>
|
||||
<Icon name="fa7-solid:play-circle" class="mr-2 inline-block" />
|
||||
<span class="inline-block">{track.data.metadata.title}</span>
|
||||
</div>
|
||||
</button>
|
||||
@@ -23,12 +23,16 @@ const types = [...new Set(projects.map((project) => project.data.type))];
|
||||
<SectionTitle Tag="h1">Recent Projects</SectionTitle>
|
||||
<div id="filter-tokens" class="my-8 space-y-2 space-x-2">
|
||||
<Token
|
||||
as="button"
|
||||
aria-pressed="true"
|
||||
class="filter-token !text-primary ring-primary bg-white ring-2 hover:cursor-pointer"
|
||||
data-type="all">All</Token
|
||||
>
|
||||
{
|
||||
types.map((type) => (
|
||||
<Token
|
||||
as="button"
|
||||
aria-pressed="false"
|
||||
class="filter-token hover:cursor-pointer"
|
||||
data-type={slugify(type)}
|
||||
>
|
||||
@@ -70,14 +74,15 @@ const types = [...new Set(projects.map((project) => project.data.type))];
|
||||
const token = (e.target as Element).closest<HTMLElement>(".filter-token");
|
||||
if (!token) return;
|
||||
|
||||
tokens.forEach((t) =>
|
||||
tokens.forEach((t) => {
|
||||
t.classList.remove(
|
||||
"bg-white",
|
||||
"!text-primary",
|
||||
"ring-primary",
|
||||
"ring-2"
|
||||
)
|
||||
);
|
||||
t.setAttribute("aria-pressed", "false");
|
||||
});
|
||||
|
||||
token.classList.add(
|
||||
"bg-white",
|
||||
@@ -85,6 +90,7 @@ const types = [...new Set(projects.map((project) => project.data.type))];
|
||||
"ring-primary",
|
||||
"ring-2"
|
||||
);
|
||||
token.setAttribute("aria-pressed", "true");
|
||||
|
||||
const type = token.dataset.type;
|
||||
|
||||
|
||||
Reference in new issue
Block a user