feat(apps/docs): fix contributors path

This commit is contained in:
Ayo 2022-12-02 09:22:29 +01:00
parent 924edc017a
commit 26e099e2cf

View file

@ -1,66 +1,66 @@
--- ---
// fetch all commits for just this page's path // fetch all commits for just this page's path
type Props = { type Props = {
path: string; path: string;
}; };
const { path } = Astro.props as Props; const { path } = Astro.props as Props;
const resolvedPath = `examples/docs/${path}`; const resolvedPath = `apps/docs/${path}`;
const url = `https://api.github.com/repos/ayoayco/astro-reactive-library/commits?path=${resolvedPath}`; const url = `https://api.github.com/repos/ayoayco/astro-reactive-library/commits?path=${resolvedPath}`;
const commitsURL = `https://github.com/ayoayco/astro-reactive-library/commits/main/${resolvedPath}`; const commitsURL = `https://github.com/ayoayco/astro-reactive-library/commits/main/${resolvedPath}`;
type Commit = { type Commit = {
author: { author: {
id: string; id: string;
login: string; login: string;
}; };
}; };
async function getCommits(url: string) { async function getCommits(url: string) {
try { try {
const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? 'hello'; const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? "hello";
if (!token) { if (!token) {
throw new Error( throw new Error(
'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.' 'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.'
); );
} }
const auth = `Basic ${Buffer.from(token, 'binary').toString('base64')}`; const auth = `Basic ${Buffer.from(token, "binary").toString("base64")}`;
const res = await fetch(url, { const res = await fetch(url, {
method: 'GET', method: "GET",
headers: { headers: {
Authorization: auth, Authorization: auth,
'User-Agent': 'astro-docs/1.0', "User-Agent": "astro-docs/1.0",
}, },
}); });
const data = await res.json(); const data = await res.json();
if (!res.ok) { if (!res.ok) {
throw new Error( throw new Error(
`Request to fetch commits failed. Reason: ${res.statusText} `Request to fetch commits failed. Reason: ${res.statusText}
Message: ${data.message}` Message: ${data.message}`
); );
} }
return data as Commit[]; return data as Commit[];
} catch (e) { } catch (e) {
console.warn(`[error] /src/components/AvatarList.astro console.warn(`[error] /src/components/AvatarList.astro
${(e as any)?.message ?? e}`); ${(e as any)?.message ?? e}`);
return [] as Commit[]; return [] as Commit[];
} }
} }
function removeDups(arr: Commit[]) { function removeDups(arr: Commit[]) {
const map = new Map<string, Commit['author']>(); const map = new Map<string, Commit["author"]>();
for (let item of arr) { for (let item of arr) {
const author = item.author; const author = item.author;
// Deduplicate based on author.id // Deduplicate based on author.id
map.set(author.id, { login: author.login, id: author.id }); map.set(author.id, { login: author.login, id: author.id });
} }
return [...map.values()]; return [...map.values()];
} }
const data = await getCommits(url); const data = await getCommits(url);
@ -71,97 +71,112 @@ const additionalContributors = unique.length - recentContributors.length; // lis
<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! --> <!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
<div class="contributors"> <div class="contributors">
<ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}> <ul
{recentContributors.map((item) => ( class="avatar-list"
<li> style={`--avatar-count: ${recentContributors.length}`}
<a href={`https://github.com/${item.login}`}> >
<img {
alt={`Contributor ${item.login}`} recentContributors.map((item) => (
title={`Contributor ${item.login}`} <li>
width="64" <a href={`https://github.com/${item.login}`}>
height="64" <img
src={`https://avatars.githubusercontent.com/u/${item.id}`} alt={`Contributor ${item.login}`}
/> title={`Contributor ${item.login}`}
</a> width="64"
</li> height="64"
))} src={`https://avatars.githubusercontent.com/u/${item.id}`}
</ul> />
{additionalContributors > 0 && ( </a>
<span> </li>
<a href={commitsURL}>{`and ${additionalContributors} additional contributor${ ))
additionalContributors > 1 ? 's' : '' }
}.`}</a> </ul>
</span> {
)} additionalContributors > 0 && (
{unique.length === 0 && <a href={commitsURL}>Contributors</a>} <span>
<a
href={commitsURL}
>{`and ${additionalContributors} additional contributor${
additionalContributors > 1 ? "s" : ""
}.`}</a>
</span>
)
}
{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
</div> </div>
<style> <style>
.avatar-list { .avatar-list {
--avatar-size: 2.5rem; --avatar-size: 2.5rem;
--avatar-count: 3; --avatar-count: 3;
display: grid; display: grid;
list-style: none; list-style: none;
/* Default to displaying most of the avatar to /* Default to displaying most of the avatar to
enable easier access on touch devices, ensuring enable easier access on touch devices, ensuring
the WCAG touch target size is met or exceeded */ the WCAG touch target size is met or exceeded */
grid-template-columns: repeat(var(--avatar-count), max(44px, calc(var(--avatar-size) / 1.15))); grid-template-columns: repeat(
/* `padding` matches added visual dimensions of var(--avatar-count),
max(44px, calc(var(--avatar-size) / 1.15))
);
/* `padding` matches added visual dimensions of
the `box-shadow` to help create a more accurate the `box-shadow` to help create a more accurate
computed component size */ computed component size */
padding: 0.08em; padding: 0.08em;
font-size: var(--avatar-size); font-size: var(--avatar-size);
} }
@media (any-hover: hover) and (any-pointer: fine) { @media (any-hover: hover) and (any-pointer: fine) {
.avatar-list { .avatar-list {
/* We create 1 extra cell to enable the computed /* We create 1 extra cell to enable the computed
width to match the final visual width */ width to match the final visual width */
grid-template-columns: repeat(calc(var(--avatar-count) + 1), calc(var(--avatar-size) / 1.75)); grid-template-columns: repeat(
} calc(var(--avatar-count) + 1),
} calc(var(--avatar-size) / 1.75)
);
}
}
.avatar-list li { .avatar-list li {
width: var(--avatar-size); width: var(--avatar-size);
height: var(--avatar-size); height: var(--avatar-size);
} }
.avatar-list li:hover ~ li a, .avatar-list li:hover ~ li a,
.avatar-list li:focus-within ~ li a { .avatar-list li:focus-within ~ li a {
transform: translateX(33%); transform: translateX(33%);
} }
.avatar-list img, .avatar-list img,
.avatar-list a { .avatar-list a {
display: block; display: block;
border-radius: 50%; border-radius: 50%;
} }
.avatar-list a { .avatar-list a {
transition: transform 180ms ease-in-out; transition: transform 180ms ease-in-out;
} }
.avatar-list img { .avatar-list img {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
background-color: #fff; background-color: #fff;
box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15); box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
} }
.avatar-list a:focus { .avatar-list a:focus {
outline: 2px solid transparent; outline: 2px solid transparent;
/* Double-layer trick to work for dark and light backgrounds */ /* Double-layer trick to work for dark and light backgrounds */
box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white; box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
} }
.contributors { .contributors {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.contributors > * + * { .contributors > * + * {
margin-left: 0.75rem; margin-left: 0.75rem;
} }
</style> </style>