pesde/website/src/routes/(app)/packages/[scope]/[name]/+layout.svelte
Luka f0d04fc87c
feat: website
* feat(website): init

* feat(website): home page

* feat(website): make page more responsive

* feat(website): layout

* feat(website): package page

* feat(website): update PackageResponse type

* feat(website): display package readme

* feat(website): use new /latest/any endpoint

* feat(website): make website lg instead of xl

* fix(website): use NodeJS.Timeout

* feat(website): versions page

* feat(website): add latest version indicator

* feat(website): add target select menu

* feat(website): indicate current version

* feat(website): add package metadata

* feat(website): add hamburger

* fix(website): header responsiveness

* feat(website): better package layout

* feat(website): display authors on package page

* fix(website): only display relative dates on client

* feat(docs): init docs site

* chore(website): read .env from project root

* feat(website): add gemoji support

* fix(website): overflow on code blocks

* chore(docs): read .env from project root

* feat(docs): config changes

* fix: authors not displaying

* fix(website): use fallback language

* refactor(website): use predefined target names

* refactor(website): change Github to GitHub

* chore: remove starter readmes

* chore(docs): remove .vscode

* chore(docs): remove unused assets folder

* fix(website): fix missing datetime attribute

* feat(website): switch to universal loaders

* feat(docs): search

* fix(website): type errors

* fix(website): use provided fetch instead of global

* feat(website): remove isr

* chore(website): add .env.example

* feat(website): add icons and metadata

* chore(website): add debug logs

* chore(website): remove shiki temporarily

* fix(website): rehype shiki lazy load

* fix(website): use custom highlighter

* fix(website): move highlighter creation into load

* docs: write docs

* feat(website): add og image

* feat(website): fix accessibility issues

* fix(website): no target selector on mobile

* fix(website): close dialog on navigation

* fix(website): logo is not a link in hamburger menu

* feat(website): dependencies tab

* fix(website): use correct dependency target

* fix(website): navigation links

* feat(website): support wally dependencies

* feat(website): metadata + case insensitivity

* fix(website): manually implement groupBy

`Object.groupBy` isn't supported on Vercel right now.

* fix(website): code block with an unknown language

* docs(policies): explain & cover more cases

* docs: update cli reference

* docs: add self hosting registries guide

* docs: update README

* docs: add more configs to registry guide

* fix: favicon and logomark

* feat(website): package documentation

* fix(website): missing $derive for toc

* docs: change SENTRY_URL to SENTRY_DSN

* chore(website): remove unused file

* chore: remove favicon.zip

* fix(website): strip wally# prefix

* chore: add changelog entry

---------

Co-authored-by: daimond113 <72147841+daimond113@users.noreply.github.com>
2024-10-29 20:06:00 +01:00

91 lines
2.4 KiB
Svelte

<script lang="ts">
import { page } from "$app/stores"
import { formatDistanceToNow } from "date-fns"
import { onMount, setContext, untrack } from "svelte"
import Tab from "./Tab.svelte"
import TargetSelector from "./TargetSelector.svelte"
let { children, data } = $props()
const [scope, name] = $derived(data.pkg.name.split("/"))
let currentPkg = $state(data.pkg)
let currentTarget = $state(
data.pkg.targets.find((target) => target.kind === $page.params.target) ?? data.pkg.targets[0],
)
setContext("currentPkg", {
get value() {
return currentPkg
},
set value(v) {
currentPkg = v
},
})
setContext("currentTarget", {
get value() {
return currentTarget
},
set value(v) {
currentTarget = v
},
})
const getReadme = () => {
if ("target" in $page.params) {
return `${$page.params.version}/${$page.params.target}`
}
return ""
}
const pkgVersion = $derived(currentPkg.version)
const pkgDescription = $derived(currentPkg.description)
let pkgDate = $state<null | string>(null)
let readme = $state(getReadme())
$effect(() => {
pkgDate = formatDistanceToNow(new Date(currentPkg.published_at), { addSuffix: true })
readme = untrack(getReadme)
})
onMount(() => {
return page.subscribe((page) => {
if (pkgDate === null || page.params.target !== undefined) {
currentTarget =
data.pkg.targets.find((target) => target.kind === page.params.target) ??
data.pkg.targets[0]
currentPkg = data.pkg
}
})
})
</script>
<div class="mx-auto max-w-prose px-4 py-16 lg:max-w-screen-lg">
<h1 class="text-3xl font-bold">
<span class="text-heading">{scope}/</span><span class="text-light">{name}</span>
</h1>
<div class="text-primary mb-2 font-semibold" class:invisible={pkgDate === null}>
v{pkgVersion} ·
<time datetime={data.pkg.published_at} title={new Date(data.pkg.published_at).toLocaleString()}>
published {pkgDate ?? "..."}
</time>
</div>
<p class="mb-6 max-w-prose">{pkgDescription}</p>
<div class="mb-8 lg:hidden">
<TargetSelector />
</div>
<nav class="flex w-full flex-col sm:flex-row sm:border-b-2">
<Tab tab={readme}>Readme</Tab>
<Tab tab={`${pkgVersion}/${currentTarget.kind}/dependencies`}>Dependencies</Tab>
<Tab tab="versions">Versions</Tab>
{#if currentPkg.docs && currentPkg.docs.length > 0}
<Tab tab={`${pkgVersion}/${currentTarget.kind}/docs`}>Documentation</Tab>
{/if}
</nav>
{@render children()}
</div>