diff --git a/web/src/lib/actions/resizable.ts b/web/src/lib/actions/resizable.ts index f4fc4f25a..de704873c 100644 --- a/web/src/lib/actions/resizable.ts +++ b/web/src/lib/actions/resizable.ts @@ -19,7 +19,8 @@ export const resizable: Action = (node, options) const move = (event: MouseEvent) => { if (!panel) return; - const delta = current.direction === "after" ? startX - event.clientX : event.clientX - startX; + const delta = + current.direction === "after" ? startX - event.clientX : event.clientX - startX; const width = startWidth + delta; if (width < (current.min ?? 100) || width > (current.max ?? Infinity)) return; panel.style.width = `${width}px`; diff --git a/web/src/lib/api/_request.ts b/web/src/lib/api/_request.ts index 686430c63..e45a25179 100644 --- a/web/src/lib/api/_request.ts +++ b/web/src/lib/api/_request.ts @@ -53,7 +53,11 @@ export const jsonPost = async ( ): Promise => { const response = await ctx.fetch(buildUrl(ctx.serviceUrl, nsid), { method: "POST", - headers: { "content-type": "application/json", accept: "application/json", ...init?.headers }, + headers: { + "content-type": "application/json", + accept: "application/json", + ...init?.headers + }, body: JSON.stringify(body), signal: init?.signal }); diff --git a/web/src/lib/api/blob.ts b/web/src/lib/api/blob.ts index 6b95e9f2b..bf46a2939 100644 --- a/web/src/lib/api/blob.ts +++ b/web/src/lib/api/blob.ts @@ -126,7 +126,8 @@ export const loadRepoBlob = async ( const kind = classifyBlob(output); const size = output.size ?? null; const fileTooLarge = - output.fileTooLarge === true || (hasTextView(kind) && size !== null && size > MAX_INLINE_SIZE); + output.fileTooLarge === true || + (hasTextView(kind) && size !== null && size > MAX_INLINE_SIZE); const contents = hasTextView(kind) && !fileTooLarge && output.encoding === "utf-8" @@ -171,7 +172,9 @@ export const loadRepoBlob = async ( ? "code" : "rendered" : "code", - submodule: output.submodule ? { name: output.submodule.name, url: output.submodule.url } : null, + submodule: output.submodule + ? { name: output.submodule.name, url: output.submodule.url } + : null, lastCommit }; }; diff --git a/web/src/lib/api/client.test.ts b/web/src/lib/api/client.test.ts index ba6d7aca8..bce124618 100644 --- a/web/src/lib/api/client.test.ts +++ b/web/src/lib/api/client.test.ts @@ -26,7 +26,9 @@ describe("createBobbinClient", () => { describe("jsonGet URL construction", () => { it("appends an array param as repeated keys", async () => { - const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ ok: 1 })); + const fetchMock = vi + .fn() + .mockResolvedValue(jsonResponse({ ok: 1 })); await jsonGet(makeCtx(fetchMock), "sh.tangled.repo.getRepos", { repos: ["a", "b"] }); const url = fetchedUrl(fetchMock); expect(url.searchParams.getAll("repos")).toEqual(["a", "b"]); @@ -34,7 +36,9 @@ describe("jsonGet URL construction", () => { }); it("omits undefined params entirely", async () => { - const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ ok: 1 })); + const fetchMock = vi + .fn() + .mockResolvedValue(jsonResponse({ ok: 1 })); await jsonGet(makeCtx(fetchMock), "sh.tangled.x", { keep: "yes", drop: undefined }); const url = fetchedUrl(fetchMock); expect(url.searchParams.has("drop")).toBe(false); @@ -42,7 +46,9 @@ describe("jsonGet URL construction", () => { }); it("resolves the query against the normalized origin", async () => { - const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ ok: 1 })); + const fetchMock = vi + .fn() + .mockResolvedValue(jsonResponse({ ok: 1 })); await jsonGet(makeCtx(fetchMock, "https://bobbin.test/"), "sh.tangled.x", { a: "1" }); expect(fetchedUrl(fetchMock).href).toBe("https://bobbin.test/xrpc/sh.tangled.x?a=1"); }); @@ -50,7 +56,9 @@ describe("jsonGet URL construction", () => { describe("jsonGet request headers & signal", () => { it("sends accept: application/json and merges caller headers + signal", async () => { - const fetchMock = vi.fn().mockResolvedValue(jsonResponse({ ok: 1 })); + const fetchMock = vi + .fn() + .mockResolvedValue(jsonResponse({ ok: 1 })); const controller = new AbortController(); await jsonGet(makeCtx(fetchMock), "sh.tangled.x", undefined, { headers: { "x-custom": "1" }, diff --git a/web/src/lib/api/client.ts b/web/src/lib/api/client.ts index 68d13e8bf..8ab2ee0b1 100644 --- a/web/src/lib/api/client.ts +++ b/web/src/lib/api/client.ts @@ -49,11 +49,17 @@ const withServiceAuth = ( }; }; -export const createBobbinClient = ({ serviceUrl, fetch, agent }: CreateBobbinOptions): BobbinContext => { +export const createBobbinClient = ({ + serviceUrl, + fetch, + agent +}: CreateBobbinOptions): BobbinContext => { const origin = serviceUrl.replace(/\/+$/, ""); const baseFetch = fetch ?? globalThis.fetch; const boundFetch = agent ? withServiceAuth(baseFetch, agent, origin) : baseFetch; - const xrpc = new Client({ handler: simpleFetchHandler({ service: origin, fetch: boundFetch }) }); + const xrpc = new Client({ + handler: simpleFetchHandler({ service: origin, fetch: boundFetch }) + }); return { xrpc, serviceUrl: origin, fetch: boundFetch }; }; diff --git a/web/src/lib/api/gitmirror.test.ts b/web/src/lib/api/gitmirror.test.ts index 42cfd3f4d..0af23185b 100644 --- a/web/src/lib/api/gitmirror.test.ts +++ b/web/src/lib/api/gitmirror.test.ts @@ -133,7 +133,10 @@ describe("gitmirror diff mappers", () => { lines: [{ lhs: 9 }] } ]; - expect(diffFileStat(fileDiff("a.ts", "a.ts", hunks))).toEqual({ insertions: 2, deletions: 2 }); + expect(diffFileStat(fileDiff("a.ts", "a.ts", hunks))).toEqual({ + insertions: 2, + deletions: 2 + }); expect(diffFileStat(fileDiff("a.ts", "a.ts"))).toEqual({ insertions: 0, deletions: 0 }); }); }); diff --git a/web/src/lib/api/knotmirror.test.ts b/web/src/lib/api/knotmirror.test.ts index 4c2ca5c2a..8d56371d2 100644 --- a/web/src/lib/api/knotmirror.test.ts +++ b/web/src/lib/api/knotmirror.test.ts @@ -107,7 +107,10 @@ describe("knotmirror.blob", () => { }); it("skips the content fetch when the entry is over the inline cap", async () => { - const fetchMock = blobFetch(new TextEncoder().encode("hello"), { ...entryBody, size: 2048 }); + const fetchMock = blobFetch(new TextEncoder().encode("hello"), { + ...entryBody, + size: 2048 + }); const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); const output = await knotmirror.blob( diff --git a/web/src/lib/api/knotmirror.ts b/web/src/lib/api/knotmirror.ts index 10691656c..4e70de4f1 100644 --- a/web/src/lib/api/knotmirror.ts +++ b/web/src/lib/api/knotmirror.ts @@ -86,7 +86,13 @@ export const blob = async ( } if (meta.size !== undefined && meta.size > maxBytes) { - return { path: params.path, ref: params.ref, size: meta.size, fileTooLarge: true, lastCommit }; + return { + path: params.path, + ref: params.ref, + size: meta.size, + fileTooLarge: true, + lastCommit + }; } const bytes = new Uint8Array(await (await rawGet(ctx, BLOB_NSID, params, init)).arrayBuffer()); diff --git a/web/src/lib/api/pagination.test.ts b/web/src/lib/api/pagination.test.ts index 292c5025a..d44e8da41 100644 --- a/web/src/lib/api/pagination.test.ts +++ b/web/src/lib/api/pagination.test.ts @@ -46,7 +46,9 @@ describe("pagination caps", () => { it("maxPages caps the number of network round-trips even with unbounded cursors", async () => { const fetchMock = vi .fn() - .mockImplementation(async () => pageResponse({ items: [{ uri: "x" }], cursor: "always" })); + .mockImplementation(async () => + pageResponse({ items: [{ uri: "x" }], cursor: "always" }) + ); const out = await collect(makeCtx(fetchMock), NAME, PARAMS, { maxPages: 2 }); expect(fetchMock).toHaveBeenCalledTimes(2); expect(out).toHaveLength(2); diff --git a/web/src/lib/api/pull.ts b/web/src/lib/api/pull.ts index 61fd96a68..07540b16e 100644 --- a/web/src/lib/api/pull.ts +++ b/web/src/lib/api/pull.ts @@ -45,14 +45,18 @@ export const editPull = ( agent: OAuthUserAgent, rkey: string, ticket: { title: string; body: string } -): Promise> => updatePull(agent, rkey, (record) => ({ ...record, ...ticket })); +): Promise> => + updatePull(agent, rkey, (record) => ({ ...record, ...ticket })); export const resubmitPull = ( agent: OAuthUserAgent, rkey: string, version: PullRecord["versions"][number] ): Promise> => - updatePull(agent, rkey, (record) => ({ ...record, versions: [...(record.versions ?? []), version] })); + updatePull(agent, rkey, (record) => ({ + ...record, + versions: [...(record.versions ?? []), version] + })); export const deletePull = async (agent: OAuthUserAgent, rkey: string): Promise => { await deleteRecord(agent, PULL_COLLECTION, rkey); diff --git a/web/src/lib/api/rawdiff.test.ts b/web/src/lib/api/rawdiff.test.ts index f6c0fcae8..8b22a39be 100644 --- a/web/src/lib/api/rawdiff.test.ts +++ b/web/src/lib/api/rawdiff.test.ts @@ -232,9 +232,15 @@ describe("renderFormatPatch", () => { it("renders the full patch for a rename and a delete", () => { const got = renderFormatPatch({ commit: { - hash: [0xab, 0xc1, 0x23, 0x45, 0x67, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + hash: [ + 0xab, 0xc1, 0x23, 0x45, 0x67, 0x89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ], message: "Fix the bug\n\nThis patch resolves the long-standing issue.\n\n\n", - author: { Name: "Alice Dev", Email: "alice@example.com", When: "2024-03-15T10:30:00Z" } + author: { + Name: "Alice Dev", + Email: "alice@example.com", + When: "2024-03-15T10:30:00Z" + } }, stat: { files_changed: 2, insertions: 1, deletions: 3 }, diff: [ diff --git a/web/src/lib/api/repo.test.ts b/web/src/lib/api/repo.test.ts index 79d56a3fe..8c9e53c0b 100644 --- a/web/src/lib/api/repo.test.ts +++ b/web/src/lib/api/repo.test.ts @@ -37,7 +37,9 @@ describe("repoNameOf", () => { }); it("prefers the record's cosmetic name over a tid rkey", () => { - expect(repoNameOf(view("at://did:plc:o/sh.tangled.repo/3lzg6enurmo22", "infra"))).toBe("infra"); + expect(repoNameOf(view("at://did:plc:o/sh.tangled.repo/3lzg6enurmo22", "infra"))).toBe( + "infra" + ); }); it("falls back to the rkey for unnamed records", () => { @@ -69,7 +71,12 @@ describe("sortTreeEntries", () => { entry(".gitignore", "file"), entry("vendor", "submodule") ]); - expect(sorted.map((item) => item.name)).toEqual(["src", "vendor", ".gitignore", "readme.md"]); + expect(sorted.map((item) => item.name)).toEqual([ + "src", + "vendor", + ".gitignore", + "readme.md" + ]); }); }); @@ -198,7 +205,9 @@ describe("toBranchSummary", () => { }); it("treats a missing is_default as not default", () => { - expect(toBranchSummary({ reference: { name: "topic", hash: "abc" } }).isDefault).toBe(false); + expect(toBranchSummary({ reference: { name: "topic", hash: "abc" } }).isDefault).toBe( + false + ); }); }); diff --git a/web/src/lib/api/repoIndex.test.ts b/web/src/lib/api/repoIndex.test.ts index 33078d352..548dfea96 100644 --- a/web/src/lib/api/repoIndex.test.ts +++ b/web/src/lib/api/repoIndex.test.ts @@ -8,7 +8,10 @@ const unsupported = () => describe("classifyRepoAvailability", () => { it("recognizes a legacy knot that does not expose repository endpoints", () => { const result = classifyRepoAvailability( - [unsupported(), unsupported(), unsupported()].map((cause) => ({ value: null, error: cause })) + [unsupported(), unsupported(), unsupported()].map((cause) => ({ + value: null, + error: cause + })) ); expect(result).toBe("needs-upgrade"); @@ -16,7 +19,10 @@ describe("classifyRepoAvailability", () => { it("keeps transport failures as unreachable", () => { const result = classifyRepoAvailability( - ["tree", "log", "branches"].map(() => ({ value: null, error: new TypeError("offline") })) + ["tree", "log", "branches"].map(() => ({ + value: null, + error: new TypeError("offline") + })) ); expect(result).toBe("unreachable"); diff --git a/web/src/lib/api/spindle.test.ts b/web/src/lib/api/spindle.test.ts index 9270e0125..c28aaae8f 100644 --- a/web/src/lib/api/spindle.test.ts +++ b/web/src/lib/api/spindle.test.ts @@ -111,7 +111,11 @@ describe("toPipelineSummary", () => { startedAt: "2026-08-04T09:00:00.000Z", finishedAt: "2026-08-04T09:01:12.000Z" }), - workflow({ name: "test", status: "running", startedAt: "2026-08-04T09:00:00.000Z" }) + workflow({ + name: "test", + status: "running", + startedAt: "2026-08-04T09:00:00.000Z" + }) ] }) ); diff --git a/web/src/lib/api/spindleLogs.test.ts b/web/src/lib/api/spindleLogs.test.ts index cad9130a7..9e0ce7115 100644 --- a/web/src/lib/api/spindleLogs.test.ts +++ b/web/src/lib/api/spindleLogs.test.ts @@ -9,8 +9,7 @@ const frames = { controlMinimal: "a261746823636f6e74726f6c626f7001a46473746570016474696d6574323032362d30382d30365431323a30303a30395a67636f6e74656e746952756e20746573747368776f726b666c6f77656275696c64", data: "a26174652364617461626f7001a56473746570016474696d6574323032362d30382d30365431323a30303a30315a6673747265616d6673746465727267636f6e74656e746e1b5b33316d626f6f6d1b5b306d0a68776f726b666c6f77656275696c64", - error: - "a1626f7020a2656572726f7270576f726b666c6f774e6f74466f756e64676d657373616765706e6f207375636820776f726b666c6f77" + error: "a1626f7020a2656572726f7270576f726b666c6f774e6f74466f756e64676d657373616765706e6f207375636820776f726b666c6f77" } as const; const bytes = (hex: string): Uint8Array => diff --git a/web/src/lib/components/notifications/NotificationItem.svelte b/web/src/lib/components/notifications/NotificationItem.svelte index ec6ba37de..3b250f85b 100644 --- a/web/src/lib/components/notifications/NotificationItem.svelte +++ b/web/src/lib/components/notifications/NotificationItem.svelte @@ -20,7 +20,9 @@ variants: { read: { true: { root: "bg-background-default hover:bg-background-subtle" }, - false: { root: "bg-background-info-subtle hover:bg-background-info-subtle-hover dark:hover:bg-background-subtle" } + false: { + root: "bg-background-info-subtle hover:bg-background-info-subtle-hover dark:hover:bg-background-subtle" + } } }, defaultVariants: { diff --git a/web/src/lib/components/profile/pages.test.ts b/web/src/lib/components/profile/pages.test.ts index 974825824..3138ffb25 100644 --- a/web/src/lib/components/profile/pages.test.ts +++ b/web/src/lib/components/profile/pages.test.ts @@ -38,7 +38,10 @@ describe("fetchStarredPage", () => { items: [ { uri: "at://did:plc:alice/sh.tangled.feed.star/one", - value: { subject: { did: "did:plc:repo" }, createdAt: "2026-08-01T00:00:00Z" } + value: { + subject: { did: "did:plc:repo" }, + createdAt: "2026-08-01T00:00:00Z" + } } ] }, @@ -132,7 +135,9 @@ describe("fetchStarredPage", () => { }); it("targets repo dids for both pinned repo queries", async () => { - const fetchMock = vi.fn().mockImplementation(async () => enriched()); + const fetchMock = vi + .fn() + .mockImplementation(async () => enriched()); const ctx = createBobbinClient({ serviceUrl: "https://bobbin.test", fetch: fetchMock }); await fetchPinned(ctx, { diff --git a/web/src/lib/components/reaction/Reactions.svelte b/web/src/lib/components/reaction/Reactions.svelte index c62ffcf86..9d2ac1134 100644 --- a/web/src/lib/components/reaction/Reactions.svelte +++ b/web/src/lib/components/reaction/Reactions.svelte @@ -62,7 +62,9 @@ if (group.viewerRkey) await deleteReaction(agent, group.viewerRkey); commit( groups - .map((g) => (g.kind === group.kind ? withoutViewerReaction(g, viewer.handle) : g)) + .map((g) => + g.kind === group.kind ? withoutViewerReaction(g, viewer.handle) : g + ) .filter((g) => g.count > 0) ); } else { diff --git a/web/src/lib/components/reaction/reactions.ts b/web/src/lib/components/reaction/reactions.ts index b4eceb3fc..5e099c2be 100644 --- a/web/src/lib/components/reaction/reactions.ts +++ b/web/src/lib/components/reaction/reactions.ts @@ -85,7 +85,7 @@ export function upsertViewerReaction( const next = exists ? groups.map((g) => (g.kind === kind ? withViewerReaction(g, viewerHandle, rkey) : g)) : [...groups, { kind, count: 1, users: [viewerHandle], isReacted: true, viewerRkey: rkey }]; - return ORDERED_REACTION_KINDS.filter((k) => next.some((g) => g.kind === k)).map( - (k) => next.find((g) => g.kind === k)! + return ORDERED_REACTION_KINDS.filter((k) => next.some((g) => g.kind === k)).map((k) => + next.find((g) => g.kind === k)! ); } diff --git a/web/src/lib/components/repo/RepoCardContent.svelte b/web/src/lib/components/repo/RepoCardContent.svelte index a47bee7b7..676acd996 100644 --- a/web/src/lib/components/repo/RepoCardContent.svelte +++ b/web/src/lib/components/repo/RepoCardContent.svelte @@ -50,12 +50,14 @@ {#if repo.description} -

{repo.description}

+

+ {repo.description} +

{/if} {#if repo.language !== undefined || stats.length > 0}
{#if repo.language} diff --git a/web/src/lib/components/repo/pulls/PullCommitListInterdiff.svelte b/web/src/lib/components/repo/pulls/PullCommitListInterdiff.svelte index 7b221016a..5ffb5562e 100644 --- a/web/src/lib/components/repo/pulls/PullCommitListInterdiff.svelte +++ b/web/src/lib/components/repo/pulls/PullCommitListInterdiff.svelte @@ -85,7 +85,7 @@ : ''}" > - @@ -62,7 +68,9 @@
diff --git a/web/src/lib/components/ui/ButtonCard.svelte b/web/src/lib/components/ui/ButtonCard.svelte index f85a4d1af..a04a421ee 100644 --- a/web/src/lib/components/ui/ButtonCard.svelte +++ b/web/src/lib/components/ui/ButtonCard.svelte @@ -52,7 +52,10 @@ SvelteHTMLElements } from "svelte/elements"; - interface Props extends Omit { + interface Props extends Omit< + HTMLAnchorAttributes & HTMLButtonAttributes, + "class" | "children" + > { variant?: ButtonCardVariants["variant"]; insetShadow?: boolean; href?: ResolvedPathname; @@ -90,7 +93,9 @@ {#if Icon}
- + { + interface Props extends Omit< + HTMLAnchorAttributes & HTMLButtonAttributes, + "class" | "children" + > { variant?: LinkVariants["variant"]; size?: LinkVariants["size"]; href?: ResolvedPathname; diff --git a/web/src/lib/components/ui/Pagination.svelte b/web/src/lib/components/ui/Pagination.svelte index e8f3eef89..888d24bbd 100644 --- a/web/src/lib/components/ui/Pagination.svelte +++ b/web/src/lib/components/ui/Pagination.svelte @@ -5,8 +5,7 @@ slots: { nav: "inline-flex items-center gap-1", track: "relative typography-paragraph-regular tabular-nums [--gap:0.25rem]", - plate: - "pointer-events-none absolute inset-y-0 left-0 w-(--slot) rounded-sm border border-border-default bg-background-default", + plate: "pointer-events-none absolute inset-y-0 left-0 w-(--slot) rounded-sm border border-border-default bg-background-default", list: "relative flex gap-(--gap)", slot: "w-(--slot)", page: "w-full px-0", @@ -147,8 +146,9 @@ onclick={() => goTo(item)} > {#key item} - rolled)} style="--roll: {untrack(() => direction)}" - >{item} rolled)} + style="--roll: {untrack(() => direction)}">{item} {/key} diff --git a/web/src/lib/components/ui/Section.stories.svelte b/web/src/lib/components/ui/Section.stories.svelte index 72c5759e9..50ef1651c 100644 --- a/web/src/lib/components/ui/Section.stories.svelte +++ b/web/src/lib/components/ui/Section.stories.svelte @@ -43,7 +43,9 @@ listClass="grid grid-cols-2 gap-4" > {#snippet header()} -

Up to four pinned repositories.

+

+ Up to four pinned repositories. +

{/snippet} {@render items()} @@ -53,7 +55,9 @@
{@render items()} {#snippet footer()} -
footer
+
+ footer +
{/snippet}
diff --git a/web/src/lib/components/ui/Select.svelte b/web/src/lib/components/ui/Select.svelte index ed75110b2..9bad43760 100644 --- a/web/src/lib/components/ui/Select.svelte +++ b/web/src/lib/components/ui/Select.svelte @@ -83,7 +83,9 @@ {#snippet nativeOptions(items: SelectOption[])} {#each items as option (option.value)} - + {/each} {/snippet} diff --git a/web/src/lib/components/ui/ShimmerText.stories.svelte b/web/src/lib/components/ui/ShimmerText.stories.svelte index 3ad162401..3947a77ef 100644 --- a/web/src/lib/components/ui/ShimmerText.stories.svelte +++ b/web/src/lib/components/ui/ShimmerText.stories.svelte @@ -9,7 +9,16 @@ argTypes: { color: { control: { type: "inline-radio" }, - options: ["inherit", "default", "muted", "subtle", "success", "danger", "warning", "info"] + options: [ + "inherit", + "default", + "muted", + "subtle", + "success", + "danger", + "warning", + "info" + ] }, duration: { control: { type: "number" } }, delay: { control: { type: "number" } } diff --git a/web/src/lib/components/ui/Tag.svelte b/web/src/lib/components/ui/Tag.svelte index de5cb2e56..26ac74d68 100644 --- a/web/src/lib/components/ui/Tag.svelte +++ b/web/src/lib/components/ui/Tag.svelte @@ -5,14 +5,16 @@ base: "inline-flex items-center gap-1 rounded-sm leading-none font-medium select-none", variants: { color: { - default: "border border-border-default bg-background-default text-foreground-default", + default: + "border border-border-default bg-background-default text-foreground-default", gray: "border border-transparent bg-background-inset text-foreground-default", - highlight: "border border-transparent bg-background-highlight text-foreground-highlight", + highlight: + "border border-transparent bg-background-highlight text-foreground-highlight", success: "border border-transparent bg-background-success-subtle text-foreground-success-strong", - danger: - "border border-transparent bg-background-danger-subtle text-foreground-danger-strong", - warning: "border border-transparent bg-background-warning-subtle text-foreground-warning", + danger: "border border-transparent bg-background-danger-subtle text-foreground-danger-strong", + warning: + "border border-transparent bg-background-warning-subtle text-foreground-warning", info: "border border-transparent bg-background-info-subtle text-foreground-info-strong" }, size: { diff --git a/web/src/lib/components/ui/TagInput.svelte b/web/src/lib/components/ui/TagInput.svelte index 80a097ede..fbeef70ba 100644 --- a/web/src/lib/components/ui/TagInput.svelte +++ b/web/src/lib/components/ui/TagInput.svelte @@ -19,15 +19,11 @@ // of Tag's six fills, and a muted grey goes muddy on the coloured ones in dark field: "shrink-0 opacity-70", label: "truncate", - remove: - "text-foreground-inherit -mr-0.5 flex min-h-0 shrink-0 rounded-xs p-0 transition-colors focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-border-focus", - draft: - "w-full min-w-0 bg-transparent outline-none placeholder:text-foreground-placeholder placeholder:transition-opacity placeholder:duration-200 disabled:cursor-not-allowed motion-reduce:placeholder:transition-none", - panel: - "tag-panel fixed z-50 m-0 hidden max-h-[min(18rem,calc(100dvh-1rem))] w-72 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default open:flex", + remove: "text-foreground-inherit -mr-0.5 flex min-h-0 shrink-0 rounded-xs p-0 transition-colors focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-border-focus", + draft: "w-full min-w-0 bg-transparent outline-none placeholder:text-foreground-placeholder placeholder:transition-opacity placeholder:duration-200 disabled:cursor-not-allowed motion-reduce:placeholder:transition-none", + panel: "tag-panel fixed z-50 m-0 hidden max-h-[min(18rem,calc(100dvh-1rem))] w-72 max-w-[calc(100vw-1rem)] popover-transition flex-col overflow-hidden rounded-sm border border-border-default bg-background-default p-0 text-foreground-default open:flex", options: "min-h-0 flex-1 overflow-y-auto p-1", - option: - "flex w-full cursor-pointer items-center gap-2 rounded-sm bg-transparent px-2 py-1.5 text-left data-active:bg-background-subtle", + option: "flex w-full cursor-pointer items-center gap-2 rounded-sm bg-transparent px-2 py-1.5 text-left data-active:bg-background-subtle", optionLabel: "min-w-0 flex-1 truncate", empty: "px-2 py-6 text-center text-foreground-muted", footer: "mt-1.5 flex items-start gap-2", @@ -35,7 +31,8 @@ // without the footer changing height message: "grid min-w-0 flex-1", hint: "col-start-1 row-start-1 text-foreground-muted transition-opacity duration-200", - rejection: "col-start-1 row-start-1 text-foreground-danger transition-opacity duration-200", + rejection: + "col-start-1 row-start-1 text-foreground-danger transition-opacity duration-200", counter: "shrink-0 text-foreground-subtle tabular-nums" }, variants: { @@ -603,7 +600,9 @@ role={suggestions.length > 0 ? "combobox" : undefined} aria-expanded={suggestions.length > 0 ? open : undefined} aria-controls={suggestions.length > 0 ? optionsId : undefined} - aria-activedescendant={open && activeIndex >= 0 ? optionId(activeIndex) : undefined} + aria-activedescendant={open && activeIndex >= 0 + ? optionId(activeIndex) + : undefined} autocomplete="off" {...rest} /> @@ -653,7 +652,10 @@ {:else} {#if option.icon} {@const OptionIcon = option.icon} -
- {hint ?? ""} - + {hint ?? ""} + {rejectionText}
diff --git a/web/src/lib/components/ui/Toggle.svelte b/web/src/lib/components/ui/Toggle.svelte index 86b21aa7b..e331e5265 100644 --- a/web/src/lib/components/ui/Toggle.svelte +++ b/web/src/lib/components/ui/Toggle.svelte @@ -47,7 +47,14 @@
{@render heading(doc.icon, doc.title)}

{doc.body}

-
+ Read the docs diff --git a/web/src/lib/components/welcome/Steps.svelte b/web/src/lib/components/welcome/Steps.svelte index f99c80e74..c44d21a77 100644 --- a/web/src/lib/components/welcome/Steps.svelte +++ b/web/src/lib/components/welcome/Steps.svelte @@ -7,8 +7,7 @@ slots: { root: "flex w-full items-center gap-2", item: "flex shrink-0 items-center gap-2", - marker: - "flex size-5 shrink-0 items-center justify-center rounded-full typography-paragraph-small", + marker: "flex size-5 shrink-0 items-center justify-center rounded-full typography-paragraph-small", // labels are desktop-only, but sr-only rather than hidden so the rail still // reads as a named list of steps on a narrow screen label: "sr-only typography-paragraph-small whitespace-nowrap sm:not-sr-only", diff --git a/web/src/lib/markup/markdown.test.ts b/web/src/lib/markup/markdown.test.ts index 422943355..0f9a6d51c 100644 --- a/web/src/lib/markup/markdown.test.ts +++ b/web/src/lib/markup/markdown.test.ts @@ -82,7 +82,9 @@ describe("renderMarkdown", () => { }); it("leaves off-site images alone when there is no camo", () => { - expect(render("![x](https://example.com/a.png)")).toContain('src="https://example.com/a.png"'); + expect(render("![x](https://example.com/a.png)")).toContain( + 'src="https://example.com/a.png"' + ); }); describe("with camo", () => { @@ -102,12 +104,18 @@ describe("renderMarkdown", () => { }); it("leaves our own images and repo files direct", () => { - expect(camo("![x](https://tangled.org/a.png)")).toContain('src="https://tangled.org/a.png"'); - expect(camo("![x](assets/a.png)")).toContain('src="/ada.test/infra/raw/main/assets/a.png"'); + expect(camo("![x](https://tangled.org/a.png)")).toContain( + 'src="https://tangled.org/a.png"' + ); + expect(camo("![x](assets/a.png)")).toContain( + 'src="/ada.test/infra/raw/main/assets/a.png"' + ); }); it("does not proxy links, only what the page loads by itself", () => { - expect(camo("[x](https://example.com/a.png)")).toContain('href="https://example.com/a.png"'); + expect(camo("[x](https://example.com/a.png)")).toContain( + 'href="https://example.com/a.png"' + ); }); }); diff --git a/web/src/lib/markup/markdown.ts b/web/src/lib/markup/markdown.ts index 2c5a692d8..80b428afd 100644 --- a/web/src/lib/markup/markdown.ts +++ b/web/src/lib/markup/markdown.ts @@ -74,7 +74,8 @@ const commitLinks = // only bare urls, a link someone gave a label to keeps it if (open.type !== "link_open" || open.info !== "auto") continue; const text = token.children[i + 1]; - if (text?.type !== "text" || token.children[i + 2]?.type !== "link_close") continue; + if (text?.type !== "text" || token.children[i + 2]?.type !== "link_close") + continue; const sha = shortSha(open.attrGet("href") ?? "", host); if (!sha) continue; const code = new state.Token("code_inline", "code", 0); diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index 8d1b68dc2..85426bf3b 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -11,10 +11,7 @@ Tangled · The next-generation social coding platform - + {#if auth.currentUser && data.timeline}