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 ( + <> + + ) : undefined, + closeButton, + }) + } + > + Show toast! + + + + ); +}; + +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);