Compare commits

...

4 Commits

Author SHA1 Message Date
349495019f Slightly darker red 2025-03-09 19:29:29 +01:00
bb31650718 Add toast 2025-03-09 19:26:19 +01:00
ce9ed1f950 Minor update 2025-03-09 18:50:45 +01:00
f314b960e1 smol stuff 2025-03-09 18:29:00 +01:00
15 changed files with 203 additions and 156 deletions

View File

@@ -7,7 +7,7 @@ services:
PSN_DEFAULT_UDP_MCAST_ADDRESS: "236.10.10.10" PSN_DEFAULT_UDP_MCAST_ADDRESS: "236.10.10.10"
WEB_SERVER_PORT: 8000 WEB_SERVER_PORT: 8000
OSC_SERVER_PORT: 9000 OSC_SERVER_PORT: 9000
NUM_TRACKERS: 3 NUM_TRACKERS: 0
volumes: volumes:
- spot-data:/data - spot-data:/data

View File

@@ -1,5 +1,5 @@
{ {
"$schema": "https://shadcn-svelte.com/schema.json", "$schema": "https://next.shadcn-svelte.com/schema.json",
"style": "default", "style": "default",
"tailwind": { "tailwind": {
"config": "tailwind.config.mjs", "config": "tailwind.config.mjs",
@@ -8,7 +8,10 @@
}, },
"aliases": { "aliases": {
"components": "$lib/components", "components": "$lib/components",
"utils": "$lib/utils" "utils": "$lib/utils",
"ui": "$lib/components/ui",
"hooks": "$lib/hooks"
}, },
"typescript": true "typescript": true,
"registry": "https://next.shadcn-svelte.com/registry"
} }

View File

