(feat): big updates, added og tensamin theme
All checks were successful
/ package (push) Successful in 1m4s
All checks were successful
/ package (push) Successful in 1m4s
This commit is contained in:
parent
29098d1f61
commit
0d2dc1676c
19 changed files with 329 additions and 153 deletions
|
|
@ -15,7 +15,7 @@ const badgeVariants = cva(
|
|||
destructive:
|
||||
"bg-destructive/10 text-destructive dark:bg-destructive/20 [a]:hover:bg-destructive/20",
|
||||
outline:
|
||||
"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
||||
"border-input bg-transparent text-foreground dark:bg-input/30 [a]:hover:border-ring/60 [a]:hover:bg-input/50 [a]:hover:text-foreground [a]:focus-visible:border-ring [a]:focus-visible:bg-input/50",
|
||||
ghost:
|
||||
"hover:bg-muted focus-visible:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50 dark:focus-visible:bg-muted/50",
|
||||
link: "text-primary underline-offset-4 hover:underline focus-visible:underline",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const buttonVariants = cva(
|
|||
subtleDefault:
|
||||
"bg-primary-foreground-alt/10 text-primary-foreground-alt hover:bg-primary-foreground-alt/20 focus-visible:bg-primary-foreground-alt/20 dark:bg-primary-foreground-alt/20 dark:hover:bg-primary-foreground-alt/30 dark:focus-visible:bg-primary-foreground-alt/30",
|
||||
outline:
|
||||
"border-border bg-background hover:bg-muted focus-visible:bg-muted hover:text-foreground focus-visible:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50",
|
||||
"border-input bg-transparent text-foreground hover:border-ring/60 hover:bg-input/50 focus-visible:border-ring focus-visible:bg-input/50 aria-expanded:border-ring/60 aria-expanded:bg-input/50 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
||||
ghost:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|||
data-slot="input-group"
|
||||
role="group"
|
||||
className={cn(
|
||||
"group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
|
||||
"group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none hover:border-ring/60 hover:bg-input/20 focus-within:border-ring focus-within:bg-input/20 in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:hover:bg-input/50 dark:focus-within:bg-input/50 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|||
type={type}
|
||||
data-slot="input"
|
||||
className={cn(
|
||||
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none hover:border-ring/60 hover:bg-input/20 focus-visible:border-ring focus-visible:bg-input/20 file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -35,13 +35,15 @@ function ItemSeparator({
|
|||
}
|
||||
|
||||
const itemVariants = cva(
|
||||
"group/item flex w-full flex-wrap items-center rounded-lg border text-sm transition-colors duration-100 outline-none [a]:transition-colors [a]:hover:bg-muted focus-visible:bg-muted",
|
||||
"group/item flex w-full flex-wrap items-center rounded-lg border text-sm transition-colors duration-100 outline-none [a]:transition-colors",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "border-transparent",
|
||||
outline: "border-border",
|
||||
muted: "border-transparent bg-muted/50",
|
||||
default: "border-transparent [a]:hover:bg-muted focus-visible:bg-muted",
|
||||
outline:
|
||||
"border-input bg-transparent hover:border-ring/60 hover:bg-input/50 focus-visible:border-ring focus-visible:bg-input/50 dark:bg-input/30",
|
||||
muted:
|
||||
"border-transparent bg-muted/50 [a]:hover:bg-muted focus-visible:bg-muted",
|
||||
},
|
||||
size: {
|
||||
default: "gap-2.5 px-3 py-2.5",
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ function NativeSelect({
|
|||
<select
|
||||
data-slot="native-select"
|
||||
data-size={size}
|
||||
className="h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
|
||||
className="h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none hover:border-ring/60 hover:bg-input/20 focus-visible:border-ring focus-visible:bg-input/20 selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
|
||||
{...props}
|
||||
/>
|
||||
<ChevronDownIcon
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function SelectTrigger({
|
|||
data-slot="select-trigger"
|
||||
data-size={size}
|
||||
className={cn(
|
||||
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none hover:border-ring/60 hover:bg-input/20 focus-visible:border-ring focus-visible:bg-input/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|||
<textarea
|
||||
data-slot="textarea"
|
||||
className={cn(
|
||||
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
"flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none hover:border-ring/60 hover:bg-input/20 focus-visible:border-ring focus-visible:bg-input/20 placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const toggleVariants = cva(
|
|||
variant: {
|
||||
default: "bg-transparent",
|
||||
outline:
|
||||
"border border-input bg-transparent hover:bg-muted focus-visible:bg-muted",
|
||||
"border border-input bg-transparent hover:border-ring/60 hover:bg-input/50 focus-visible:border-ring focus-visible:bg-input/50 dark:bg-input/30 dark:hover:bg-input/50 dark:focus-visible:bg-input/50",
|
||||
},
|
||||
size: {
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -218,6 +218,14 @@
|
|||
[data-slot="textarea"],
|
||||
[data-slot="native-select"],
|
||||
[data-slot="select-trigger"],
|
||||
[data-slot="select-content"],
|
||||
[data-slot="dropdown-menu-content"],
|
||||
[data-slot="dropdown-menu-sub-content"],
|
||||
[data-slot="context-menu-content"],
|
||||
[data-slot="context-menu-sub-content"],
|
||||
[data-slot="menubar-content"],
|
||||
[data-slot="menubar-sub-content"],
|
||||
[data-slot="combobox-content"],
|
||||
[data-slot="input-group"],
|
||||
[data-slot="card"],
|
||||
[data-slot="item"]
|
||||
|
|
|
|||
|
|
@ -45,42 +45,17 @@ export function ThemeSelector({
|
|||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
role="group"
|
||||
aria-label="Parent theme"
|
||||
className={cn("flex flex-wrap gap-3", className)}
|
||||
>
|
||||
<div className={cn("flex flex-wrap gap-3", className)}>
|
||||
{themes.map((theme) => (
|
||||
<div
|
||||
key={theme.id}
|
||||
className="flex w-16 flex-col items-center gap-1.5"
|
||||
>
|
||||
<div key={theme.id} className="flex flex-col items-center gap-1.5">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
aria-label={theme.title}
|
||||
aria-pressed={selected === theme.id}
|
||||
variant={selected === theme.id ? "default" : "outline"}
|
||||
onClick={() => choose(theme.id)}
|
||||
className={cn(
|
||||
"size-14 overflow-hidden rounded-md p-1.5",
|
||||
selected === theme.id &&
|
||||
"border-primary ring-2 ring-primary/20 shadow-lg",
|
||||
)}
|
||||
className="h-20! w-20 overflow-hidden rounded-md p-1.5!"
|
||||
>
|
||||
<img
|
||||
src={theme.logo}
|
||||
alt=""
|
||||
className="size-full object-contain"
|
||||
/>
|
||||
<img src={theme.logo} className="rounded-md aspect-square" />
|
||||
</Button>
|
||||
<span className="font-heading text-xs font-semibold">
|
||||
{theme.title}
|
||||
{selected === theme.id && isThemeCustomized && (
|
||||
<span className="ml-1 font-normal text-muted-foreground">
|
||||
Edited
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
<p className="text-sm font-medium">{theme.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -95,9 +70,8 @@ export function ThemeSelector({
|
|||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Replace your custom theme?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
Choosing another parent theme replaces your current visual
|
||||
settings and custom CSS. This cannot be undone after leaving this
|
||||
page.
|
||||
Choosing another base theme replaces your current visual settings
|
||||
and custom CSS. This cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
|
|
|
|||
|
|
@ -19,11 +19,5 @@ export function ThemeOnboardingPage({
|
|||
onValueChange?.(id);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeCustomizer
|
||||
value={chosenThemeId}
|
||||
onValueChange={choose}
|
||||
showHeader={false}
|
||||
/>
|
||||
);
|
||||
return <ThemeCustomizer value={chosenThemeId} onValueChange={choose} />;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import type {
|
|||
ResolvedThemePolarity,
|
||||
ThemeDesign,
|
||||
ThemeFontFamily,
|
||||
ThemePreset,
|
||||
ThemeProviderProps,
|
||||
ThemeProviderState,
|
||||
ThemeTint,
|
||||
|
|
@ -96,6 +97,14 @@ function designsEqual(left: ThemeDesign, right: ThemeDesign) {
|
|||
return JSON.stringify(left) === JSON.stringify(right);
|
||||
}
|
||||
|
||||
function presetDesign(theme: ThemePreset | null, fallback: ThemeDesign) {
|
||||
return theme?.defaultValues?.design ?? fallback;
|
||||
}
|
||||
|
||||
function presetBorderRadius(theme: ThemePreset | null, fallback: number) {
|
||||
return theme?.defaultValues?.borderRadius ?? fallback;
|
||||
}
|
||||
|
||||
export function ThemeProvider({
|
||||
children,
|
||||
defaultTheme = "system",
|
||||
|
|
@ -126,6 +135,11 @@ export function ThemeProvider({
|
|||
return findTheme(themes, stored)?.id ?? configuredParent?.id ?? null;
|
||||
});
|
||||
const initialParent = findTheme(themes, parentThemeId);
|
||||
const initialDesign = presetDesign(initialParent, defaultDesign);
|
||||
const initialBorderRadius = presetBorderRadius(
|
||||
initialParent,
|
||||
defaultBorderRadius,
|
||||
);
|
||||
const [themePolarity, setThemePolarityState] = useState(() =>
|
||||
readStoredValue(storageKey, isTheme, defaultTheme),
|
||||
);
|
||||
|
|
@ -149,7 +163,7 @@ export function ThemeProvider({
|
|||
const [themeBorderRadius, setThemeBorderRadiusState] = useState(
|
||||
() =>
|
||||
parseBorderRadius(storageValue(borderRadiusStorageKey)) ??
|
||||
defaultBorderRadius,
|
||||
initialBorderRadius,
|
||||
);
|
||||
const [themeCustomCss, setThemeCustomCssState] = useState(() => {
|
||||
const storedCss = storageValue(customCssStorageKey);
|
||||
|
|
@ -160,7 +174,7 @@ export function ThemeProvider({
|
|||
return storedCss;
|
||||
});
|
||||
const [themeDesign, setThemeDesignState] = useState(() =>
|
||||
storedDesign(designStorageKey, defaultDesign),
|
||||
storedDesign(designStorageKey, initialDesign),
|
||||
);
|
||||
const [systemPolarity, setSystemPolarity] = useState<ResolvedThemePolarity>(
|
||||
() => getSystemTheme(),
|
||||
|
|
@ -252,12 +266,13 @@ export function ThemeProvider({
|
|||
setThemePalette(null);
|
||||
setThemePrimaryColor("");
|
||||
setThemeTint("soft");
|
||||
setThemeBorderRadius(DEFAULT_BORDER_RADIUS);
|
||||
setThemeDesign(defaultDesign);
|
||||
setThemeBorderRadius(presetBorderRadius(preset, defaultBorderRadius));
|
||||
setThemeDesign(presetDesign(preset, defaultDesign));
|
||||
setThemeCustomCss(preset.css);
|
||||
},
|
||||
[
|
||||
defaultDesign,
|
||||
defaultBorderRadius,
|
||||
setParentThemeId,
|
||||
setThemeBorderRadius,
|
||||
setThemeColor,
|
||||
|
|
@ -382,7 +397,8 @@ export function ThemeProvider({
|
|||
);
|
||||
register(borderRadiusStorageKey, (stored) =>
|
||||
setThemeBorderRadiusState(
|
||||
parseBorderRadius(stored) ?? defaultBorderRadius,
|
||||
parseBorderRadius(stored) ??
|
||||
presetBorderRadius(parentTheme, defaultBorderRadius),
|
||||
),
|
||||
);
|
||||
register(customCssStorageKey, (stored) =>
|
||||
|
|
@ -392,7 +408,9 @@ export function ThemeProvider({
|
|||
setParentThemeIdState(findTheme(themes, stored)?.id ?? null),
|
||||
);
|
||||
register(designStorageKey, (stored) =>
|
||||
setThemeDesignState(parseDesign(stored, defaultDesign)),
|
||||
setThemeDesignState(
|
||||
parseDesign(stored, presetDesign(parentTheme, defaultDesign)),
|
||||
),
|
||||
);
|
||||
const handleStorageChange = (event: StorageEvent) => {
|
||||
if (event.storageArea !== localStorage) return;
|
||||
|
|
@ -414,12 +432,19 @@ export function ThemeProvider({
|
|||
designStorageKey,
|
||||
paletteStorageKey,
|
||||
parentThemeStorageKey,
|
||||
parentTheme,
|
||||
primaryColorStorageKey,
|
||||
storageKey,
|
||||
themes,
|
||||
tintStorageKey,
|
||||
]);
|
||||
|
||||
const parentDesign = presetDesign(parentTheme, defaultDesign);
|
||||
const parentBorderRadius = presetBorderRadius(
|
||||
parentTheme,
|
||||
defaultBorderRadius,
|
||||
);
|
||||
|
||||
const isThemeCustomized = Boolean(
|
||||
parentTheme &&
|
||||
(themeCustomCss !== parentTheme.css ||
|
||||
|
|
@ -427,8 +452,8 @@ export function ThemeProvider({
|
|||
themePalette !== null ||
|
||||
themePrimaryColor !== "" ||
|
||||
themeTint !== "soft" ||
|
||||
themeBorderRadius !== DEFAULT_BORDER_RADIUS ||
|
||||
!designsEqual(themeDesign, defaultDesign)),
|
||||
themeBorderRadius !== parentBorderRadius ||
|
||||
!designsEqual(themeDesign, parentDesign)),
|
||||
);
|
||||
|
||||
const value = useMemo<ThemeProviderState>(
|
||||
|
|
|
|||
BIN
src/theme/assets/tensamin-og-logo.png
Normal file
BIN
src/theme/assets/tensamin-og-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
|
|
@ -88,11 +88,9 @@ function DesignSlider({
|
|||
export function ThemeCustomizer({
|
||||
value,
|
||||
onValueChange,
|
||||
showHeader = true,
|
||||
}: {
|
||||
value?: string | null;
|
||||
onValueChange?: (id: string) => void;
|
||||
showHeader?: boolean;
|
||||
}) {
|
||||
const [advancedOpen, setAdvancedOpen] = useState(false);
|
||||
const fontId = useId();
|
||||
|
|
@ -105,7 +103,7 @@ export function ThemeCustomizer({
|
|||
} = useTheme();
|
||||
return (
|
||||
<div className="w-full min-w-0 space-y-7">
|
||||
<div className="border border-dotted p-5 rounded-2xl bg-card/30 flex flex-col gap-5">
|
||||
<div className="flex flex-col gap-5">
|
||||
<ThemeSelector value={value} onValueChange={onValueChange} />
|
||||
<div className="grid gap-7 lg:grid-cols-2">
|
||||
<Section title="Color scheme">
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ const TENSAMIN_LOGO = new URL("./assets/tensamin-logo.svg", import.meta.url)
|
|||
const METHANIUM_LOGO = new URL("./assets/methanium-logo.svg", import.meta.url)
|
||||
.href;
|
||||
const SECRET_LOGO = new URL("./assets/secret-logo.svg", import.meta.url).href;
|
||||
const OG_TENSAMIN_LOGO = new URL(
|
||||
"./assets/tensamin-og-logo.png",
|
||||
import.meta.url,
|
||||
).href;
|
||||
|
||||
export function defineThemes<const T extends readonly ThemePreset[]>(
|
||||
themes: T,
|
||||
|
|
@ -35,6 +39,10 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
id: "tensamin",
|
||||
title: "Tensamin",
|
||||
logo: TENSAMIN_LOGO,
|
||||
defaultValues: {
|
||||
borderRadius: 0.625,
|
||||
design: DEFAULT_THEME_DESIGN,
|
||||
},
|
||||
css: `:root[data-theme="tensamin"] {
|
||||
--card: oklch(0.97 0 0);
|
||||
--primary: oklch(0.54 0.105 186);
|
||||
|
|
@ -51,10 +59,10 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
}
|
||||
:root[data-theme="tensamin"] [data-slot] {
|
||||
--tensamin-edge: var(--border);
|
||||
border-left-width: 0;
|
||||
border-right-width: 0;
|
||||
border-left-color: color-mix(in oklch, var(--tensamin-edge) 89%, black);
|
||||
border-right-color: color-mix(in oklch, var(--tensamin-edge) 89%, black);
|
||||
border-top-color: color-mix(in oklch, var(--tensamin-edge) 98%, white);
|
||||
border-bottom-color: color-mix(in oklch, var(--tensamin-edge) 88%, black);
|
||||
border-bottom-color: color-mix(in oklch, var(--tensamin-edge) 83%, black);
|
||||
transition: border-color 160ms ease, background-color 160ms ease;
|
||||
}
|
||||
:root[data-theme="tensamin"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="select-trigger"], [data-slot="native-select"], [data-slot="input-group"]) {
|
||||
|
|
@ -80,8 +88,10 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
}
|
||||
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"] {
|
||||
background-color: color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt));
|
||||
border-top-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 82%, white);
|
||||
border-bottom-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 90%, white);
|
||||
border-top-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 98%, white);
|
||||
border-left-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 89%, black);
|
||||
border-right-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 89%, black);
|
||||
border-bottom-color: color-mix(in oklch, color-mix(in oklch, var(--background) 88%, var(--primary-foreground-alt)) 83%, black);
|
||||
}
|
||||
:root[data-theme="tensamin"] [data-slot="button"][data-variant="subtleDefault"]:hover {
|
||||
background-color: color-mix(in oklch, var(--background) 80%, var(--primary-foreground-alt));
|
||||
|
|
@ -105,11 +115,16 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
background-color: color-mix(in oklch, var(--background) 76%, var(--destructive));
|
||||
}
|
||||
:root[data-theme="tensamin"] [data-slot][data-variant="destructive"] {
|
||||
border-top-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 82%, white);
|
||||
border-bottom-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 90%, white);
|
||||
border-top-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 98%, white);
|
||||
border-left-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 89%, black);
|
||||
border-right-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 89%, black);
|
||||
border-bottom-color: color-mix(in oklch, color-mix(in oklch, var(--background) 86%, var(--destructive)) 83%, black);
|
||||
}
|
||||
:root[data-theme="tensamin"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"] {
|
||||
--tensamin-edge: color-mix(in oklch, var(--primary) 16%, var(--border));
|
||||
--tensamin-edge: var(--input);
|
||||
}
|
||||
:root[data-theme="tensamin"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="select-trigger"], [data-slot="native-select"], [data-slot="input-group"], [data-slot="button"][data-variant="outline"], [data-slot="badge"][data-variant="outline"], [data-slot="toggle"][data-variant="outline"]):is(:hover, :focus-visible, :focus-within) {
|
||||
--tensamin-edge: color-mix(in oklch, var(--input) 75%, var(--ring));
|
||||
}
|
||||
:root[data-theme="tensamin"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"]):where([data-variant="ghost"], [data-variant="link"]) {
|
||||
--tensamin-edge: color-mix(in oklch, currentColor 12%, var(--border));
|
||||
|
|
@ -120,12 +135,108 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
}
|
||||
:root[data-theme="tensamin"] [data-slot][aria-invalid="true"] {
|
||||
--tensamin-edge: var(--destructive);
|
||||
}`,
|
||||
},
|
||||
{
|
||||
id: "og-tensamin",
|
||||
title: "OG Tensamin",
|
||||
logo: OG_TENSAMIN_LOGO,
|
||||
defaultValues: {
|
||||
borderRadius: 0.625,
|
||||
design: DEFAULT_THEME_DESIGN,
|
||||
},
|
||||
css: `:root[data-theme="og-tensamin"] {
|
||||
--background: #f2f1f3;
|
||||
--foreground: #17181e;
|
||||
--card: #d8d6db;
|
||||
--card-foreground: #17181e;
|
||||
--popover: #f2f1f3;
|
||||
--popover-foreground: #17181e;
|
||||
--primary: #aca1cf;
|
||||
--primary-foreground: #0f1014;
|
||||
--primary-foreground-alt: #aca1cf;
|
||||
--secondary: #d8d6db;
|
||||
--secondary-foreground: #17181e;
|
||||
--muted: #d8d6db;
|
||||
--muted-foreground: #383b46;
|
||||
--accent: #bebbc3;
|
||||
--accent-foreground: #0f1014;
|
||||
--destructive: #e78284;
|
||||
--border: #a4a0ab;
|
||||
--input: #a4a0ab;
|
||||
--ring: #aca1cf;
|
||||
--sidebar: #d8d6db;
|
||||
--sidebar-foreground: #17181e;
|
||||
--sidebar-primary: #aca1cf;
|
||||
--sidebar-primary-foreground: #0f1014;
|
||||
--sidebar-accent: #bebbc3;
|
||||
--sidebar-accent-foreground: #0f1014;
|
||||
--sidebar-border: #a4a0ab;
|
||||
--sidebar-ring: #aca1cf;
|
||||
--chart-1: #90b99f;
|
||||
--chart-2: #babbf1;
|
||||
--chart-3: #aca1cf;
|
||||
--chart-4: #e29eca;
|
||||
--chart-5: #e5c890;
|
||||
}
|
||||
:root.dark[data-theme="og-tensamin"] {
|
||||
--background: #0f1014;
|
||||
--foreground: #bebbc3;
|
||||
--card: #17181e;
|
||||
--card-foreground: #bebbc3;
|
||||
--popover: #17181e;
|
||||
--popover-foreground: #bebbc3;
|
||||
--primary: #aca1cf;
|
||||
--primary-foreground: #0f1014;
|
||||
--primary-foreground-alt: #babbf1;
|
||||
--secondary: #282a33;
|
||||
--secondary-foreground: #d8d6db;
|
||||
--muted: #17181e;
|
||||
--muted-foreground: #a4a0ab;
|
||||
--accent: #282a33;
|
||||
--accent-foreground: #f2f1f3;
|
||||
--destructive: #e78284;
|
||||
--border: #282a33;
|
||||
--input: #383b46;
|
||||
--ring: #aca1cf;
|
||||
--sidebar: #0f1014;
|
||||
--sidebar-foreground: #bebbc3;
|
||||
--sidebar-primary: #aca1cf;
|
||||
--sidebar-primary-foreground: #0f1014;
|
||||
--sidebar-accent: #282a33;
|
||||
--sidebar-accent-foreground: #f2f1f3;
|
||||
--sidebar-border: #282a33;
|
||||
--sidebar-ring: #aca1cf;
|
||||
--chart-1: #90b99f;
|
||||
--chart-2: #babbf1;
|
||||
--chart-3: #aca1cf;
|
||||
--chart-4: #e29eca;
|
||||
--chart-5: #e5c890;
|
||||
}
|
||||
:root[data-theme="og-tensamin"] :where([data-slot="select-content"], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-sub-content"], [data-slot="context-menu-content"], [data-slot="context-menu-sub-content"], [data-slot="menubar-content"], [data-slot="menubar-sub-content"], [data-slot="combobox-content"], [data-slot="popover-content"], [data-slot="hover-card-content"]) {
|
||||
background-color: var(--popover);
|
||||
border-color: var(--border);
|
||||
color: var(--popover-foreground);
|
||||
}
|
||||
:root[data-theme="og-tensamin"] :where([data-slot="select-item"], [data-slot="dropdown-menu-item"], [data-slot="dropdown-menu-checkbox-item"], [data-slot="dropdown-menu-radio-item"], [data-slot="dropdown-menu-sub-trigger"], [data-slot="context-menu-item"], [data-slot="context-menu-checkbox-item"], [data-slot="context-menu-radio-item"], [data-slot="context-menu-sub-trigger"], [data-slot="menubar-item"], [data-slot="menubar-checkbox-item"], [data-slot="menubar-radio-item"], [data-slot="menubar-sub-trigger"]):focus,
|
||||
:root[data-theme="og-tensamin"] [data-slot="combobox-item"][data-highlighted],
|
||||
:root[data-theme="og-tensamin"] [data-slot="command-item"][data-selected] {
|
||||
background-color: var(--accent);
|
||||
color: var(--accent-foreground);
|
||||
}`,
|
||||
},
|
||||
{
|
||||
id: "methanium",
|
||||
title: "Methanium",
|
||||
logo: METHANIUM_LOGO,
|
||||
defaultValues: {
|
||||
borderRadius: 0.25,
|
||||
design: {
|
||||
...DEFAULT_THEME_DESIGN,
|
||||
headingWeight: 500,
|
||||
fontFamily: "system",
|
||||
},
|
||||
},
|
||||
css: `:root[data-theme="methanium"] {
|
||||
--background: #d2e0f0;
|
||||
--foreground: #10161d;
|
||||
|
|
@ -198,7 +309,7 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
background-color: var(--background);
|
||||
}
|
||||
:root[data-theme="methanium"] :where([data-slot="card"], [data-slot="button"], [data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"], [data-slot="popover-content"]) {
|
||||
border-radius: 0.25rem;
|
||||
border-radius: var(--radius);
|
||||
border-style: solid;
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"] {
|
||||
|
|
@ -238,27 +349,30 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
:root[data-theme="methanium"] [data-slot="card"] {
|
||||
padding-block: calc(1rem * var(--ui-density));
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"] {
|
||||
:root[data-theme="methanium"] [data-slot="button"]:where([data-variant="default"], [data-variant="outline"]) {
|
||||
background-color: var(--primary);
|
||||
color: var(--primary-foreground);
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"]:hover {
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="default"] {
|
||||
border-color: transparent;
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"] {
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"]:where([data-variant="default"], [data-variant="outline"]):hover {
|
||||
background-color: #bb6fd6;
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"]:is(:hover, :focus-visible) {
|
||||
border-color: color-mix(in srgb, var(--input) 75%, var(--foreground) 25%);
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"] {
|
||||
background-color: var(--secondary);
|
||||
border-color: color-mix(in srgb, white 16%, transparent);
|
||||
color: var(--secondary-foreground);
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"]:hover,
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"]:hover {
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="secondary"]:hover {
|
||||
background-color: color-mix(in srgb, var(--secondary) 80%, var(--foreground) 20%);
|
||||
}
|
||||
:root[data-theme="methanium"] [data-slot="button"][data-variant="outline"] {
|
||||
background-color: transparent;
|
||||
border-color: var(--input);
|
||||
color: var(--foreground);
|
||||
}
|
||||
:root[data-theme="methanium"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) {
|
||||
background-color: color-mix(in srgb, var(--input) 55%, var(--background));
|
||||
border-color: var(--input);
|
||||
|
|
@ -273,103 +387,148 @@ export const BUILT_IN_THEMES = defineThemes([
|
|||
id: "secret",
|
||||
title: "Secret",
|
||||
logo: SECRET_LOGO,
|
||||
defaultValues: {
|
||||
borderRadius: 0.625,
|
||||
design: DEFAULT_THEME_DESIGN,
|
||||
},
|
||||
css: `:root[data-theme="secret"] {
|
||||
--background: oklch(0.93 0.04 150);
|
||||
--foreground: oklch(0.2 0.025 150);
|
||||
--card: oklch(0.84 0.1 84);
|
||||
--card-foreground: oklch(0.2 0.025 150);
|
||||
--popover: oklch(0.975 0.012 135);
|
||||
--popover-foreground: oklch(0.2 0.025 150);
|
||||
--primary: oklch(0.72 0.14 80);
|
||||
--primary-foreground: oklch(0.19 0.025 75);
|
||||
--primary-foreground-alt: oklch(0.59 0.13 76);
|
||||
--secondary: oklch(0.925 0.025 145);
|
||||
--secondary-foreground: oklch(0.25 0.035 150);
|
||||
--muted: oklch(0.935 0.016 105);
|
||||
--muted-foreground: oklch(0.48 0.025 125);
|
||||
--accent: oklch(0.91 0.035 145);
|
||||
--accent-foreground: oklch(0.3 0.06 150);
|
||||
--destructive: oklch(0.52 0.11 95);
|
||||
--border: oklch(0.79 0.045 78);
|
||||
--input: oklch(0.86 0.025 110);
|
||||
--ring: oklch(0.7 0.13 80);
|
||||
--sidebar: oklch(0.945 0.018 145);
|
||||
--sidebar-foreground: oklch(0.22 0.03 150);
|
||||
--sidebar-primary: oklch(0.7 0.13 80);
|
||||
--sidebar-primary-foreground: oklch(0.19 0.025 75);
|
||||
--sidebar-accent: oklch(0.9 0.03 145);
|
||||
--sidebar-accent-foreground: oklch(0.3 0.06 150);
|
||||
--sidebar-border: oklch(0.78 0.04 78);
|
||||
--background: #2f1b13;
|
||||
--foreground: #fffaf2;
|
||||
--card: #f9b637;
|
||||
--card-foreground: #24120c;
|
||||
--popover: #5e244e;
|
||||
--popover-foreground: #fffaf2;
|
||||
--primary: #f9b637;
|
||||
--primary-foreground: #24120c;
|
||||
--primary-foreground-alt: #fb6c00;
|
||||
--secondary: #5e244e;
|
||||
--secondary-foreground: #fffaf2;
|
||||
--muted: #24120c;
|
||||
--muted-foreground: #ffe8b4;
|
||||
--accent: #fb6c00;
|
||||
--accent-foreground: #24120c;
|
||||
--destructive: #e73f1e;
|
||||
--border: #f9b637;
|
||||
--input: #5e244e;
|
||||
--ring: #fb6c00;
|
||||
--sidebar: #24120c;
|
||||
--sidebar-foreground: #fffaf2;
|
||||
--sidebar-primary: #f9b637;
|
||||
--sidebar-primary-foreground: #24120c;
|
||||
--sidebar-accent: #aa1c41;
|
||||
--sidebar-accent-foreground: #fffaf2;
|
||||
--sidebar-border: #e68457;
|
||||
}
|
||||
:root.dark[data-theme="secret"] {
|
||||
--background: oklch(0.16 0.025 155);
|
||||
--foreground: oklch(0.92 0.018 88);
|
||||
--card: oklch(0.38 0.08 82);
|
||||
--card-foreground: oklch(0.92 0.018 88);
|
||||
--popover: oklch(0.205 0.035 150);
|
||||
--popover-foreground: oklch(0.93 0.018 88);
|
||||
--primary: oklch(0.78 0.13 82);
|
||||
--primary-foreground: oklch(0.2 0.025 75);
|
||||
--primary-foreground-alt: oklch(0.8 0.12 84);
|
||||
--secondary: oklch(0.235 0.035 150);
|
||||
--secondary-foreground: oklch(0.9 0.018 88);
|
||||
--muted: oklch(0.225 0.025 145);
|
||||
--muted-foreground: oklch(0.7 0.025 95);
|
||||
--accent: oklch(0.235 0.055 150);
|
||||
--accent-foreground: oklch(0.91 0.025 82);
|
||||
--destructive: oklch(0.66 0.13 95);
|
||||
--border: oklch(0.34 0.045 76);
|
||||
--input: oklch(0.275 0.035 145);
|
||||
--ring: oklch(0.76 0.12 82);
|
||||
--sidebar: oklch(0.175 0.03 150);
|
||||
--sidebar-foreground: oklch(0.92 0.018 88);
|
||||
--sidebar-primary: oklch(0.76 0.12 82);
|
||||
--sidebar-primary-foreground: oklch(0.2 0.025 75);
|
||||
--sidebar-accent: oklch(0.225 0.05 150);
|
||||
--sidebar-accent-foreground: oklch(0.91 0.025 82);
|
||||
--sidebar-border: oklch(0.32 0.04 75);
|
||||
--background: #24120c;
|
||||
--foreground: #ffe8b4;
|
||||
--card: #f9b637;
|
||||
--card-foreground: #24120c;
|
||||
--popover: #2f1b13;
|
||||
--popover-foreground: #ffe8b4;
|
||||
--primary: #f9b637;
|
||||
--primary-foreground: #24120c;
|
||||
--primary-foreground-alt: #fb6c00;
|
||||
--secondary: #5e244e;
|
||||
--secondary-foreground: #fffaf2;
|
||||
--muted: #2f1b13;
|
||||
--muted-foreground: #e68457;
|
||||
--accent: #e73f1e;
|
||||
--accent-foreground: #fffaf2;
|
||||
--destructive: #e73f1e;
|
||||
--border: #e68457;
|
||||
--input: #5e244e;
|
||||
--ring: #fb6c00;
|
||||
--sidebar: #24120c;
|
||||
--sidebar-foreground: #ffe8b4;
|
||||
--sidebar-primary: #f9b637;
|
||||
--sidebar-primary-foreground: #24120c;
|
||||
--sidebar-accent: #aa1c41;
|
||||
--sidebar-accent-foreground: #fffaf2;
|
||||
--sidebar-border: #5e244e;
|
||||
}
|
||||
:root[data-theme="secret"] body {
|
||||
background-color: var(--background);
|
||||
background-image: radial-gradient(circle at 12% 8%, oklch(0.3 0.07 150 / 9%), transparent 34%), radial-gradient(circle at 90% 5%, oklch(0.58 0.09 165 / 8%), transparent 30%);
|
||||
background-image: radial-gradient(circle at 12% 8%, rgb(94 36 78 / 24%), transparent 34%), radial-gradient(circle at 90% 5%, rgb(231 63 30 / 14%), transparent 30%);
|
||||
background-attachment: fixed;
|
||||
}
|
||||
:root.dark[data-theme="secret"] body {
|
||||
background-image: radial-gradient(circle at 12% 8%, oklch(0.29 0.075 150 / 52%), transparent 38%), radial-gradient(circle at 92% 4%, oklch(0.25 0.08 165 / 42%), transparent 34%);
|
||||
background-image: radial-gradient(circle at 12% 8%, rgb(94 36 78 / 42%), transparent 38%), radial-gradient(circle at 92% 4%, rgb(170 28 65 / 30%), transparent 34%);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="button"], [data-slot="toggle"], [data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"], [data-slot="checkbox"], [data-slot="radio-group-item"], [data-slot="switch"]) {
|
||||
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%));
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]) {
|
||||
background-color: var(--input);
|
||||
color: var(--foreground);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):hover {
|
||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="input"], [data-slot="textarea"], [data-slot="native-select"], [data-slot="select-trigger"], [data-slot="input-group"]):is(:focus-visible, :focus-within) {
|
||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="select-trigger"]:is([data-popup-open], [data-open], [aria-expanded="true"]) {
|
||||
background-color: color-mix(in srgb, var(--input) 84%, #24120c 16%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="select-content"] {
|
||||
background-color: var(--popover);
|
||||
border-color: color-mix(in srgb, #ffe8b4 15%, #24120c 85%);
|
||||
color: var(--popover-foreground);
|
||||
}
|
||||
:root.dark[data-theme="secret"] [data-slot="select-content"] {
|
||||
border-color: color-mix(in srgb, #ffe8b4 15%, #24120c 85%);
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="select-item"]:is(:hover, :focus, [data-highlighted], [data-selected]) {
|
||||
background-color: #24120c;
|
||||
color: #ffe8b4;
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="button"][data-variant="default"] {
|
||||
background-color: var(--primary);
|
||||
background-image: linear-gradient(115deg, oklch(0.57 0.12 72) 0%, oklch(0.76 0.15 82) 30%, oklch(0.96 0.035 92) 47%, oklch(0.79 0.14 84) 58%, oklch(0.62 0.13 74) 100%);
|
||||
border-color: oklch(0.62 0.12 76);
|
||||
background-image: linear-gradient(to top, rgb(255 255 255 / 12%), rgb(255 255 255 / 2%)), linear-gradient(115deg, #e73f1e 0%, #fb6c00 30%, #ffdd9c 47%, #f9b637 58%, #fb6c00 100%);
|
||||
border-color: #e68457;
|
||||
color: var(--primary-foreground);
|
||||
text-shadow: 0 1px rgb(255 255 255 / 35%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 45%), 0 0.45rem 1.2rem oklch(0.35 0.07 75 / 16%);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 45%), 0 0.45rem 1.2rem rgb(36 18 12 / 28%);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="card"], [data-slot="dialog-content"], [data-slot="alert-dialog-content"]) {
|
||||
border-color: color-mix(in oklch, var(--border) 72%, var(--primary));
|
||||
box-shadow: inset 0 1px color-mix(in oklch, white 8%, transparent), 0 1rem 3rem oklch(0.1 0.03 150 / 12%);
|
||||
box-shadow: inset 0 1px color-mix(in oklch, white 8%, transparent), 0 1rem 3rem rgb(97 37 82 / 12%);
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="card"] {
|
||||
background: linear-gradient(115deg, oklch(0.68 0.1 74) 0%, oklch(0.86 0.12 84) 30%, oklch(0.98 0.025 94) 47%, oklch(0.88 0.11 86) 58%, oklch(0.72 0.1 76) 100%);
|
||||
background: linear-gradient(115deg, #e68457 0%, #f9b637 30%, #fffaf2 47%, #ffdd9c 58%, #fb6c00 100%);
|
||||
}
|
||||
:root.dark[data-theme="secret"] [data-slot="card"] {
|
||||
background: linear-gradient(115deg, oklch(0.27 0.055 72) 0%, oklch(0.43 0.09 82) 30%, oklch(0.68 0.075 91) 47%, oklch(0.46 0.09 84) 58%, oklch(0.3 0.06 74) 100%);
|
||||
background: linear-gradient(115deg, #5e244e 0%, #aa1c41 18%, #e68457 32%, #f9b637 44%, #fffaf2 50%, #ffdd9c 58%, #fb6c00 72%, #5e244e 100%);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"] {
|
||||
background-color: oklch(0.86 0.055 150);
|
||||
border-color: oklch(0.5 0.09 150);
|
||||
color: oklch(0.27 0.07 150);
|
||||
background-color: #5e244e;
|
||||
border-color: var(--input);
|
||||
color: #fffaf2;
|
||||
}
|
||||
:root[data-theme="secret"] [data-slot="button"][data-variant="outline"]:hover {
|
||||
background-color: oklch(0.8 0.075 150);
|
||||
background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:hover {
|
||||
background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"]:is(:focus-visible, [aria-expanded="true"], [data-popup-open], [data-open]) {
|
||||
background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%);
|
||||
border-color: var(--input);
|
||||
}
|
||||
:root.dark[data-theme="secret"] :where([data-slot="button"], [data-slot="badge"], [data-slot="toggle"])[data-variant="outline"] {
|
||||
background-color: oklch(0.22 0.055 150);
|
||||
border-color: oklch(0.52 0.1 150);
|
||||
color: oklch(0.82 0.08 150);
|
||||
background-color: #5e244e;
|
||||
border-color: var(--input);
|
||||
color: #ffe8b4;
|
||||
}
|
||||
:root.dark[data-theme="secret"] [data-slot="button"][data-variant="outline"]:hover {
|
||||
background-color: oklch(0.3 0.07 150);
|
||||
background-color: color-mix(in srgb, #5e244e 82%, #24120c 18%);
|
||||
}
|
||||
:root[data-theme="secret"] :where([data-slot="card-title"], [data-slot="item-media"][data-variant="icon"], [data-slot="badge"][data-variant="outline"]) svg {
|
||||
color: var(--primary);
|
||||
|
|
|
|||
|
|
@ -36,11 +36,17 @@ export type ThemeDesign = {
|
|||
fontFamily: ThemeFontFamily;
|
||||
};
|
||||
|
||||
export type ThemeDefaultValues = {
|
||||
borderRadius: number;
|
||||
design: ThemeDesign;
|
||||
};
|
||||
|
||||
export type ThemePreset = {
|
||||
id: string;
|
||||
title: string;
|
||||
logo: string;
|
||||
css: string;
|
||||
defaultValues?: ThemeDefaultValues;
|
||||
};
|
||||
|
||||
export type ThemeProviderProps = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue