Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import type { Preview } from "@storybook/react-vite";
import type { Decorator, Preview } from "@storybook/react-vite";
import { useEffect } from "react";
import { INITIAL_VIEWPORTS, MINIMAL_VIEWPORTS } from "storybook/viewport";
import "../src/fonts.css";
import "../src/globals.css";

const withDarkMode: Decorator = (Story, context) => {
const raw = context.globals.darkMode;
const darkMode = raw === true || raw === "true";

useEffect(() => {
const root = document.documentElement;
root.classList.toggle("dark", darkMode);
return () => {
root.classList.remove("dark");
};
}, [darkMode]);

return <Story />;
};

const preview: Preview = {
decorators: [withDarkMode],
parameters: {
controls: {
matchers: {
Expand All @@ -23,6 +41,12 @@ const preview: Preview = {
},
],
},
viewport: {
options: {
...MINIMAL_VIEWPORTS,
...INITIAL_VIEWPORTS,
},
},
},
globalTypes: {
darkMode: {
Expand Down
9 changes: 8 additions & 1 deletion apps/studio/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,12 @@
"**/dist/**",
"dist-storybook/**"
],
"words": ["streamable", "waitlist"]
"words": [
"hackernews",
"modelcontextprotocol",
"streamable",
"summarise",
"triaging",
"waitlist"
]
}
35 changes: 35 additions & 0 deletions apps/studio/src/kitchen-sink/components-all.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from "@storybook/react";
import { ContentGallery } from "./lib/gallery/content-gallery";
import { FormsGallery } from "./lib/gallery/forms-gallery";
import { OverlaysGallery } from "./lib/gallery/overlays-gallery";
import { PrimitivesGallery } from "./lib/gallery/primitives-gallery";

/**
* Everything at once: all four galleries stacked on a single scrollable page,
* so the totality of the design system can be examined without switching
* stories.
*/
function AllComponents() {
return (
<div className="flex flex-col gap-y-20 p-8">
<PrimitivesGallery />
<FormsGallery />
<OverlaysGallery />
<ContentGallery />
</div>
);
}

const meta = {
title: "kitchen-sink/components/all-components",
component: AllComponents,
parameters: {
layout: "fullscreen",
chromatic: { disableSnapshot: true },
},
} satisfies Meta<typeof AllComponents>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
17 changes: 17 additions & 0 deletions apps/studio/src/kitchen-sink/components-content.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";
import { ContentGallery } from "./lib/gallery/content-gallery";

/**
* Layout and content components — containers, sections, lists, tabs, menus,
* breadcrumbs, markdown, JSON schema and the domain cards built on them.
*/
const meta = {
title: "kitchen-sink/components/content",
component: ContentGallery,
parameters: { layout: "padded" },
} satisfies Meta<typeof ContentGallery>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
17 changes: 17 additions & 0 deletions apps/studio/src/kitchen-sink/components-forms.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";
import { FormsGallery } from "./lib/gallery/forms-gallery";

/**
* Form building blocks and the higher-level forms composed from them, with
* validation and submitting states.
*/
const meta = {
title: "kitchen-sink/components/forms",
component: FormsGallery,
parameters: { layout: "padded" },
} satisfies Meta<typeof FormsGallery>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
17 changes: 17 additions & 0 deletions apps/studio/src/kitchen-sink/components-overlays.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from "@storybook/react";
import { OverlaysGallery } from "./lib/gallery/overlays-gallery";

/**
* Overlay components — dialogs, alert dialogs, sheets, popovers, dropdown
* menus and toasts — each with a trigger and, where useful, an open variant.
*/
const meta = {
title: "kitchen-sink/components/overlays",
component: OverlaysGallery,
parameters: { layout: "padded" },
} satisfies Meta<typeof OverlaysGallery>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
21 changes: 21 additions & 0 deletions apps/studio/src/kitchen-sink/components-primitives.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Meta, StoryObj } from "@storybook/react";
import { PrimitivesGallery } from "./lib/gallery/primitives-gallery";

/**
* Every low-level UI primitive (buttons, badges, inputs, typography, loaders,
* icons) with its variants, sizes and states on one page.
*/
const meta = {
title: "kitchen-sink/components/primitives",
component: PrimitivesGallery,
parameters: {
layout: "padded",
// ScrambleText and Loader animate via setInterval — skip visual snapshots.
chromatic: { disableSnapshot: true },
},
} satisfies Meta<typeof PrimitivesGallery>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
60 changes: 60 additions & 0 deletions apps/studio/src/kitchen-sink/kitchen-sink-app.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { Meta, StoryObj } from "@storybook/react";
import { emptyKitchenSinkPlaybook } from "./lib/fixtures";
import { KitchenSinkApp } from "./lib/kitchen-sink-app";

/**
* The flagship kitchen-sink story: a fully interactive mock of the Director
* Studio app. The sidebar, menus, sheets, dialogs and toasts are all live and
* driven by in-memory state — click around to move between playbooks, the
* registry library, settings and onboarding.
*/
const meta = {
title: "kitchen-sink/app",
component: KitchenSinkApp,
parameters: {
layout: "fullscreen",
},
} satisfies Meta<typeof KitchenSinkApp>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Desktop: Story = {};

export const Mobile: Story = {
globals: { viewport: { value: "mobile2", isRotated: false } },
};

export const MobileSmall: Story = {
globals: { viewport: { value: "mobile1", isRotated: false } },
};

export const Tablet: Story = {
globals: { viewport: { value: "tablet", isRotated: false } },
};

export const SidebarLoading: Story = {
args: { sidebarLoading: true },
parameters: { chromatic: { disableSnapshot: true } },
};

export const LoadingStates: Story = {
args: { pageState: "loading", sidebarLoading: true },
parameters: { chromatic: { disableSnapshot: true } },
};

export const EmptyStates: Story = {
args: { initialPlaybooks: [emptyKitchenSinkPlaybook()] },
};

export const ErrorState: Story = {
args: { pageState: "error" },
};

export const Onboarding: Story = {
args: { initialRoute: { name: "get-started" } },
};

export const DarkMode: Story = {
globals: { darkMode: true },
};
Loading
Loading