@@ -21,12 +21,15 @@
"devDependencies": { "devDependencies": {
"bits-ui": "0.22.0", "bits-ui": "0.22.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"mode-watcher": "^0.5.1",
"prettier": "^3.5.3", "prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1", "prettier-plugin-astro": "^0.14.1",
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11", "prettier-plugin-tailwindcss": "^0.6.11",
"svelte-sonner": "^0.3.28",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",
"tailwind-variants": "^1.0.0", "tailwind-variants": "^1.0.0",
"tailwindcss-animate": "^1.0.7",
"vaul-svelte": "^0.3.2" "vaul-svelte": "^0.3.2"
}, },
"pnpm": { "pnpm": {

View File

@@ -36,6 +36,9 @@ importers:
clsx: clsx:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.1.1 version: 2.1.1
mode-watcher:
specifier: ^0.5.1
version: 0.5.1(svelte@5.22.6)
prettier: prettier:
specifier: ^3.5.3 specifier: ^3.5.3
version: 3.5.3 version: 3.5.3
@@ -48,12 +51,18 @@ importers:
prettier-plugin-tailwindcss: prettier-plugin-tailwindcss:
specifier: ^0.6.11 specifier: ^0.6.11
version: 0.6.11(prettier-plugin-astro@0.14.1)(prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.22.6))(prettier@3.5.3) version: 0.6.11(prettier-plugin-astro@0.14.1)(prettier-plugin-svelte@3.3.3(prettier@3.5.3)(svelte@5.22.6))(prettier@3.5.3)
svelte-sonner:
specifier: ^0.3.28
version: 0.3.28(svelte@5.22.6)
tailwind-merge: tailwind-merge:
specifier: ^3.0.2 specifier: ^3.0.2
version: 3.0.2 version: 3.0.2
tailwind-variants: tailwind-variants:
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0(tailwindcss@3.4.17) version: 1.0.0(tailwindcss@3.4.17)
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.17)
vaul-svelte: vaul-svelte:
specifier: ^0.3.2 specifier: ^0.3.2
version: 0.3.2(svelte@5.22.6) version: 0.3.2(svelte@5.22.6)
@@ -1392,6 +1401,11 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'} engines: {node: '>=16 || 14 >=14.17'}
mode-watcher@0.5.1:
resolution: {integrity: sha512-adEC6T7TMX/kzQlaO/MtiQOSFekZfQu4MC+lXyoceQG+U5sKpJWZ4yKXqw846ExIuWJgedkOIPqAYYRk/xHm+w==}
peerDependencies:
svelte: ^4.0.0 || ^5.0.0-next.1
mrmime@2.0.1: mrmime@2.0.1:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@@ -1857,6 +1871,11 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
svelte-sonner@0.3.28:
resolution: {integrity: sha512-K3AmlySeFifF/cKgsYNv5uXqMVNln0NBAacOYgmkQStLa/UoU0LhfAACU6Gr+YYC8bOCHdVmFNoKuDbMEsppJg==}
peerDependencies:
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0-next.1
svelte2tsx@0.7.35: svelte2tsx@0.7.35:
resolution: {integrity: sha512-z2lnOnrfb5nrlRfFQI8Qdz03xQqMHUfPj0j8l/fQuydrH89cCeN+v9jgDwK9GyMtdTRUkE7Neu9Gh+vfXJAfuQ==} resolution: {integrity: sha512-z2lnOnrfb5nrlRfFQI8Qdz03xQqMHUfPj0j8l/fQuydrH89cCeN+v9jgDwK9GyMtdTRUkE7Neu9Gh+vfXJAfuQ==}
peerDependencies: peerDependencies:
@@ -1879,6 +1898,11 @@ packages:
peerDependencies: peerDependencies:
tailwindcss: '*' tailwindcss: '*'
tailwindcss-animate@1.0.7:
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
tailwindcss@3.4.17: tailwindcss@3.4.17:
resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@@ -3913,6 +3937,10 @@ snapshots:
minipass@7.1.2: {} minipass@7.1.2: {}
mode-watcher@0.5.1(svelte@5.22.6):
dependencies:
svelte: 5.22.6
mrmime@2.0.1: {} mrmime@2.0.1: {}
ms@2.1.3: {} ms@2.1.3: {}
@@ -4392,6 +4420,10 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {} supports-preserve-symlinks-flag@1.0.0: {}
svelte-sonner@0.3.28(svelte@5.22.6):
dependencies:
svelte: 5.22.6
svelte2tsx@0.7.35(svelte@5.22.6)(typescript@5.8.2): svelte2tsx@0.7.35(svelte@5.22.6)(typescript@5.8.2):
dependencies: dependencies:
dedent-js: 1.0.1 dedent-js: 1.0.1
@@ -4425,6 +4457,10 @@ snapshots:
tailwind-merge: 3.0.2 tailwind-merge: 3.0.2
tailwindcss: 3.4.17 tailwindcss: 3.4.17
tailwindcss-animate@1.0.7(tailwindcss@3.4.17):
dependencies:
tailwindcss: 3.4.17
tailwindcss@3.4.17: tailwindcss@3.4.17:
dependencies: dependencies:
'@alloc/quick-lru': 5.2.0 '@alloc/quick-lru': 5.2.0

View File

@@ -8,10 +8,7 @@
let ws: WebSocket | null = $state(null); let ws: WebSocket | null = $state(null);
let image: HTMLImageElement | null = $state(null); let image: HTMLImageElement | null = $state(null);
let trackers: TrackerData[] = $state([ let trackers: TrackerData[] = $state([]);
{ id: 1, x: 0, y: 0, z: 0 },
{ id: 2, x: 0, y: 0, z: 0 },
]);
let width = $state(0); let width = $state(0);
let height = $state(0); let height = $state(0);
@@ -65,7 +62,7 @@
</script> </script>
<svelte:window onresize={resize} /> <svelte:window onresize={resize} />
<div class="flex h-screen w-screen items-center justify-center"> <div class="flex h-screen w-screen items-center justify-center gap-2 py-2">
<div class="mr-auto w-20"> <div class="mr-auto w-20">
<Settings /> <Settings />
</div> </div>

View File

