Detailed changes
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./IssueRow.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`IssueRow/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./LabelBadge.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`LabelBadge/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./StatusBadge.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`StatusBadge/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,444 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`IssueRow/ClosedIssue matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-check mt-0.5 size-4 shrink-0 text-purple-600 dark:text-purple-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <path
+ d="m9 12 2 2 4-4"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Add dark mode support
+ </a>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(163, 230, 53); color: rgba(0, 0, 0, 0.75);"
+ >
+ enhancement
+ </span>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #d4e5f6 opened
+ about 1 hour ago
+ </p>
+ </div>
+ <div
+ class="text-muted-foreground flex shrink-0 items-center gap-1 text-xs"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-message-square size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"
+ />
+ </svg>
+ 12
+ </div>
+ </div>
+</div>
+`;
+
+exports[`IssueRow/List matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border rounded-md border"
+ >
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0 hover:bg-muted/30"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot mt-0.5 size-4 shrink-0 text-green-600 dark:text-green-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Fix login page crash on empty email
+ </a>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(252, 41, 41); color: rgba(255, 255, 255, 0.9);"
+ >
+ bug
+ </span>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #a1b2c3 opened
+ about 1 hour ago
+ by Jane Doe
+ </p>
+ </div>
+ <div
+ class="text-muted-foreground flex shrink-0 items-center gap-1 text-xs"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-message-square size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"
+ />
+ </svg>
+ 3
+ </div>
+ </div>
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0 hover:bg-muted/30"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot mt-0.5 size-4 shrink-0 text-green-600 dark:text-green-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Add dark mode support
+ </a>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(163, 230, 53); color: rgba(0, 0, 0, 0.75);"
+ >
+ enhancement
+ </span>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #d4e5f6 opened
+ about 1 hour ago
+ by Bob
+ </p>
+ </div>
+ </div>
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0 hover:bg-muted/30"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-check mt-0.5 size-4 shrink-0 text-purple-600 dark:text-purple-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <path
+ d="m9 12 2 2 4-4"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Update dependencies
+ </a>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #g7h8i9 opened
+ about 1 hour ago
+ by Alice
+ </p>
+ </div>
+ <div
+ class="text-muted-foreground flex shrink-0 items-center gap-1 text-xs"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-message-square size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"
+ />
+ </svg>
+ 7
+ </div>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`IssueRow/NoLabelsNoComments matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot mt-0.5 size-4 shrink-0 text-green-600 dark:text-green-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Simple issue with no labels
+ </a>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #abc123 opened
+ about 1 hour ago
+ by
+ <a
+ class="hover:underline"
+ href="#"
+ >
+ Bob
+ </a>
+ </p>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`IssueRow/OpenIssue matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border flex items-start gap-3 border-b px-4 py-3 last:border-0 hover:bg-muted/30"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot mt-0.5 size-4 shrink-0 text-green-600 dark:text-green-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ <div
+ class="min-w-0 flex-1"
+ >
+ <div
+ class="flex flex-wrap items-baseline gap-2"
+ >
+ <a
+ class="text-foreground hover:text-primary font-medium hover:underline"
+ href="#"
+ >
+ Fix login page crash on empty email
+ </a>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(252, 41, 41); color: rgba(255, 255, 255, 0.9);"
+ >
+ bug
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(255, 152, 0); color: rgba(0, 0, 0, 0.75);"
+ >
+ priority
+ </span>
+ </div>
+ <p
+ class="text-muted-foreground mt-0.5 text-xs"
+ >
+ #a1b2c3 opened
+ about 1 hour ago
+ by
+ <a
+ class="hover:underline"
+ href="#"
+ >
+ Jane Doe
+ </a>
+ </p>
+ </div>
+ <div
+ class="text-muted-foreground flex shrink-0 items-center gap-1 text-xs"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-message-square size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"
+ />
+ </svg>
+ 3
+ </div>
+ </div>
+</div>
+`;
@@ -0,0 +1,90 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`LabelBadge/AllColors matches snapshot 1`] = `
+<div>
+ <div
+ class="flex flex-wrap gap-2"
+ >
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(252, 41, 41); color: rgba(255, 255, 255, 0.9);"
+ >
+ bug
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(163, 230, 53); color: rgba(0, 0, 0, 0.75);"
+ >
+ enhancement
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(30, 80, 160); color: rgba(255, 255, 255, 0.9);"
+ >
+ documentation
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(0, 150, 136); color: rgba(255, 255, 255, 0.9);"
+ >
+ help wanted
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(200, 200, 200); color: rgba(0, 0, 0, 0.75);"
+ >
+ wontfix
+ </span>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(255, 152, 0); color: rgba(0, 0, 0, 0.75);"
+ >
+ priority
+ </span>
+ </div>
+</div>
+`;
+
+exports[`LabelBadge/Clickable matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(100, 200, 150); color: rgba(0, 0, 0, 0.75);"
+ >
+ feature
+ </span>
+</div>
+`;
+
+exports[`LabelBadge/DarkBackground matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(30, 80, 160); color: rgba(255, 255, 255, 0.9);"
+ >
+ documentation
+ </span>
+</div>
+`;
+
+exports[`LabelBadge/Default matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(252, 41, 41); color: rgba(255, 255, 255, 0.9);"
+ >
+ bug
+ </span>
+</div>
+`;
+
+exports[`LabelBadge/LightBackground matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium "
+ style="background-color: rgb(163, 230, 53); color: rgba(0, 0, 0, 0.75);"
+ >
+ enhancement
+ </span>
+</div>
+`;
@@ -0,0 +1,67 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`StatusBadge/Closed matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-check size-3"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <path
+ d="m9 12 2 2 4-4"
+ />
+ </svg>
+ Closed
+ </span>
+</div>
+`;
+
+exports[`StatusBadge/Open matches snapshot 1`] = `
+<div>
+ <span
+ class="inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot size-3"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ Open
+ </span>
+</div>
+`;
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./CodeBreadcrumb.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`CodeBreadcrumb/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./FileTree.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`FileTree/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./FileViewer.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`FileViewer/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./RefSelector.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`RefSelector/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,305 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`CodeBreadcrumb/DeepPath matches snapshot 1`] = `
+<div>
+ <div
+ class="flex flex-wrap items-center gap-1 font-mono text-sm"
+ >
+ <a
+ class="text-foreground font-medium hover:underline"
+ href="/git-bug/tree/feature%2Fauth"
+ >
+ git-bug
+ </a>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/feature%2Fauth/src"
+ >
+ src
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/feature%2Fauth/src/components"
+ >
+ components
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/feature%2Fauth/src/components/bugs"
+ >
+ bugs
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/feature%2Fauth/src/components/bugs/timeline"
+ >
+ timeline
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <span
+ class="text-foreground font-medium"
+ >
+ CommentItem.tsx
+ </span>
+ </span>
+ <span
+ class="text-muted-foreground ml-2 text-xs"
+ >
+ @
+ feature/auth
+ </span>
+ </div>
+</div>
+`;
+
+exports[`CodeBreadcrumb/FilePath matches snapshot 1`] = `
+<div>
+ <div
+ class="flex flex-wrap items-center gap-1 font-mono text-sm"
+ >
+ <a
+ class="text-foreground font-medium hover:underline"
+ href="/git-bug/tree/main"
+ >
+ git-bug
+ </a>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/main/src"
+ >
+ src
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/main/src/components"
+ >
+ components
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <a
+ class="text-muted-foreground hover:text-foreground hover:underline"
+ href="/git-bug/tree/main/src/components/ui"
+ >
+ ui
+ </a>
+ </span>
+ <span
+ class="flex items-center gap-1"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevron-right text-muted-foreground size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m9 18 6-6-6-6"
+ />
+ </svg>
+ <span
+ class="text-foreground font-medium"
+ >
+ button.tsx
+ </span>
+ </span>
+ <span
+ class="text-muted-foreground ml-2 text-xs"
+ >
+ @
+ main
+ </span>
+ </div>
+</div>
+`;
+
+exports[`CodeBreadcrumb/RootPath matches snapshot 1`] = `
+<div>
+ <div
+ class="flex flex-wrap items-center gap-1 font-mono text-sm"
+ >
+ <a
+ class="text-foreground font-medium hover:underline"
+ href="/git-bug/tree/main"
+ >
+ git-bug
+ </a>
+ <span
+ class="text-muted-foreground ml-2 text-xs"
+ >
+ @
+ main
+ </span>
+ </div>
+</div>
+`;
@@ -0,0 +1,423 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`FileTree/RootDirectory matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border overflow-hidden rounded-md border"
+ >
+ <table
+ class="w-full text-sm"
+ >
+ <tbody
+ class="divide-border divide-y"
+ >
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-folder size-4 text-blue-500 dark:text-blue-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono font-medium hover:underline"
+ href="/my-repo/tree/main/docs"
+ >
+ docs
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def2"
+ >
+ docs: update getting started guide
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ 2 days ago
+ </td>
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-folder size-4 text-blue-500 dark:text-blue-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono font-medium hover:underline"
+ href="/my-repo/tree/main/src"
+ >
+ src
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def1"
+ >
+ refactor: restructure source directory
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ 1 day ago
+ </td>
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-file text-muted-foreground size-4"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
+ />
+ <path
+ d="M14 2v5a1 1 0 0 0 1 1h5"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono hover:underline"
+ href="/my-repo/blob/main/.gitignore"
+ >
+ .gitignore
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ />
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ />
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-file text-muted-foreground size-4"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
+ />
+ <path
+ d="M14 2v5a1 1 0 0 0 1 1h5"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono hover:underline"
+ href="/my-repo/blob/main/package.json"
+ >
+ package.json
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def4"
+ >
+ chore: bump dependencies
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ about 2 hours ago
+ </td>
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-file text-muted-foreground size-4"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
+ />
+ <path
+ d="M14 2v5a1 1 0 0 0 1 1h5"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono hover:underline"
+ href="/my-repo/blob/main/README.md"
+ >
+ README.md
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def3"
+ >
+ docs: add badges to README
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ about 1 hour ago
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+`;
+
+exports[`FileTree/SubDirectory matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border overflow-hidden rounded-md border"
+ >
+ <table
+ class="w-full text-sm"
+ >
+ <tbody
+ class="divide-border divide-y"
+ >
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ colspan="4"
+ >
+ <a
+ class="flex items-center gap-3 py-2 pl-4"
+ href="/my-repo/tree/main"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-folder size-4 text-blue-500 dark:text-blue-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
+ />
+ </svg>
+ <span
+ class="text-muted-foreground font-mono"
+ >
+ ..
+ </span>
+ </a>
+ </td>
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-folder size-4 text-blue-500 dark:text-blue-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono font-medium hover:underline"
+ href="/my-repo/tree/main/src/components"
+ >
+ components
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def5"
+ >
+ feat: add button component
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ about 1 hour ago
+ </td>
+ </tr>
+ <tr
+ class="hover:bg-muted/40"
+ >
+ <td
+ class="w-6 py-2 pl-4"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-file text-muted-foreground size-4"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
+ />
+ <path
+ d="M14 2v5a1 1 0 0 0 1 1h5"
+ />
+ </svg>
+ </td>
+ <td
+ class="px-3 py-2"
+ >
+ <a
+ class="font-mono hover:underline"
+ href="/my-repo/blob/main/src/index.ts"
+ >
+ index.ts
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden max-w-xs truncate px-3 py-2 md:table-cell"
+ >
+ <a
+ class="hover:text-foreground hover:underline"
+ href="/my-repo/commit/def6"
+ >
+ fix: correct export paths
+ </a>
+ </td>
+ <td
+ class="text-muted-foreground hidden px-4 py-2 text-right text-xs whitespace-nowrap md:table-cell"
+ >
+ about 2 hours ago
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+</div>
+`;
@@ -0,0 +1,346 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`FileViewer/BinaryFile matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border overflow-hidden rounded-md border"
+ >
+ <div
+ class="border-border bg-muted/40 text-muted-foreground flex items-center justify-between border-b px-4 py-2 text-xs"
+ >
+ <span>
+ 0
+ lines Β·
+ 24.0 KB
+ </span>
+ <button
+ class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground size-7"
+ title="Copy"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-copy size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <rect
+ height="14"
+ rx="2"
+ ry="2"
+ width="14"
+ x="8"
+ y="8"
+ />
+ <path
+ d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
+ />
+ </svg>
+ </button>
+ </div>
+ <div
+ class="text-muted-foreground px-4 py-8 text-center text-sm"
+ >
+ Binary file β
+ 24.0 KB
+ </div>
+ </div>
+</div>
+`;
+
+exports[`FileViewer/Loading matches snapshot 1`] = `
+<div>
+ <div
+ class="divide-border border-border divide-y rounded-md border"
+ >
+ <div
+ class="flex items-center gap-2 px-4 py-2"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-4 w-48"
+ />
+ </div>
+ <div
+ class="p-4"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-64 w-full"
+ />
+ </div>
+ </div>
+</div>
+`;
+
+exports[`FileViewer/TruncatedFile matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border overflow-hidden rounded-md border"
+ >
+ <div
+ class="border-border bg-muted/40 text-muted-foreground flex items-center justify-between border-b px-4 py-2 text-xs"
+ >
+ <span>
+ 4
+ lines Β·
+ 1.0 MB
+ Β· truncated
+ </span>
+ <button
+ class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground size-7"
+ title="Copy"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-copy size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <rect
+ height="14"
+ rx="2"
+ ry="2"
+ width="14"
+ x="8"
+ y="8"
+ />
+ <path
+ d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"
+ />
+ </svg>
+ </button>
+ </div>
+ <div
+ class="flex overflow-x-auto font-mono text-xs leading-5"
+ >
+ <div
+ aria-hidden="true"
+ class="border-border bg-muted/20 text-muted-foreground/50 border-r px-4 py-4 text-right select-none"
+ >
+ <div>
+ 1
+ </div>
+ <div>
+ 2
+ </div>
+ <div>
+ 3
+ </div>
+ <div>
+ 4
+ </div>
+ </div>
+ <pre
+ class="flex-1 overflow-visible px-4 py-4"
+ >
+ <code
+ class="hljs !bg-transparent !p-0"
+ >
+ line
+ <span
+ class="hljs-number"
+ >
+ 1
+ </span>
+
+line
+ <span
+ class="hljs-number"
+ >
+ 2
+ </span>
+
+line
+ <span
+ class="hljs-number"
+ >
+ 3
+ </span>
+
+... (truncated)
+ </code>
+ </pre>
+ </div>
+ </div>
+</div>
+`;
+
+exports[`FileViewer/TypeScriptFile matches snapshot 1`] = `
+<div>
+ <div
+ class="border-border overflow-hidden rounded-md border"
+ >
+ <div
+ class="border-border bg-muted/40 border-b px-4 py-2"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-4 w-32"
+ />
+ </div>
+ <div
+ class="flex gap-4 p-4"
+ >
+ <div
+ class="space-y-1.5"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5 w-6"
+ />
+ </div>
+ <div
+ class="flex-1 space-y-1.5"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 70.27272538529849%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 84.39202253245477%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 36.70967368601532%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 87.50159030488214%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 51.86083821665096%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 46.479699116022175%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 36.75406000862486%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 60.27590888571913%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 38.67713014525041%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 86.91154246154659%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 77.40682922983703%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 82.74792087067682%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 61.364498248188944%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 48.028107813055215%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 61.27378677034177%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 50.634245170950734%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 40.67974048538118%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 87.04517503265906%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 31.598566849419893%;"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-3.5"
+ style="width: 51.4887047773234%;"
+ />
+ </div>
+ </div>
+ </div>
+</div>
+`;
@@ -0,0 +1,187 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`RefSelector/BranchesOnly matches snapshot 1`] = `
+<div>
+ <button
+ aria-controls="radix-_r_2_"
+ aria-expanded="false"
+ aria-haspopup="dialog"
+ class="inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 gap-2 font-mono text-xs"
+ data-state="closed"
+ type="button"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-git-branch size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M15 6a9 9 0 0 0-9 9V3"
+ />
+ <circle
+ cx="18"
+ cy="6"
+ r="3"
+ />
+ <circle
+ cx="6"
+ cy="18"
+ r="3"
+ />
+ </svg>
+ develop
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevrons-up-down text-muted-foreground size-3"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m7 15 5 5 5-5"
+ />
+ <path
+ d="m7 9 5-5 5 5"
+ />
+ </svg>
+ </button>
+</div>
+`;
+
+exports[`RefSelector/Default matches snapshot 1`] = `
+<div>
+ <button
+ aria-controls="radix-_r_0_"
+ aria-expanded="false"
+ aria-haspopup="dialog"
+ class="inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 gap-2 font-mono text-xs"
+ data-state="closed"
+ type="button"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-git-branch size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M15 6a9 9 0 0 0-9 9V3"
+ />
+ <circle
+ cx="18"
+ cy="6"
+ r="3"
+ />
+ <circle
+ cx="6"
+ cy="18"
+ r="3"
+ />
+ </svg>
+ main
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevrons-up-down text-muted-foreground size-3"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m7 15 5 5 5-5"
+ />
+ <path
+ d="m7 9 5-5 5 5"
+ />
+ </svg>
+ </button>
+</div>
+`;
+
+exports[`RefSelector/OnTag matches snapshot 1`] = `
+<div>
+ <button
+ aria-controls="radix-_r_1_"
+ aria-expanded="false"
+ aria-haspopup="dialog"
+ class="inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 gap-2 font-mono text-xs"
+ data-state="closed"
+ type="button"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-git-branch size-3.5"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M15 6a9 9 0 0 0-9 9V3"
+ />
+ <circle
+ cx="18"
+ cy="6"
+ r="3"
+ />
+ <circle
+ cx="6"
+ cy="18"
+ r="3"
+ />
+ </svg>
+ v1.1.0
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-chevrons-up-down text-muted-foreground size-3"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m7 15 5 5 5-5"
+ />
+ <path
+ d="m7 9 5-5 5 5"
+ />
+ </svg>
+ </button>
+</div>
+`;
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./Markdown.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Markdown/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,413 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Markdown/BasicFormatting matches snapshot 1`] = `
+<div>
+ <div
+ class="prose prose-sm dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:text-foreground prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded-sm prose-code:text-sm prose-code:before:content-none prose-code:after:content-none prose-img:inline prose-img:my-0"
+ >
+ <h1
+ id="heading-1"
+ >
+ Heading 1
+ <a
+ aria-hidden="true"
+ href="#heading-1"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h1>
+
+
+ <h2
+ id="heading-2"
+ >
+ Heading 2
+ <a
+ aria-hidden="true"
+ href="#heading-2"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h2>
+
+
+ <h3
+ id="heading-3"
+ >
+ Heading 3
+ <a
+ aria-hidden="true"
+ href="#heading-3"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h3>
+
+
+ <p>
+ This is a paragraph with
+ <strong>
+ bold
+ </strong>
+ ,
+ <em>
+ italic
+ </em>
+ , and
+ <code>
+ inline code
+ </code>
+ .
+ </p>
+
+
+ <ul>
+
+
+ <li>
+ Unordered list item 1
+ </li>
+
+
+ <li>
+ Unordered list item 2
+
+ <ul>
+
+
+ <li>
+ Nested item
+ </li>
+
+
+ </ul>
+
+
+ </li>
+
+
+ </ul>
+
+
+ <ol>
+
+
+ <li>
+ Ordered list item 1
+ </li>
+
+
+ <li>
+ Ordered list item 2
+ </li>
+
+
+ </ol>
+
+
+ <blockquote>
+
+
+ <p>
+ This is a blockquote.
+ </p>
+
+
+ </blockquote>
+
+
+ <hr />
+
+
+ <p>
+ <a
+ href="https://example.com"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ A link
+ </a>
+ </p>
+ </div>
+</div>
+`;
+
+exports[`Markdown/CodeBlock matches snapshot 1`] = `
+<div>
+ <div
+ class="prose prose-sm dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:text-foreground prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded-sm prose-code:text-sm prose-code:before:content-none prose-code:after:content-none prose-img:inline prose-img:my-0"
+ >
+ <p>
+ Here is a code block:
+ </p>
+
+
+ <pre>
+ <code
+ class="language-typescript"
+ >
+ interface User {
+ id: string;
+ name: string;
+ email: string;
+}
+
+function greet(user: User): string {
+ return \`Hello, \${user.name}!\`;
+}
+
+ </code>
+ </pre>
+ </div>
+</div>
+`;
+
+exports[`Markdown/Comment matches snapshot 1`] = `
+<div>
+ <div
+ class="prose prose-sm dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:text-foreground prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded-sm prose-code:text-sm prose-code:before:content-none prose-code:after:content-none prose-img:inline prose-img:my-0"
+ >
+ <p>
+ Fixed the issue by updating the query builder.
+ </p>
+
+
+ <p>
+ The problem was that
+ <code>
+ buildQuery()
+ </code>
+ wasn't escaping special characters in label names containing spaces.
+ </p>
+
+
+ <pre>
+ <code
+ class="language-diff"
+ >
+ - const q = \`label:\${name}\`;
++ const q = \`label:"\${name}"\`;
+
+ </code>
+ </pre>
+
+
+ <p>
+ Closes #42.
+ </p>
+ </div>
+</div>
+`;
+
+exports[`Markdown/GithubFlavored matches snapshot 1`] = `
+<div>
+ <div
+ class="prose prose-sm dark:prose-invert max-w-none prose-pre:bg-muted prose-pre:text-foreground prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:rounded-sm prose-code:text-sm prose-code:before:content-none prose-code:after:content-none prose-img:inline prose-img:my-0"
+ >
+ <h2
+ id="task-list"
+ >
+ Task list
+ <a
+ aria-hidden="true"
+ href="#task-list"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h2>
+
+
+ <ul
+ class="contains-task-list"
+ >
+
+
+ <li
+ class="task-list-item"
+ >
+ <input
+ checked=""
+ disabled=""
+ type="checkbox"
+ />
+ Completed task
+ </li>
+
+
+ <li
+ class="task-list-item"
+ >
+ <input
+ disabled=""
+ type="checkbox"
+ />
+ Incomplete task
+ </li>
+
+
+ <li
+ class="task-list-item"
+ >
+ <input
+ disabled=""
+ type="checkbox"
+ />
+ Another task
+ </li>
+
+
+ </ul>
+
+
+ <h2
+ id="table"
+ >
+ Table
+ <a
+ aria-hidden="true"
+ href="#table"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <table>
+ <thead>
+ <tr>
+ <th>
+ Feature
+ </th>
+ <th>
+ Status
+ </th>
+ <th>
+ Priority
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ Auth
+ </td>
+ <td>
+ Done
+ </td>
+ <td>
+ High
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Search
+ </td>
+ <td>
+ WIP
+ </td>
+ <td>
+ Medium
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Export
+ </td>
+ <td>
+ Todo
+ </td>
+ <td>
+ Low
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+
+ <h2
+ id="strikethrough"
+ >
+ Strikethrough
+ <a
+ aria-hidden="true"
+ href="#strikethrough"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h2>
+
+
+ <p>
+ This is
+ <del>
+ deleted
+ </del>
+ text.
+ </p>
+
+
+ <h2
+ id="emoji"
+ >
+ Emoji
+ <a
+ aria-hidden="true"
+ href="#emoji"
+ tabindex="-1"
+ >
+ <span
+ class="icon icon-link"
+ />
+ </a>
+ </h2>
+
+
+ <p>
+ π π β¨
+ </p>
+ </div>
+</div>
+`;
@@ -0,0 +1,57 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Avatar/Large matches snapshot 1`] = `
+<div>
+ <span
+ class="relative flex shrink-0 overflow-hidden rounded-full size-16"
+ >
+ <span
+ class="flex h-full w-full items-center justify-center rounded-full bg-muted text-xs font-medium"
+ >
+ CN
+ </span>
+ </span>
+</div>
+`;
+
+exports[`Avatar/Small matches snapshot 1`] = `
+<div>
+ <span
+ class="relative flex shrink-0 overflow-hidden rounded-full size-6"
+ >
+ <span
+ class="flex h-full w-full items-center justify-center rounded-full bg-muted font-medium text-[8px]"
+ >
+ AB
+ </span>
+ </span>
+</div>
+`;
+
+exports[`Avatar/WithFallback matches snapshot 1`] = `
+<div>
+ <span
+ class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full"
+ >
+ <span
+ class="flex h-full w-full items-center justify-center rounded-full bg-muted text-xs font-medium"
+ >
+ JD
+ </span>
+ </span>
+</div>
+`;
+
+exports[`Avatar/WithImage matches snapshot 1`] = `
+<div>
+ <span
+ class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full"
+ >
+ <span
+ class="flex h-full w-full items-center justify-center rounded-full bg-muted text-xs font-medium"
+ >
+ CN
+ </span>
+ </span>
+</div>
+`;
@@ -0,0 +1,41 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Badge/Default matches snapshot 1`] = `
+<div>
+ <div
+ class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-primary text-primary-foreground shadow-sm hover:bg-primary/80"
+ >
+ Badge
+ </div>
+</div>
+`;
+
+exports[`Badge/Destructive matches snapshot 1`] = `
+<div>
+ <div
+ class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/80"
+ >
+ Destructive
+ </div>
+</div>
+`;
+
+exports[`Badge/Outline matches snapshot 1`] = `
+<div>
+ <div
+ class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground"
+ >
+ Outline
+ </div>
+</div>
+`;
+
+exports[`Badge/Secondary matches snapshot 1`] = `
+<div>
+ <div
+ class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80"
+ >
+ Secondary
+ </div>
+</div>
+`;
@@ -0,0 +1,39 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Input/Default matches snapshot 1`] = `
+<div>
+ <input
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ placeholder="Type somethingβ¦"
+ />
+</div>
+`;
+
+exports[`Input/Disabled matches snapshot 1`] = `
+<div>
+ <input
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ disabled=""
+ placeholder="Disabled"
+ />
+</div>
+`;
+
+exports[`Input/Password matches snapshot 1`] = `
+<div>
+ <input
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ placeholder="Enter password"
+ type="password"
+ />
+</div>
+`;
+
+exports[`Input/WithValue matches snapshot 1`] = `
+<div>
+ <input
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ value="Hello world"
+ />
+</div>
+`;
@@ -0,0 +1,266 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`QueryInput/AsyncCompletions matches snapshot 1`] = `
+<div>
+ <div
+ class="relative flex flex-1 items-center rounded-md border border-input bg-background ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2"
+ >
+ <div
+ class="text-muted-foreground pointer-events-none absolute left-3 size-4 shrink-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-search"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m21 21-4.34-4.34"
+ />
+ <circle
+ cx="11"
+ cy="11"
+ r="8"
+ />
+ </svg>
+ </div>
+ <div
+ aria-hidden="true"
+ class="text-foreground pointer-events-none absolute inset-0 flex items-center overflow-hidden pr-3 pl-9 font-mono text-sm whitespace-pre"
+ />
+ <input
+ autocomplete="off"
+ class="caret-foreground placeholder:text-muted-foreground relative w-full bg-transparent py-2 pr-3 pl-9 font-mono text-sm text-transparent outline-hidden placeholder:font-sans"
+ placeholder="Type label: to see async loadingβ¦"
+ spellcheck="false"
+ type="text"
+ value=""
+ />
+ </div>
+</div>
+`;
+
+exports[`QueryInput/Default matches snapshot 1`] = `
+<div>
+ <div
+ class="relative flex flex-1 items-center rounded-md border border-input bg-background ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2"
+ >
+ <div
+ class="text-muted-foreground pointer-events-none absolute left-3 size-4 shrink-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-search"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m21 21-4.34-4.34"
+ />
+ <circle
+ cx="11"
+ cy="11"
+ r="8"
+ />
+ </svg>
+ </div>
+ <div
+ aria-hidden="true"
+ class="text-foreground pointer-events-none absolute inset-0 flex items-center overflow-hidden pr-3 pl-9 font-mono text-sm whitespace-pre"
+ >
+ <span>
+ <span
+ class="text-green-600 dark:text-green-400"
+ >
+ status:
+ </span>
+ <span>
+ open
+ </span>
+ </span>
+ </div>
+ <input
+ autocomplete="off"
+ class="caret-foreground placeholder:text-muted-foreground relative w-full bg-transparent py-2 pr-3 pl-9 font-mono text-sm text-transparent outline-hidden placeholder:font-sans"
+ placeholder="status:open author:β¦ label:β¦"
+ spellcheck="false"
+ type="text"
+ value="status:open"
+ />
+ </div>
+</div>
+`;
+
+exports[`QueryInput/SyntaxOnly matches snapshot 1`] = `
+<div>
+ <div
+ class="relative flex flex-1 items-center rounded-md border border-input bg-background ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2"
+ >
+ <div
+ class="text-muted-foreground pointer-events-none absolute left-3 size-4 shrink-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-search"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m21 21-4.34-4.34"
+ />
+ <circle
+ cx="11"
+ cy="11"
+ r="8"
+ />
+ </svg>
+ </div>
+ <div
+ aria-hidden="true"
+ class="text-foreground pointer-events-none absolute inset-0 flex items-center overflow-hidden pr-3 pl-9 font-mono text-sm whitespace-pre"
+ >
+ <span>
+ <span
+ class="text-green-600 dark:text-green-400"
+ >
+ status:
+ </span>
+ <span>
+ open
+ </span>
+ </span>
+ <span>
+
+ </span>
+ <span>
+ label:bug
+ </span>
+ </div>
+ <input
+ autocomplete="off"
+ class="caret-foreground placeholder:text-muted-foreground relative w-full bg-transparent py-2 pr-3 pl-9 font-mono text-sm text-transparent outline-hidden placeholder:font-sans"
+ placeholder="Searchβ¦"
+ spellcheck="false"
+ type="text"
+ value="status:open label:bug"
+ />
+ </div>
+</div>
+`;
+
+exports[`QueryInput/WithFilters matches snapshot 1`] = `
+<div>
+ <div
+ class="relative flex flex-1 items-center rounded-md border border-input bg-background ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2"
+ >
+ <div
+ class="text-muted-foreground pointer-events-none absolute left-3 size-4 shrink-0"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-search"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="m21 21-4.34-4.34"
+ />
+ <circle
+ cx="11"
+ cy="11"
+ r="8"
+ />
+ </svg>
+ </div>
+ <div
+ aria-hidden="true"
+ class="text-foreground pointer-events-none absolute inset-0 flex items-center overflow-hidden pr-3 pl-9 font-mono text-sm whitespace-pre"
+ >
+ <span>
+ <span
+ class="text-green-600 dark:text-green-400"
+ >
+ status:
+ </span>
+ <span>
+ open
+ </span>
+ </span>
+ <span>
+
+ </span>
+ <span>
+ <span
+ class="text-yellow-600 dark:text-yellow-500"
+ >
+ label:
+ </span>
+ <span>
+ bug
+ </span>
+ </span>
+ <span>
+
+ </span>
+ <span>
+ <span
+ class="text-blue-600 dark:text-blue-400"
+ >
+ author:
+ </span>
+ <span>
+ janedoe
+ </span>
+ </span>
+ <span>
+
+ </span>
+ <span>
+ fix
+ </span>
+ <span>
+
+ </span>
+ <span>
+ login
+ </span>
+ </div>
+ <input
+ autocomplete="off"
+ class="caret-foreground placeholder:text-muted-foreground relative w-full bg-transparent py-2 pr-3 pl-9 font-mono text-sm text-transparent outline-hidden placeholder:font-sans"
+ placeholder="status:open author:β¦ label:β¦"
+ spellcheck="false"
+ type="text"
+ value="status:open label:bug author:janedoe fix login"
+ />
+ </div>
+</div>
+`;
@@ -0,0 +1,49 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Separator/Horizontal matches snapshot 1`] = `
+<div>
+ <div
+ class="w-64 space-y-2"
+ >
+ <p
+ class="text-sm"
+ >
+ Above
+ </p>
+ <div
+ class="shrink-0 bg-border h-[1px] w-full"
+ data-orientation="horizontal"
+ role="none"
+ />
+ <p
+ class="text-sm"
+ >
+ Below
+ </p>
+ </div>
+</div>
+`;
+
+exports[`Separator/Vertical matches snapshot 1`] = `
+<div>
+ <div
+ class="flex h-8 items-center gap-2"
+ >
+ <span
+ class="text-sm"
+ >
+ Left
+ </span>
+ <div
+ class="shrink-0 bg-border h-full w-[1px]"
+ data-orientation="vertical"
+ role="none"
+ />
+ <span
+ class="text-sm"
+ >
+ Right
+ </span>
+ </div>
+</div>
+`;
@@ -0,0 +1,39 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Skeleton/Card matches snapshot 1`] = `
+<div>
+ <div
+ class="flex items-center gap-4"
+ >
+ <div
+ class="animate-pulse bg-primary/10 size-12 rounded-full"
+ />
+ <div
+ class="space-y-2"
+ >
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-4 w-48"
+ />
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-4 w-32"
+ />
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Skeleton/Circle matches snapshot 1`] = `
+<div>
+ <div
+ class="animate-pulse bg-primary/10 size-10 rounded-full"
+ />
+</div>
+`;
+
+exports[`Skeleton/Default matches snapshot 1`] = `
+<div>
+ <div
+ class="animate-pulse rounded-md bg-primary/10 h-4 w-48"
+ />
+</div>
+`;
@@ -0,0 +1,76 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`StatusTabs/Default matches snapshot 1`] = `
+<div>
+ <div
+ class="flex items-center gap-1"
+ >
+ <button
+ class="bg-accent text-accent-foreground flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-dot size-4 group-[.active]:text-green-600 dark:group-[.active]:text-green-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <circle
+ cx="12"
+ cy="12"
+ r="1"
+ />
+ </svg>
+ Open
+ <span
+ class="bg-muted ml-0.5 rounded-full px-1.5 py-0.5 text-xs leading-none"
+ >
+ 12
+ </span>
+ </button>
+ <button
+ class="text-muted-foreground hover:bg-accent/50 hover:text-foreground flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium"
+ >
+ <svg
+ aria-hidden="true"
+ class="lucide lucide-circle-check size-4 group-[.active]:text-purple-600 dark:group-[.active]:text-purple-400"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <circle
+ cx="12"
+ cy="12"
+ r="10"
+ />
+ <path
+ d="m9 12 2 2 4-4"
+ />
+ </svg>
+ Closed
+ <span
+ class="bg-muted ml-0.5 rounded-full px-1.5 py-0.5 text-xs leading-none"
+ >
+ 5
+ </span>
+ </button>
+ </div>
+</div>
+`;
@@ -0,0 +1,30 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Textarea/Default matches snapshot 1`] = `
+<div>
+ <textarea
+ class="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ placeholder="Write a commentβ¦"
+ />
+</div>
+`;
+
+exports[`Textarea/Disabled matches snapshot 1`] = `
+<div>
+ <textarea
+ class="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ disabled=""
+ placeholder="Disabled"
+ />
+</div>
+`;
+
+exports[`Textarea/WithValue matches snapshot 1`] = `
+<div>
+ <textarea
+ class="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
+ >
+ This is some content in the textarea.
+ </textarea>
+</div>
+`;
@@ -0,0 +1,86 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`WritePreview/Controlled matches snapshot 1`] = `
+<div>
+ <div>
+ <div
+ class="flex gap-2 mb-2"
+ >
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm transition-colors bg-muted font-medium"
+ type="button"
+ >
+ Write
+ </button>
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm font-medium transition-colors disabled:opacity-40 text-muted-foreground hover:text-foreground"
+ disabled=""
+ type="button"
+ >
+ Preview
+ </button>
+ </div>
+ <textarea
+ class="flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm min-h-[120px]"
+ placeholder="Leave a commentβ¦"
+ />
+ </div>
+</div>
+`;
+
+exports[`WritePreview/Empty matches snapshot 1`] = `
+<div>
+ <div>
+ <div
+ class="flex gap-2 mb-2"
+ >
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm transition-colors bg-muted font-medium"
+ type="button"
+ >
+ Write
+ </button>
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm font-medium transition-colors disabled:opacity-40 text-muted-foreground hover:text-foreground"
+ disabled=""
+ type="button"
+ >
+ Preview
+ </button>
+ </div>
+ <textarea
+ class="flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm min-h-[120px]"
+ placeholder="Preview is disabled until you type somethingβ¦"
+ />
+ </div>
+</div>
+`;
+
+exports[`WritePreview/Uncontrolled matches snapshot 1`] = `
+<div>
+ <div>
+ <div
+ class="flex gap-2 mb-2"
+ >
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm transition-colors bg-muted font-medium"
+ type="button"
+ >
+ Write
+ </button>
+ <button
+ class="rounded-sm px-2 py-0.5 text-sm font-medium transition-colors disabled:opacity-40 text-muted-foreground hover:text-foreground"
+ type="button"
+ >
+ Preview
+ </button>
+ </div>
+ <textarea
+ class="flex w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm min-h-[200px]"
+ placeholder="Describe the issueβ¦"
+ >
+ Hello **world**!
+ </textarea>
+ </div>
+</div>
+`;
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./avatar.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Avatar/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./badge.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Badge/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./input.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Input/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./query-input.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`QueryInput/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./separator.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Separator/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./skeleton.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Skeleton/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./status-tabs.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`StatusTabs/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./textarea.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`Textarea/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}
@@ -0,0 +1,13 @@
+import { composeStories } from "@storybook/react-vite";
+import { expect, test } from "vitest";
+
+import * as stories from "./write-preview.stories";
+
+const composed = composeStories(stories);
+
+for (const [name, Story] of Object.entries(composed)) {
+ test(`WritePreview/${name} matches snapshot`, async () => {
+ await Story.run();
+ expect(document.body.firstChild).toMatchSnapshot();
+ });
+}