From d0dca7d9568cf9352d64d18e06d201febbfc8a2f Mon Sep 17 00:00:00 2001 From: GauthierWebDev Date: Fri, 11 Apr 2025 12:19:56 +0200 Subject: [PATCH] style: Update CSS classes in Tabs and Callout components --- app/components/md/Tabs.tsx | 6 ++--- app/components/syntax/Callout.tsx | 8 +++--- app/components/syntax/Logo.tsx | 3 +-- app/components/syntax/ThemeSelector.tsx | 35 +++++-------------------- app/contexts/ThemeContext.ts | 13 +++++++++ app/hooks/useTheme.ts | 11 ++++++++ app/layouts/LayoutDefault.tsx | 29 +++++++++++--------- app/markdoc/nodes.ts | 10 +++++++ app/providers/ThemeProvider.tsx | 22 ++++++++++++++++ 9 files changed, 87 insertions(+), 50 deletions(-) create mode 100644 app/contexts/ThemeContext.ts create mode 100644 app/hooks/useTheme.ts create mode 100644 app/providers/ThemeProvider.tsx diff --git a/app/components/md/Tabs.tsx b/app/components/md/Tabs.tsx index da75fa4..5f55811 100644 --- a/app/components/md/Tabs.tsx +++ b/app/components/md/Tabs.tsx @@ -53,8 +53,8 @@ export function Tabs({ }} >
-
-
    +
    +
      {tabs.map((tab) => (
    • selectTab(tab.value)} /> @@ -62,7 +62,7 @@ export function Tabs({ ))}
    -
    {children}
    +
    {children}
); diff --git a/app/components/syntax/Callout.tsx b/app/components/syntax/Callout.tsx index 5a95f47..566b0b7 100644 --- a/app/components/syntax/Callout.tsx +++ b/app/components/syntax/Callout.tsx @@ -3,14 +3,14 @@ import clsx from "clsx"; const styles = { note: { - container: "bg-violet-50 dark:bg-slate-800/60 dark:ring-1 dark:ring-slate-300/10", + container: "bg-violet-50 dark:bg-violet-800/60 dark:ring-1 dark:ring-violet-300/10", title: "text-violet-900 dark:text-violet-400", - body: "text-violet-800 [--tw-prose-background:var(--color-violet-50)] prose-a:text-violet-900 prose-code:text-violet-900 dark:text-slate-300 dark:prose-code:text-slate-300", + body: "text-slate-800 [--tw-prose-background:var(--color-slate-50)] prose-a:text-slate-900 prose-code:text-slate-900 dark:text-slate-300 dark:prose-code:text-slate-300", }, warning: { - container: "bg-amber-50 dark:bg-slate-800/60 dark:ring-1 dark:ring-slate-300/10", + container: "bg-amber-50 dark:bg-amber-800/60 dark:ring-1 dark:ring-amber-300/10", title: "text-amber-900 dark:text-amber-500", - body: "text-amber-800 [--tw-prose-underline:var(--color-amber-400)] [--tw-prose-background:var(--color-amber-50)] prose-a:text-amber-900 prose-code:text-amber-900 dark:text-slate-300 dark:[--tw-prose-underline:var(--color-violet-700)] dark:prose-code:text-slate-300", + body: "text-slate-800 [--tw-prose-underline:var(--color-slate-400)] [--tw-prose-background:var(--color-slate-50)] prose-a:text-slate-900 prose-code:text-slate-900 dark:text-slate-300 dark:[--tw-prose-underline:var(--color-slate-700)] dark:prose-code:text-slate-300", }, }; diff --git a/app/components/syntax/Logo.tsx b/app/components/syntax/Logo.tsx index 32f7ae3..e6e1530 100644 --- a/app/components/syntax/Logo.tsx +++ b/app/components/syntax/Logo.tsx @@ -38,8 +38,7 @@ export function Logo(props: React.ComponentPropsWithoutRef<"svg">) { ) { @@ -33,27 +32,9 @@ function DarkIcon(props: React.ComponentPropsWithoutRef<"svg">) { ); } -function SystemIcon(props: React.ComponentPropsWithoutRef<"svg">) { - return ( - - ); -} - export function ThemeSelector(props: React.ComponentPropsWithoutRef>) { - const useTheme = () => { - return { - theme: "light", - setTheme: (theme: string) => {}, - }; - }; - let { theme, setTheme } = useTheme(); let [mounted, setMounted] = useState(false); + let { theme, setTheme } = useTheme(); useEffect(() => { setMounted(true); @@ -70,10 +51,8 @@ export function ThemeSelector(props: React.ComponentPropsWithoutRef - - + + {themes.map((theme) => ( diff --git a/app/contexts/ThemeContext.ts b/app/contexts/ThemeContext.ts new file mode 100644 index 0000000..323602f --- /dev/null +++ b/app/contexts/ThemeContext.ts @@ -0,0 +1,13 @@ +import { createContext } from "react"; + +export type Theme = "light" | "dark"; + +export type ThemeContextType = { + theme: Theme; + setTheme: (theme: Theme) => void; +}; + +export const ThemeContext = createContext({ + theme: "light", + setTheme: () => {}, +}); diff --git a/app/hooks/useTheme.ts b/app/hooks/useTheme.ts new file mode 100644 index 0000000..0b8c76d --- /dev/null +++ b/app/hooks/useTheme.ts @@ -0,0 +1,11 @@ +import { ThemeContext } from "@/contexts/ThemeContext"; +import { useContext } from "react"; + +export function useTheme() { + const context = useContext(ThemeContext); + if (!context) { + throw new Error("useTheme must be used within a ThemeProvider"); + } + + return context; +} diff --git a/app/layouts/LayoutDefault.tsx b/app/layouts/LayoutDefault.tsx index 8ce8487..4650679 100644 --- a/app/layouts/LayoutDefault.tsx +++ b/app/layouts/LayoutDefault.tsx @@ -1,8 +1,9 @@ import { MobileNavigation } from "@syntax/MobileNavigation"; import { usePageContext } from "vike-react/usePageContext"; +import { ThemeProvider } from "@/providers/ThemeProvider"; import { ThemeSelector } from "@syntax/ThemeSelector"; -import { Link } from "@/components/common/Link"; import { Navigation } from "@syntax/Navigation"; +import { Link } from "@/components/common/Link"; import { useEffect, useState } from "react"; import { Search } from "@syntax/Search"; import { Hero } from "@syntax/Hero"; @@ -74,22 +75,24 @@ export default function DefaultLayout({ children }: { children: React.ReactNode const isHomePage = urlPathname === "/"; return ( -
-
+ +
+
- {isHomePage && } + {isHomePage && } -
-
-
-
-
-
- +
+
+
+
+
+
+ +
+ {children}
- {children}
-
+ ); } diff --git a/app/markdoc/nodes.ts b/app/markdoc/nodes.ts index 72ba7a9..4eb69fb 100644 --- a/app/markdoc/nodes.ts +++ b/app/markdoc/nodes.ts @@ -36,6 +36,16 @@ const nodes = { return new Tag(`h${node.attributes.level}`, { ...attributes, id }, children); }, }, + strong: { + ...defaultNodes.strong, + attributes: { + ...defaultNodes.strong.attributes, + class: { + type: String, + default: "font-semibold text-slate-800 dark:text-slate-200", + }, + }, + }, th: { ...defaultNodes.th, attributes: { diff --git a/app/providers/ThemeProvider.tsx b/app/providers/ThemeProvider.tsx new file mode 100644 index 0000000..ccb59c7 --- /dev/null +++ b/app/providers/ThemeProvider.tsx @@ -0,0 +1,22 @@ +import { ThemeContext, type Theme } from "@/contexts/ThemeContext"; +import { useEffect, useState } from "react"; + +type ThemeProviderProps = { + children: React.ReactNode; + defaultTheme?: Theme; +}; + +export function ThemeProvider(props: ThemeProviderProps) { + const [theme, setTheme] = useState(props.defaultTheme || "light"); + + useEffect(() => { + const rootElement = document.documentElement; + + rootElement.classList.toggle("dark", theme === "dark"); + rootElement.classList.toggle("light", theme === "light"); + + console.log("changed theme to", theme); + }, [theme]); + + return {props.children}; +}