@@ -1,4 +1,6 @@
<script lang="ts"> <script lang="ts">
import { cn } from "$lib/utils";
type Props = { type Props = {
id: number; id: number;
x: number; x: number;
@@ -75,8 +77,12 @@
onpointerup={onPointerUp} onpointerup={onPointerUp}
onpointermove={onPointerMove} onpointermove={onPointerMove}
style={`transform: translate(${vis_x}px, ${vis_y}px)`} style={`transform: translate(${vis_x}px, ${vis_y}px)`}
class={`absolute flex h-24 w-24 touch-none select-none items-center justify-center rounded-full class={cn(
${selected === id ? "border-green-400 bg-green-400 z-50" : "border-red-400 bg-red-400"}`} "absolute flex h-24 w-24 touch-none select-none items-center justify-center rounded-full",
selected === id
? "z-50 border-green-400 bg-green-400"
: "border-red-400 bg-red-400",
)}
> >
Tracker {id} Tracker {id}
</div> </div>

View File

@@ -11,7 +11,7 @@
}; };
</script> </script>
<button class="mb-24 rounded-md bg-red-400 p-2" onclick={openModal}> <button class="mb-24 rounded-md bg-red-500 p-2" onclick={openModal}>
Change mode Change mode
</button> </button>
@@ -21,13 +21,13 @@
class="absolute left-0 top-0 z-50 m-0 h-full max-h-full w-full max-w-full p-0 open:bg-black/80" class="absolute left-0 top-0 z-50 m-0 h-full max-h-full w-full max-w-full p-0 open:bg-black/80"
> >
<div class="flex h-full w-full flex-col items-center justify-center"> <div class="flex h-full w-full flex-col items-center justify-center">
<h1 class="text-8xl text-red-600">THIS GONNA FUCK THINGS UP</h1> <h1 class="text-center text-8xl text-red-600">THIS GONNA FUCK THINGS UP</h1>
<div class="flex items-center justify-center gap-6"> <div class="flex items-center justify-center gap-6">
<button class="rounded-md bg-gray-400 p-4" onclick={() => dialog.close()} <button class="rounded-md bg-gray-400 p-4" onclick={() => dialog.close()}
>Close</button >Close</button
> >
<button <button
class="rounded-md bg-red-400 p-4" class="rounded-md bg-red-500 p-4"
onclick={() => { onclick={() => {
action(); action();
dialog.close(); dialog.close();

View File

@@ -2,6 +2,7 @@
import * as Drawer from "$lib/components/ui/drawer/index.js"; import * as Drawer from "$lib/components/ui/drawer/index.js";
import { Button } from "$lib/components/ui/button/index.js"; import { Button } from "$lib/components/ui/button/index.js";
import TrackerSetting from "./TrackerSetting.svelte"; import TrackerSetting from "./TrackerSetting.svelte";
import { toast } from "svelte-sonner";
const addTracker = async (arg: number) => { const addTracker = async (arg: number) => {
const response = await fetch("/tracker", { const response = await fetch("/tracker", {
@@ -14,7 +15,9 @@
}), }),
}); });
console.log(response); if (!response.ok) {
toast.error("Could not add tracker");
}
}; };
const deleteTracker = async (arg: number) => { const deleteTracker = async (arg: number) => {
@@ -27,7 +30,9 @@
id: Number(arg), id: Number(arg),
}), }),
}); });
console.log(response); if (!response.ok) {
toast.error("Could not delete tracker");
}
}; };
let id = $state(0); let id = $state(0);
@@ -35,7 +40,7 @@
<Drawer.Root> <Drawer.Root>
<Drawer.Trigger asChild let:builder> <Drawer.Trigger asChild let:builder>
<Button builders={[builder]} variant="outline">Settings</Button> <Button builders={[builder]} variant="secondary">Settings</Button>
</Drawer.Trigger> </Drawer.Trigger>
<Drawer.Content> <Drawer.Content>
<Drawer.Header> <Drawer.Header>

View File

