+ import { defineMeta } from "@storybook/addon-svelte-csf";
+ import TabPanel from "./TabPanel.svelte";
+ import Tabs from "./Tabs.svelte";
+ import SquareChartGantt from "$icon/square-chart-gantt";
+ import CircleDot from "$icon/circle-dot";
+ import GitPullRequest from "$icon/git-pull-request";
+
+ const tabs = [
+ { id: "overview", label: "Overview", icon: SquareChartGantt, href: "#" },
+ { id: "issues", label: "Issues", icon: CircleDot, count: 7, href: "#" },
+ { id: "pulls", label: "Pulls", icon: GitPullRequest, href: "#" }
+ ];
+
+ const { Story } = defineMeta({
+ title: "UI/TabPanel",
+ component: TabPanel,
+ tags: ["autodocs"]
+ });
+
+
+
+
+
+
+ The active tab's bottom edge merges into this panel — one continuous outline.
+
+
+
+
+
+
+
+
+ "Issues" is active now, and the seam moves with it.
+
+
+
+
+
+
+
+
+ Roomier vertical padding (py-6) for form-heavy pages.
+
+
+
+
+
+
+
+
+ Sidebar
+
+ Main content laid out by the caller.
+
+
+
+
diff --git a/web/src/lib/components/ui/TabPanel.svelte b/web/src/lib/components/ui/TabPanel.svelte
new file mode 100644
index 00000000..54de4371
--- /dev/null
+++ b/web/src/lib/components/ui/TabPanel.svelte
@@ -0,0 +1,39 @@
+
+
+
+
+
+ {@render children()}
+
diff --git a/web/src/lib/components/ui/Tabs.svelte b/web/src/lib/components/ui/Tabs.svelte
index b9e1ed2a..3efcd2c3 100644
--- a/web/src/lib/components/ui/Tabs.svelte
+++ b/web/src/lib/components/ui/Tabs.svelte
@@ -26,7 +26,7 @@
const navClass = $derived(
vertical
? "h-fit divide-y divide-border-default overflow-hidden rounded border border-border-default"
- : "flex w-full overflow-x-auto overflow-y-hidden pl-4"
+ : "relative z-10 flex w-full overflow-x-auto overflow-y-hidden pl-4"
);
const itemClass = (isActive: boolean) =>
@@ -36,10 +36,10 @@
? "bg-background-default text-foreground-default dark:bg-background-inset"
: "bg-background-inset text-foreground-muted hover:text-foreground-default dark:bg-background-default"
}`
- : `relative mr-1 flex items-center rounded-t px-4 py-1 whitespace-nowrap text-foreground-default no-underline hover:no-underline ${
+ : `relative mr-1 flex items-center rounded-t px-4 pt-1 pb-[5px] whitespace-nowrap text-foreground-default no-underline hover:no-underline ${
isActive
- ? "-mb-px bg-background-default [-webkit-text-stroke:0.3px_currentColor]"
- : "hover:bg-background-inset"
+ ? "border border-b-0 border-border-default bg-background-default [-webkit-text-stroke:0.3px_currentColor]"
+ : "border border-b-0 border-transparent hover:bg-background-muted hover:dark:bg-background-subtle/50"
}`;
diff --git a/web/src/routes/+error.svelte b/web/src/routes/+error.svelte
index ab92e6a8..59b8194e 100644
--- a/web/src/routes/+error.svelte
+++ b/web/src/routes/+error.svelte
@@ -42,7 +42,7 @@
-
+
+
{/if}
diff --git a/web/src/routes/[handle]/[repo]/issues/+page.svelte b/web/src/routes/[handle]/[repo]/issues/+page.svelte
index cfd3947c..32ad18ab 100644
--- a/web/src/routes/[handle]/[repo]/issues/+page.svelte
+++ b/web/src/routes/[handle]/[repo]/issues/+page.svelte
@@ -1,11 +1,12 @@
-
+
diff --git a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte
index f24b0ca1..521e7bac 100644
--- a/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte
+++ b/web/src/routes/[handle]/[repo]/issues/[aturi]/+page.svelte
@@ -6,6 +6,7 @@
import CommentList from "$lib/components/comment/CommentList.svelte";
import CommentBox from "$lib/components/comment/CommentBox.svelte";
import SignupPrompt from "$lib/components/ui/SignupPrompt.svelte";
+ import TabPanel from "$lib/components/ui/TabPanel.svelte";
import IssueForm from "$lib/components/repo/issues/IssueForm.svelte";
import ErrorAlert from "$lib/components/ui/Error.svelte";
import Pencil from "$icon/pencil";
@@ -119,7 +120,7 @@
-
+
{#if editing}
{/if}
{/if}
-
+
New issue · {data.repo.ownerHandle}/{data.repo.name} · Tangled
-
+
diff --git a/web/src/routes/[handle]/[repo]/tree/[ref]/[...path]/+page.svelte b/web/src/routes/[handle]/[repo]/tree/[ref]/[...path]/+page.svelte
index 89362def..11420b94 100644
--- a/web/src/routes/[handle]/[repo]/tree/[ref]/[...path]/+page.svelte
+++ b/web/src/routes/[handle]/[repo]/tree/[ref]/[...path]/+page.svelte
@@ -3,15 +3,14 @@
import LastCommitPanel from "$lib/components/repo/LastCommitPanel.svelte";
import Readme from "$lib/components/repo/Readme.svelte";
import TreeHeader from "$lib/components/repo/TreeHeader.svelte";
+ import TabPanel from "$lib/components/ui/TabPanel.svelte";
let { data } = $props();
const repo = $derived(data.repo);
-
+
{#if data.readme}
diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte
index 2449209a..236716d1 100644
--- a/web/src/routes/login/+page.svelte
+++ b/web/src/routes/login/+page.svelte
@@ -98,7 +98,7 @@
{#if auth.error}