style: Update CSS classes in Tabs and Callout components
This commit is contained in:
parent
b8608c493c
commit
d0dca7d956
@ -53,8 +53,8 @@ export function Tabs({
|
||||
}}
|
||||
>
|
||||
<div className="relative">
|
||||
<div className="max-w-full overflow-auto">
|
||||
<ul className="-mb-4 !p-0 w-max flex items-stretch gap-2" aria-orientation="horizontal" role="tablist">
|
||||
<div className="max-w-full overflow-x-auto overflow-y-hidden">
|
||||
<ul className="!p-0 w-max flex items-stretch gap-2" aria-orientation="horizontal" role="tablist">
|
||||
{tabs.map((tab) => (
|
||||
<li key={tab.value} className="overflow-hidden" role="tab" aria-selected={selectedTab === tab.value}>
|
||||
<TabItem tab={tab} isSelected={selectedTab === tab.value} select={() => selectTab(tab.value)} />
|
||||
@ -62,7 +62,7 @@ export function Tabs({
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className={clsx("p-2")}>{children}</div>
|
||||
<div className="-mt-6 p-2">{children}</div>
|
||||
</div>
|
||||
</TabsContext.Provider>
|
||||
);
|
||||
|
||||
@ -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",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -38,8 +38,7 @@ export function Logo(props: React.ComponentPropsWithoutRef<"svg">) {
|
||||
<svg viewBox="0 0 231 38" {...props}>
|
||||
<LogomarkPaths />
|
||||
<text
|
||||
className="hidden lg:block"
|
||||
fill="#1A202C"
|
||||
className="hidden lg:block fill-zinc-900 dark:fill-zinc-100"
|
||||
fontFamily="Inter Variable, sans-serif"
|
||||
fontSize={24}
|
||||
fontWeight="bold"
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import { useEffect, useState } from "react";
|
||||
// import { useTheme } from 'next-themes'
|
||||
import { Label, Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTheme } from "@/hooks/useTheme";
|
||||
import clsx from "clsx";
|
||||
|
||||
const themes = [
|
||||
{ name: "Light", value: "light", icon: LightIcon },
|
||||
{ name: "Dark", value: "dark", icon: DarkIcon },
|
||||
{ name: "System", value: "system", icon: SystemIcon },
|
||||
{ name: "Clair", value: "light", icon: LightIcon },
|
||||
{ name: "Sombre", value: "dark", icon: DarkIcon },
|
||||
];
|
||||
|
||||
function LightIcon(props: React.ComponentPropsWithoutRef<"svg">) {
|
||||
@ -33,27 +32,9 @@ function DarkIcon(props: React.ComponentPropsWithoutRef<"svg">) {
|
||||
);
|
||||
}
|
||||
|
||||
function SystemIcon(props: React.ComponentPropsWithoutRef<"svg">) {
|
||||
return (
|
||||
<svg aria-hidden="true" viewBox="0 0 16 16" {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M1 4a3 3 0 0 1 3-3h8a3 3 0 0 1 3 3v4a3 3 0 0 1-3 3h-1.5l.31 1.242c.084.333.36.573.63.808.091.08.182.158.264.24A1 1 0 0 1 11 15H5a1 1 0 0 1-.704-1.71c.082-.082.173-.16.264-.24.27-.235.546-.475.63-.808L5.5 11H4a3 3 0 0 1-3-3V4Zm3-1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ThemeSelector(props: React.ComponentPropsWithoutRef<typeof Listbox<"div">>) {
|
||||
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<typeof Listb
|
||||
className="flex h-6 w-6 items-center justify-center rounded-lg ring-1 shadow-md shadow-black/5 ring-black/5 dark:bg-slate-700 dark:ring-white/5 dark:ring-inset"
|
||||
aria-label="Theme"
|
||||
>
|
||||
<LightIcon className={clsx("h-4 w-4 dark:hidden", theme === "system" ? "fill-slate-400" : "fill-violet-400")} />
|
||||
<DarkIcon
|
||||
className={clsx("hidden h-4 w-4 dark:block", theme === "system" ? "fill-slate-400" : "fill-violet-400")}
|
||||
/>
|
||||
<LightIcon className={clsx("h-4 w-4 dark:hidden", "fill-violet-400")} />
|
||||
<DarkIcon className={clsx("hidden h-4 w-4 dark:block", "fill-violet-400")} />
|
||||
</ListboxButton>
|
||||
<ListboxOptions className="absolute top-full left-1/2 mt-3 w-36 -translate-x-1/2 space-y-1 rounded-xl bg-white p-3 text-sm font-medium ring-1 shadow-md shadow-black/5 ring-black/5 dark:bg-slate-800 dark:ring-white/5">
|
||||
{themes.map((theme) => (
|
||||
|
||||
13
app/contexts/ThemeContext.ts
Normal file
13
app/contexts/ThemeContext.ts
Normal file
@ -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<ThemeContextType>({
|
||||
theme: "light",
|
||||
setTheme: () => {},
|
||||
});
|
||||
11
app/hooks/useTheme.ts
Normal file
11
app/hooks/useTheme.ts
Normal file
@ -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;
|
||||
}
|
||||
@ -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 (
|
||||
<div className="flex w-full flex-col">
|
||||
<Header />
|
||||
<ThemeProvider>
|
||||
<div className="flex w-full flex-col">
|
||||
<Header />
|
||||
|
||||
{isHomePage && <Hero />}
|
||||
{isHomePage && <Hero />}
|
||||
|
||||
<div className="relative mx-auto w-full flex max-w-8xl flex-auto justify-center sm:px-2 lg:px-8 xl:px-12">
|
||||
<div className="hidden lg:relative lg:block lg:flex-none">
|
||||
<div className="absolute inset-y-0 right-0 w-[50vw] bg-slate-50 dark:hidden" />
|
||||
<div className="absolute top-16 right-0 bottom-0 hidden h-12 w-px bg-linear-to-t from-slate-800 dark:block" />
|
||||
<div className="absolute top-28 right-0 bottom-0 hidden w-px bg-slate-800 dark:block" />
|
||||
<div className="sticky top-[4.75rem] -ml-0.5 h-[calc(100vh-4.75rem)] w-64 overflow-x-hidden overflow-y-auto py-16 pr-8 pl-0.5 xl:w-72 xl:pr-16">
|
||||
<Navigation />
|
||||
<div className="relative mx-auto w-full flex max-w-8xl flex-auto justify-center sm:px-2 lg:px-8 xl:px-12">
|
||||
<div className="hidden lg:relative lg:block lg:flex-none">
|
||||
<div className="absolute inset-y-0 right-0 w-[50vw] bg-slate-50 dark:hidden" />
|
||||
<div className="absolute top-16 right-0 bottom-0 hidden h-12 w-px bg-linear-to-t from-slate-800 dark:block" />
|
||||
<div className="absolute top-28 right-0 bottom-0 hidden w-px bg-slate-800 dark:block" />
|
||||
<div className="sticky top-[4.75rem] -ml-0.5 h-[calc(100vh-4.75rem)] w-64 overflow-x-hidden overflow-y-auto py-16 pr-8 pl-0.5 xl:w-72 xl:pr-16">
|
||||
<Navigation />
|
||||
</div>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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: {
|
||||
|
||||
22
app/providers/ThemeProvider.tsx
Normal file
22
app/providers/ThemeProvider.tsx
Normal file
@ -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<Theme>(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 <ThemeContext.Provider value={{ theme, setTheme }}>{props.children}</ThemeContext.Provider>;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user