@@ -61,7 +61,7 @@
let z_viz = $derived(tracker?.z.toFixed(2)); let z_viz = $derived(tracker?.z.toFixed(2));
</script> </script>
<div class="slider-container ml-auto"> <div class="slider-container ml-auto w-20">
<Modal action={buttonAction} /> <Modal action={buttonAction} />
{#if tracker} {#if tracker}
<input <input

View File

@@ -0,0 +1 @@
export { default as Toaster } from "./sonner.svelte";

View File

@@ -0,0 +1,20 @@
<script lang="ts">
import { Toaster as Sonner, type ToasterProps as SonnerProps } from "svelte-sonner";
import { mode } from "mode-watcher";
let restProps: SonnerProps = $props();
</script>
<Sonner
theme={$mode}
class="toaster group"
toastOptions={{
classes: {
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
description: "group-[.toast]:text-muted-foreground",
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...restProps}
/>

View File

@@ -1,6 +1,7 @@
--- ---
import Container from "../components/Container.svelte"; import Container from "../components/Container.svelte";
import "$lib/styles/app.css"; import "$lib/styles/app.css";
import { Toaster } from "$lib/components/ui/sonner/index.js";
--- ---
<html lang="en"> <html lang="en">
@@ -15,6 +16,7 @@ import "$lib/styles/app.css";
<title>Followspot</title> <title>Followspot</title>
</head> </head>
<body class="flex h-dvh w-screen items-center justify-center overflow-hidden"> <body class="flex h-dvh w-screen items-center justify-center overflow-hidden">
<Toaster client:load />
<Container client:load /> <Container client:load />
</body> </body>
</html> </html>

View File

@@ -6,65 +6,62 @@
:root { :root {
--background: 0 0% 100%; --background: 0 0% 100%;
--foreground: 222.2 84% 4.9%; --foreground: 222.2 84% 4.9%;
--muted: 210 40% 96.1%; --muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%; --muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%; --popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%; --popover-foreground: 222.2 84% 4.9%;
--card: 0 0% 100%; --card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%; --card-foreground: 222.2 84% 4.9%;
--border: 214.3 31.8% 91.4%; --border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%; --primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%; --primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%; --secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%; --secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%; --accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%; --accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 72.2% 50.6%; --destructive: 0 72.2% 50.6%;
--destructive-foreground: 210 40% 98%; --destructive-foreground: 210 40% 98%;
--ring: 222.2 84% 4.9%; --ring: 222.2 84% 4.9%;
--radius: 0.5rem; --radius: 0.5rem;
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
} }
.dark { .dark {
--background: 222.2 84% 4.9%; --background: 222.2 84% 4.9%;
--foreground: 210 40% 98%; --foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%; --muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%; --muted-foreground: 215 20.2% 65.1%;
--popover: 222.2 84% 4.9%; --popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%; --popover-foreground: 210 40% 98%;
--card: 222.2 84% 4.9%; --card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%; --card-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%; --border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%;
--primary: 210 40% 98%; --primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%; --primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%; --secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%; --secondary-foreground: 210 40% 98%;
--accent: 217.2 32.6% 17.5%; --accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%; --accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%; --destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%; --destructive-foreground: 210 40% 98%;
--ring: 212.7 26.8% 83.9%; --ring: 212.7 26.8% 83.9%;
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
} }
} }
@@ -76,3 +73,4 @@
@apply bg-background text-foreground; @apply bg-background text-foreground;
} }
} }

View File

@@ -1,62 +1,6 @@
import { type ClassValue, clsx } from "clsx"; import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import { cubicOut } from "svelte/easing";
import type { TransitionConfig } from "svelte/transition";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)); return twMerge(clsx(inputs));
} }
type FlyAndScaleParams = {
y?: number;
x?: number;
start?: number;
duration?: number;
};
export const flyAndScale = (
node: Element,
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => {
const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform;
const scaleConversion = (
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB;
const percentage = (valueA - minA) / (maxA - minA);
const valueB = percentage * (maxB - minB) + minB;
return valueB;
};
const styleToString = (
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str;
return str + `${key}:${style[key]};`;
}, "");
};
return {
duration: params.duration ?? 200,
delay: 0,
css: (t) => {
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
return styleToString({
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
opacity: t
});
},
easing: cubicOut
};
};

View File

