diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 2fdbc37c82..b634c83d57 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,7 +1,7 @@
import type { Preview } from "@storybook/react";
import "../src/styles/globals.css";
-import { dystopian, inter } from "@/lib/fonts";
+import { dystopian } from "@/lib/fonts";
import { withThemeByClassName } from "@storybook/addon-themes";
import { useEffect } from "react";
@@ -20,14 +20,12 @@ const preview: Preview = {
light: "",
dark: "dark",
},
- defaultTheme: "light",
+ defaultTheme: "dark",
}),
(storyFn) => {
useEffect(() => {
if (typeof document === "undefined") return;
- document
- ?.querySelector("body")
- ?.classList.add(inter.variable, dystopian.variable);
+ document?.querySelector("body")?.classList.add(dystopian.variable);
}, []);
return storyFn();
diff --git a/package.json b/package.json
index 526ccbd825..aca2d8e80c 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"start": "next start",
"type-check": "tsc --pretty --noEmit --incremental false",
"write-check": "npx @biomejs/biome check --write --unsafe .",
- "storybook": "storybook dev -p 6006",
+ "storybook": "storybook dev -p 6006 --no-open",
"build-storybook": "storybook build"
},
"dependencies": {
@@ -48,6 +48,7 @@
"remark-gfm": "^4.0.0",
"remark-textr": "^6.1.0",
"server-only": "^0.0.1",
+ "sonner": "^1.7.0",
"tailwind-merge": "^2.5.4",
"tailwindcss-animate": "^1.0.7",
"typographic-base": "^1.0.4",
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 646f617485..848830a1f0 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,9 +1,11 @@
import type { Metadata } from "next";
import "@/styles/globals.css";
import { Header } from "@/components/Header";
+import { PreloadResources } from "@/components/PreloadResources";
import { Providers } from "@/components/Providers";
import { SignInDialog } from "@/components/SignInDialog";
-import { dystopian, inter } from "@/lib/fonts";
+import { Toaster } from "@/components/ui/Toaster";
+import { dystopian } from "@/lib/fonts";
import { cn } from "lib/cssUtils";
export const metadata: Metadata = {
@@ -23,13 +25,15 @@ const RootLayout = ({
}>) => {
return (
-
+
+
{children}
{/* TODO: maybe load this dynamically? */}
+
diff --git a/src/components/PreloadResources.tsx b/src/components/PreloadResources.tsx
new file mode 100644
index 0000000000..91277bb55d
--- /dev/null
+++ b/src/components/PreloadResources.tsx
@@ -0,0 +1,24 @@
+"use client";
+
+import ReactDOM from "react-dom";
+
+export const PreloadResources = () => {
+ ReactDOM.preload(
+ "https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-opsz-normal.woff2",
+ {
+ as: "font",
+ crossOrigin: "",
+ type: "font/woff2",
+ fetchPriority: "high",
+ },
+ );
+ ReactDOM.preload(
+ "https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-opsz-italic.woff2",
+ {
+ as: "font",
+ crossOrigin: "",
+ type: "font/woff2",
+ },
+ );
+ return null;
+};
diff --git a/src/components/ui/Toaster.tsx b/src/components/ui/Toaster.tsx
new file mode 100644
index 0000000000..79341a0d64
--- /dev/null
+++ b/src/components/ui/Toaster.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { useTheme } from "next-themes";
+import { Toaster as Sonner } from "sonner";
+
+type ToasterProps = React.ComponentProps;
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = "system" } = useTheme();
+
+ return (
+
+ );
+};
+
+export { Toaster };
diff --git a/src/lib/fonts.ts b/src/lib/fonts.ts
index 71fb118f90..4a83f81dd9 100644
--- a/src/lib/fonts.ts
+++ b/src/lib/fonts.ts
@@ -1,13 +1,5 @@
-import { Inter } from "next/font/google";
import localFont from "next/font/local";
-const inter = Inter({
- subsets: ["latin"],
- variable: "--font-inter",
- fallback: ["sans-serif"],
- weight: "variable",
-});
-
const dystopian = localFont({
src: [
{
@@ -33,4 +25,4 @@ const dystopian = localFont({
variable: "--font-dystopian",
});
-export { dystopian, inter };
+export { dystopian };
diff --git a/src/stories/Toast.stories.tsx b/src/stories/Toast.stories.tsx
new file mode 100644
index 0000000000..b8b567602d
--- /dev/null
+++ b/src/stories/Toast.stories.tsx
@@ -0,0 +1,56 @@
+import { Button } from "@/components/ui/Button";
+import { Toaster } from "@/components/ui/Toaster";
+import type { Meta, StoryObj } from "@storybook/react";
+import { toast } from "sonner";
+
+type ToastExampleProps = {
+ title: string;
+ description?: string;
+ action?: boolean;
+ closeButton?: boolean;
+};
+const ToastExample = ({
+ title = "Toast example",
+ description,
+ action,
+ closeButton,
+}: ToastExampleProps) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+const meta: Meta = {
+ title: "Design system/Toast",
+ component: ToastExample,
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ title: "Toast example",
+ description: "",
+ action: false,
+ closeButton: false,
+ },
+};
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 37f0070839..d16ad80f79 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -1,3 +1,23 @@
+/* inter-latin-wght-normal */
+@font-face {
+ font-family: 'Inter Variable';
+ font-style: normal;
+ font-display: swap;
+ font-weight: 100 900;
+ src: url(https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-opsz-normal.woff2) format('woff2-variations');
+ unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
+}
+
+/* inter-latin-wght-normal */
+@font-face {
+ font-family: 'Inter Variable';
+ font-style: italic;
+ font-display: swap;
+ font-weight: 100 900;
+ src: url(https://cdn.jsdelivr.net/fontsource/fonts/inter:vf@latest/latin-opsz-italic.woff2) format('woff2-variations');
+ unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
+}
+
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -7,6 +27,8 @@ html {
}
:root {
+ --font-inter: 'Inter Variable';
+
/* Raw colors */
--indigo-50: #eef2ff;
--indigo-100: #e0e7ff;
@@ -83,7 +105,7 @@ html {
--image: var(--gray-700);
--skeleton: var(--gray-300);
--border: var(--gray-300);
-
+
--input-border: var(--gray-200);
--input-border-accent: var(--gray-300);
--input-border-invalid: var(--red-500);