PackagePage
is an async component
A package at one range (range, else the newest the codebase runs): what it is, its README, its API (each export by
name, its kind and doc, its signature folded under it), and what in the codebase uses it; beside them its version, license, homepage and types, and
Upgrade (within its ranges, as tcm upgrade).
import { packageList, packagePage } from "#codebase/tcmts/cli/package_pages"; import { at, codeHref, Fold, Html, markdownHtml, servedCodebase, shareNow } from "#codebase/tcmts/share"; import { StudioFrame, studioShare, UpgradeButton } from "#codebase/tcmts/studio"; export async function PackagePage({ name, range }: { name: string; range: string }) { studioShare(); const s = shareNow(); if (!s.signedIn) return ( <StudioFrame tab="packages" title="Sign in"> {null} </StudioFrame> ); const entry = packageList(s.cb).find((p) => p.name === name); const r = entry?.ranges.find((x) => x.range === range) ?? entry?.ranges[0]; if (!entry || !r) return ( <StudioFrame tab="packages" title={name}> <div className="empty">The codebase doesn't run {name}.</div> </StudioFrame> ); const p = packagePage(s.cb, name, r.range); const own = s.cb === servedCodebase().cb; return ( <StudioFrame tab="packages" title={`${name} · packages`}> <div className="crumbs"> <a href={at("/packages")}>Packages</a> <span className="muted">/</span> </div> <div className="page cols-2"> <div> <div className="pagehead"> <h2 className="title mono">{name}</h2> <span className="muted">{`range ${p.range}, locked at ${p.version}`}</span> {own && ( <span className="right"> <UpgradeButton name={name} /> </span> )} </div> {p.description && ( <p className="lede" style={{ marginBottom: 14 }}> {p.description} </p> )} {p.readme && ( <div className="box"> <div className="boxhead"> <b>README</b> </div> <Html className="boxbody md" html={markdownHtml(s.cb, p.readme)} /> </div> )} <div className="box"> <div className="boxhead"> <b>API</b> <span className="count">{p.api.length}</span> </div> {p.api.length ? ( p.api.map((e) => ( <div className="relline apiline" key={e.name}> <Fold head={ <> <b className="mono">{e.name}</b> <span className="muted">{e.kind}</span> {e.doc && <span className="relsum muted">{e.doc.split("\n")[0]}</span>} </> } > <Html className="boxbody apisig" html={`<pre class="code">${e.html}</pre>`} /> {e.doc.includes("\n") && ( <div className="boxbody md" style={{ paddingTop: 0 }}> {e.doc} </div> )} </Fold> </div> )) ) : ( <div className="empty">Nothing it exports could be read.</div> )} </div> </div> <aside className="side"> <div className="sect"> <h4>Used by</h4> {p.users.length ? ( p.users.map((u) => ( <div key={u.path}> <a className="mono" href={codeHref(u.path)}> {u.path} </a> </div> )) ) : ( <span className="muted">Nothing named.</span> )} </div> <div className="sect"> <h4>About it</h4> <dl className="kv"> {p.license && ( <> <dt>license</dt> <dd>{p.license}</dd> </> )} {p.homepage && ( <> <dt>homepage</dt> <dd> <a href={p.homepage} target="_blank" rel="noreferrer"> {p.homepage.replace(/^https?:\/\//, "")} </a> </dd> </> )} {p.types && ( <> <dt>types</dt> <dd className="mono">{p.types}</dd> </> )} {p.integrity && ( <> <dt>tarball</dt> <dd className="mono" title={p.integrity}> {`${p.integrity.slice(0, 20)}…`} </dd> </> )} </dl> </div> {p.otherRanges.length > 0 && ( <div className="sect"> <h4>Other ranges</h4> {p.otherRanges.map((o) => ( <div key={o}> <a href={at( `/packages/${encodeURIComponent(name)}?range=${encodeURIComponent(o)}`, )} > {o} </a> </div> ))} </div> )} </aside> </div> </StudioFrame> ); }
uses
- tcmts.cli.package_pages.packageList
- tcmts.cli.package_pages.packagePage
- tcmts.share.Fold
- tcmts.share.Html
- tcmts.share.at
- tcmts.share.codeHref
- tcmts.share.markdownHtml
- tcmts.share.servedCodebase
- tcmts.share.shareNow
- tcmts.studio.StudioFrame
- tcmts.studio.UpgradeButton
- tcmts.studio.studioShare