chore: new theme `whitewall`

pull/4825/head
Johnny 1 week ago
parent 1b3083b216
commit e55ed8a9c7

@ -9,6 +9,7 @@ interface ThemeSelectorProps {
const THEMES = [
{ value: "default", label: "Default" },
{ value: "paper", label: "Paper" },
{ value: "whitewall", label: "Whitewall" },
] as const;
export const ThemeSelector = ({ value = "default", onValueChange, className }: ThemeSelectorProps) => {

@ -4,14 +4,13 @@ import * as React from "react";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none transition-[color,box-shadow] overflow-hidden",
{
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
destructive:
"border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
destructive: "border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 dark:bg-destructive/60",
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},
},

@ -4,13 +4,12 @@ import * as React from "react";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
destructive: "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-border dark:hover:bg-input/50",
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",

@ -8,7 +8,7 @@ function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxP
<CheckboxPrimitive.Root
data-slot="checkbox"
className={cn(
"peer border-border dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
"peer border-border dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}

@ -7,9 +7,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
type={type}
data-slot="input"
className={cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-border flex h-8 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-border flex h-8 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
{...props}

@ -12,7 +12,7 @@ function RadioGroupItem({ className, ...props }: React.ComponentProps<typeof Rad
<RadioGroupPrimitive.Item
data-slot="radio-group-item"
className={cn(
"border-border text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
"border-border text-primary dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}

@ -28,7 +28,7 @@ function SelectTrigger({
data-slot="select-trigger"
data-size={size}
className={cn(
"border-border data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-2 py-1 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"border-border data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-2 py-1 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-8 data-[size=sm]:h-7 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}

@ -7,7 +7,7 @@ function Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimi
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}

@ -6,7 +6,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
<textarea
data-slot="textarea"
className={cn(
"border-border placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"border-border placeholder:text-muted-foreground dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
{...props}

@ -0,0 +1,152 @@
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.15 0.01 270);
--card: oklch(1 0 0);
--card-foreground: oklch(0.15 0.01 270);
--popover: oklch(0.98 0.001 270);
--popover-foreground: oklch(0.15 0.01 270);
--primary: oklch(0.4 0.08 250);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.96 0.002 270);
--secondary-foreground: oklch(0.25 0.01 270);
--muted: oklch(0.96 0.002 270);
--muted-foreground: oklch(0.45 0.01 270);
--accent: oklch(0.94 0.003 270);
--accent-foreground: oklch(0.15 0.01 270);
--destructive: oklch(0.5 0.12 25);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.9 0.005 270);
--input: oklch(0.94 0.003 270);
--ring: oklch(0.4 0.08 250);
--chart-1: oklch(0.6 0.15 30);
--chart-2: oklch(0.6 0.15 260);
--chart-3: oklch(0.7 0.1 120);
--chart-4: oklch(0.65 0.12 300);
--chart-5: oklch(0.55 0.18 60);
--sidebar: oklch(0.98 0.001 270);
--sidebar-foreground: oklch(0.2 0.01 270);
--sidebar-primary: oklch(0.4 0.08 250);
--sidebar-primary-foreground: oklch(1 0 0);
--sidebar-accent: oklch(0.94 0.003 270);
--sidebar-accent-foreground: oklch(0.15 0.01 270);
--sidebar-border: oklch(0.9 0.005 270);
--sidebar-ring: oklch(0.4 0.08 250);
--font-sans:
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--radius: 0.5rem;
--shadow-2xs: 0 1px 3px 0px hsl(240 10% 0% / 0.02);
--shadow-xs: 0 1px 3px 0px hsl(240 10% 0% / 0.03);
--shadow-sm: 0 1px 3px 0px hsl(240 10% 0% / 0.05), 0 1px 2px -1px hsl(240 10% 0% / 0.05);
--shadow: 0 1px 3px 0px hsl(240 10% 0% / 0.06), 0 1px 2px -1px hsl(240 10% 0% / 0.06);
--shadow-md: 0 1px 3px 0px hsl(240 10% 0% / 0.07), 0 2px 4px -1px hsl(240 10% 0% / 0.07);
--shadow-lg: 0 1px 3px 0px hsl(240 10% 0% / 0.08), 0 4px 6px -1px hsl(240 10% 0% / 0.08);
--shadow-xl: 0 1px 3px 0px hsl(240 10% 0% / 0.09), 0 8px 10px -1px hsl(240 10% 0% / 0.09);
--shadow-2xl: 0 1px 3px 0px hsl(240 10% 0% / 0.15);
--tracking-normal: 0em;
--spacing: 0.25rem;
}
.dark {
--background: oklch(0.08 0.005 270);
--foreground: oklch(0.9 0.01 270);
--card: oklch(0.08 0.005 270);
--card-foreground: oklch(0.9 0.01 270);
--popover: oklch(0.12 0.008 270);
--popover-foreground: oklch(0.85 0.01 270);
--primary: oklch(0.65 0.12 250);
--primary-foreground: oklch(0.08 0.005 270);
--secondary: oklch(0.15 0.01 270);
--secondary-foreground: oklch(0.85 0.01 270);
--muted: oklch(0.12 0.008 270);
--muted-foreground: oklch(0.6 0.01 270);
--accent: oklch(0.18 0.015 270);
--accent-foreground: oklch(0.9 0.01 270);
--destructive: oklch(0.6 0.15 25);
--destructive-foreground: oklch(1 0 0);
--border: oklch(0.2 0.015 270);
--input: oklch(0.25 0.02 270);
--ring: oklch(0.65 0.12 250);
--chart-1: oklch(0.7 0.15 30);
--chart-2: oklch(0.7 0.15 260);
--chart-3: oklch(0.6 0.12 120);
--chart-4: oklch(0.65 0.15 300);
--chart-5: oklch(0.75 0.18 60);
--sidebar: oklch(0.06 0.003 270);
--sidebar-foreground: oklch(0.9 0.01 270);
--sidebar-primary: oklch(0.65 0.12 250);
--sidebar-primary-foreground: oklch(0.08 0.005 270);
--sidebar-accent: oklch(0.18 0.015 270);
--sidebar-accent-foreground: oklch(0.9 0.01 270);
--sidebar-border: oklch(0.2 0.015 270);
--sidebar-ring: oklch(0.65 0.12 250);
--font-sans:
ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--radius: 0.5rem;
--shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);
--shadow-sm: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);
--shadow-md: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);
--shadow-lg: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);
--shadow-xl: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--font-sans: var(--font-sans);
--font-mono: var(--font-mono);
--font-serif: var(--font-serif);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--shadow-2xs: var(--shadow-2xs);
--shadow-xs: var(--shadow-xs);
--shadow-sm: var(--shadow-sm);
--shadow: var(--shadow);
--shadow-md: var(--shadow-md);
--shadow-lg: var(--shadow-lg);
--shadow-xl: var(--shadow-xl);
--shadow-2xl: var(--shadow-2xl);
}

@ -1,11 +1,13 @@
import paperThemeContent from "../themes/paper.css?raw";
import whitewallThemeContent from "../themes/whitewall.css?raw";
const VALID_THEMES = ["default", "paper"] as const;
const VALID_THEMES = ["default", "paper", "whitewall"] as const;
type ValidTheme = (typeof VALID_THEMES)[number];
const THEME_CONTENT: Record<ValidTheme, string | null> = {
default: null,
paper: paperThemeContent,
whitewall: whitewallThemeContent,
};
const validateTheme = (theme: string): ValidTheme => {

Loading…
Cancel
Save