From 25b2090961d4fadc24e63ac1b3e3950329c4c73b Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Wed, 30 Oct 2024 23:02:05 -0700 Subject: [PATCH] add shadcn --- .idea/.gitignore | 8 + .idea/codeStyles/Project.xml | 180 +++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/modules.xml | 8 + .idea/prettier.xml | 6 + .idea/vcs.xml | 6 + .idea/vpgen-sv5.iml | 12 ++ bun.lockb | Bin 157246 -> 158395 bytes components.json | 14 ++ package.json | 3 + src/app.css | 84 ++++++++- src/lib/utils.ts | 62 +++++++ tailwind.config.ts | 70 ++++++-- 14 files changed, 451 insertions(+), 13 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/prettier.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/vpgen-sv5.iml create mode 100644 components.json create mode 100644 src/lib/utils.ts diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..f7ca32d --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c41ee43 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..b0c1c68 --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vpgen-sv5.iml b/.idea/vpgen-sv5.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/vpgen-sv5.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index 13a878bfeb5f8477fe3d967dfb545e74b5f64a7c..2b632428f7a561679961bf15cf64aba7475df6bf 100755 GIT binary patch delta 24136 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 delta 23506 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 Lyfx5N*Zuzi5AV~k diff --git a/components.json b/components.json new file mode 100644 index 0000000..f95a168 --- /dev/null +++ b/components.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "style": "default", + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app.css", + "baseColor": "slate" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils" + }, + "typescript": true +} \ No newline at end of file diff --git a/package.json b/package.json index 3f77631..22f0839 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@types/better-sqlite3": "^7.6.11", "@types/eslint": "^9.6.0", "autoprefixer": "^10.4.20", + "clsx": "^2.1.1", "drizzle-kit": "^0.22.0", "eslint": "^9.7.0", "eslint-config-prettier": "^9.1.0", @@ -34,6 +35,8 @@ "prettier-plugin-tailwindcss": "^0.6.5", "svelte": "^5.0.0", "svelte-check": "^4.0.0", + "tailwind-merge": "^2.5.4", + "tailwind-variants": "^0.2.1", "tailwindcss": "^3.4.9", "typescript": "^5.0.0", "typescript-eslint": "^8.0.0", diff --git a/src/app.css b/src/app.css index a31e444..c7bf8da 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,81 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities'; +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 72.2% 50.6%; + --destructive-foreground: 210 40% 98%; + + --ring: 222.2 84% 4.9%; + + --radius: 0.5rem; + } + + @media (prefers-color-scheme: dark) { + :root { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + + --ring: 212.7 26.8% 83.9%; + } + } +} + +@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..8871245 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,62 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; +import { cubicOut } from "svelte/easing"; +import type { TransitionConfig } from "svelte/transition"; + +export function cn(...inputs: ClassValue[]) { + 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 => { + 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 + }; +}; \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 9ddaa5d..c4bf235 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,14 +1,64 @@ -import containerQueries from '@tailwindcss/container-queries'; -import forms from '@tailwindcss/forms'; -import typography from '@tailwindcss/typography'; -import type { Config } from 'tailwindcss'; - -export default { - content: ['./src/**/*.{html,js,svelte,ts}'], +import { fontFamily } from "tailwindcss/defaultTheme"; +import type { Config } from "tailwindcss"; +const config: Config = { + darkMode: ["class"], + content: ["./src/**/*.{html,js,svelte,ts}"], + safelist: ["dark"], theme: { - extend: {} + 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) / )" + } + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)" + }, + fontFamily: { + sans: [...fontFamily.sans] + } + } }, +}; - plugins: [typography, forms, containerQueries] -} satisfies Config; +export default config;