From 2db24f56a56bac97df238c299b31d9df659261a6 Mon Sep 17 00:00:00 2001 From: Michael Krebs Date: Sat, 5 Apr 2025 11:07:52 +0200 Subject: [PATCH] feat: setup shadcn-svelte --- components.json | 17 ++++++++ package.json | 4 ++ pnpm-lock.yaml | 42 ++++++++++++++++++ src/app.css | 78 ++++++++++++++++++++++++++++++++-- src/lib/utils.ts | 6 +++ tailwind.config.ts | 103 +++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 238 insertions(+), 12 deletions(-) create mode 100644 components.json create mode 100644 src/lib/utils.ts diff --git a/components.json b/components.json new file mode 100644 index 0000000..4106aaa --- /dev/null +++ b/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://next.shadcn-svelte.com/schema.json", + "style": "default", + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app.css", + "baseColor": "zinc" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks" + }, + "typescript": true, + "registry": "https://next.shadcn-svelte.com/registry" +} diff --git a/package.json b/package.json index 83d9976..d0ff9ef 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,14 @@ "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "drizzle-kit": "^0.30.2", "svelte": "^5.0.0", "svelte-check": "^4.0.0", + "tailwind-merge": "^3.1.0", + "tailwind-variants": "^1.0.0", "tailwindcss": "^3.4.17", + "tailwindcss-animate": "^1.0.7", "typescript": "^5.0.0", "vite": "^6.2.5" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a213c34..a42c517 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,9 @@ importers: autoprefixer: specifier: ^10.4.20 version: 10.4.21(postcss@8.5.3) + clsx: + specifier: ^2.1.1 + version: 2.1.1 drizzle-kit: specifier: ^0.30.2 version: 0.30.6 @@ -36,9 +39,18 @@ importers: svelte-check: specifier: ^4.0.0 version: 4.1.5(svelte@5.25.6)(typescript@5.8.2) + tailwind-merge: + specifier: ^3.1.0 + version: 3.1.0 + tailwind-variants: + specifier: ^1.0.0 + version: 1.0.0(tailwindcss@3.4.17) tailwindcss: specifier: ^3.4.17 version: 3.4.17 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.17) typescript: specifier: ^5.0.0 version: 5.8.2 @@ -1397,6 +1409,23 @@ packages: resolution: {integrity: sha512-RGkaeAXDuJdvhA1fdSM5GgD++vYfJYijZL0uN6kM2s/TRJ663jktBhZlF0qjzAJGR/34PtaeT3G8MKJY1EKeqg==} engines: {node: '>=18'} + tailwind-merge@3.0.2: + resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} + + tailwind-merge@3.1.0: + resolution: {integrity: sha512-aV27Oj8B7U/tAOMhJsSGdWqelfmudnGMdXIlMnk1JfsjwSjts6o8HyfN7SFH3EztzH4YH8kk6GbLTHzITJO39Q==} + + tailwind-variants@1.0.0: + resolution: {integrity: sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==} + engines: {node: '>=16.x', pnpm: '>=7.x'} + peerDependencies: + tailwindcss: '*' + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -2601,6 +2630,19 @@ snapshots: magic-string: 0.30.17 zimmerframe: 1.1.2 + tailwind-merge@3.0.2: {} + + tailwind-merge@3.1.0: {} + + tailwind-variants@1.0.0(tailwindcss@3.4.17): + dependencies: + tailwind-merge: 3.0.2 + tailwindcss: 3.4.17 + + tailwindcss-animate@1.0.7(tailwindcss@3.4.17): + dependencies: + tailwindcss: 3.4.17 + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 diff --git a/src/app.css b/src/app.css index 6c8f99f..606172e 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,75 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities' +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 72.2% 50.6%; + --destructive-foreground: 0 0% 98%; + --ring: 240 10% 3.9%; + --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 { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --ring: 240 4.9% 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%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..ac680b3 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 879abef..d91ff63 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,11 +1,96 @@ -import type { Config } from 'tailwindcss'; +import { fontFamily } from "tailwindcss/defaultTheme"; +import type { Config } from "tailwindcss"; +import tailwindcssAnimate from "tailwindcss-animate"; -export default { - content: ['./src/**/*.{html,js,svelte,ts}'], +const config: Config = { + darkMode: ["class"], + content: ["./src/**/*.{html,js,svelte,ts}"], + safelist: ["dark"], + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px" + } + }, + extend: { + colors: { + border: "hsl(var(--border) / )", + input: "hsl(var(--input) / )", + ring: "hsl(var(--ring) / )", + background: "hsl(var(--background) / )", + foreground: "hsl(var(--foreground) / )", + primary: { + DEFAULT: "hsl(var(--primary) / )", + foreground: "hsl(var(--primary-foreground) / )" + }, + secondary: { + DEFAULT: "hsl(var(--secondary) / )", + foreground: "hsl(var(--secondary-foreground) / )" + }, + destructive: { + DEFAULT: "hsl(var(--destructive) / )", + foreground: "hsl(var(--destructive-foreground) / )" + }, + muted: { + DEFAULT: "hsl(var(--muted) / )", + foreground: "hsl(var(--muted-foreground) / )" + }, + accent: { + DEFAULT: "hsl(var(--accent) / )", + foreground: "hsl(var(--accent-foreground) / )" + }, + popover: { + DEFAULT: "hsl(var(--popover) / )", + foreground: "hsl(var(--popover-foreground) / )" + }, + card: { + DEFAULT: "hsl(var(--card) / )", + foreground: "hsl(var(--card-foreground) / )" + }, + sidebar: { + DEFAULT: "hsl(var(--sidebar-background))", + foreground: "hsl(var(--sidebar-foreground))", + primary: "hsl(var(--sidebar-primary))", + "primary-foreground": "hsl(var(--sidebar-primary-foreground))", + accent: "hsl(var(--sidebar-accent))", + "accent-foreground": "hsl(var(--sidebar-accent-foreground))", + 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], +}; - theme: { - extend: {} - }, - - plugins: [] -} satisfies Config; +export default config;