@@ -1,64 +1,96 @@
import { fontFamily } from "tailwindcss/defaultTheme"; import { fontFamily } from "tailwindcss/defaultTheme";
import tailwindcssAnimate from "tailwindcss-animate";
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
const config = { const config = {
darkMode: ["class"], darkMode: ["class"],
content: ["./src/**/*.{html,js,svelte,ts}"], content: ["./src/**/*.{html,js,svelte,ts,astro}"],
safelist: ["dark"], safelist: ["dark"],
theme: { theme: {
container: { container: {
center: true, center: true,
padding: "2rem", padding: "2rem",
screens: { screens: {
"2xl": "1400px" "2xl": "1400px",
} },
}, },
extend: { extend: {
colors: { colors: {
border: "hsl(var(--border) / <alpha-value>)", border: "hsl(var(--border) / <alpha-value>)",
input: "hsl(var(--input) / <alpha-value>)", input: "hsl(var(--input) / <alpha-value>)",
ring: "hsl(var(--ring) / <alpha-value>)", ring: "hsl(var(--ring) / <alpha-value>)",
background: "hsl(var(--background) / <alpha-value>)", background: "hsl(var(--background) / <alpha-value>)",
foreground: "hsl(var(--foreground) / <alpha-value>)", foreground: "hsl(var(--foreground) / <alpha-value>)",
primary: { primary: {
DEFAULT: "hsl(var(--primary) / <alpha-value>)", DEFAULT: "hsl(var(--primary) / <alpha-value>)",
foreground: "hsl(var(--primary-foreground) / <alpha-value>)" foreground: "hsl(var(--primary-foreground) / <alpha-value>)",
}, },
secondary: { secondary: {
DEFAULT: "hsl(var(--secondary) / <alpha-value>)", DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
foreground: "hsl(var(--secondary-foreground) / <alpha-value>)" foreground: "hsl(var(--secondary-foreground) / <alpha-value>)",
}, },
destructive: { destructive: {
DEFAULT: "hsl(var(--destructive) / <alpha-value>)", DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)" foreground: "hsl(var(--destructive-foreground) / <alpha-value>)",
}, },
muted: { muted: {
DEFAULT: "hsl(var(--muted) / <alpha-value>)", DEFAULT: "hsl(var(--muted) / <alpha-value>)",
foreground: "hsl(var(--muted-foreground) / <alpha-value>)" foreground: "hsl(var(--muted-foreground) / <alpha-value>)",
}, },
accent: { accent: {
DEFAULT: "hsl(var(--accent) / <alpha-value>)", DEFAULT: "hsl(var(--accent) / <alpha-value>)",
foreground: "hsl(var(--accent-foreground) / <alpha-value>)" foreground: "hsl(var(--accent-foreground) / <alpha-value>)",
}, },
popover: { popover: {
DEFAULT: "hsl(var(--popover) / <alpha-value>)", DEFAULT: "hsl(var(--popover) / <alpha-value>)",
foreground: "hsl(var(--popover-foreground) / <alpha-value>)" foreground: "hsl(var(--popover-foreground) / <alpha-value>)",
}, },
card: { card: {
DEFAULT: "hsl(var(--card) / <alpha-value>)", DEFAULT: "hsl(var(--card) / <alpha-value>)",
foreground: "hsl(var(--card-foreground) / <alpha-value>)" foreground: "hsl(var(--card-foreground) / <alpha-value>)",
} },
}, sidebar: {
borderRadius: { DEFAULT: "hsl(var(--sidebar-background))",
lg: "var(--radius)", foreground: "hsl(var(--sidebar-foreground))",
md: "calc(var(--radius) - 2px)", primary: "hsl(var(--sidebar-primary))",
sm: "calc(var(--radius) - 4px)" "primary-foreground": "hsl(var(--sidebar-primary-foreground))",
}, accent: "hsl(var(--sidebar-accent))",
fontFamily: { "accent-foreground": "hsl(var(--sidebar-accent-foreground))",
sans: [...fontFamily.sans] border: "hsl(var(--sidebar-border))",
} ring: "hsl(var(--sidebar-ring))",
} },
}, },
borderRadius: {
xl: "calc(var(--radius) + 4px)",
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
fontFamily: {
sans: [...fontFamily.sans],
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--bits-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--bits-accordion-content-height)" },
to: { height: "0" },
},
"caret-blink": {
"0%,70%,100%": { opacity: "1" },
"20%,50%": { opacity: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"caret-blink": "caret-blink 1.25s ease-out infinite",
},
},
},
plugins: [tailwindcssAnimate],
}; };
export default config; export default config;