From abecae1fee5b37652badaf3dd353a3d91aa8d1c3 Mon Sep 17 00:00:00 2001 From: April Hall Date: Wed, 5 Feb 2025 18:06:49 -0500 Subject: [PATCH] build: Install and configure ShadCN --- bun.lockb | Bin 170972 -> 170772 bytes components.json | 14 +++ package.json | 41 ++++--- src/app.css | 64 +++++++++-- src/app.html | 27 +---- src/lib/components/channel.svelte | 20 ++++ src/lib/components/mainLayout.svelte | 40 +++++++ src/lib/components/ui/badge/badge.svelte | 13 +++ src/lib/components/ui/badge/index.ts | 19 ++++ src/lib/components/ui/button/button.svelte | 18 +++ src/lib/components/ui/button/index.ts | 48 ++++++++ .../components/ui/card/card-content.svelte | 13 +++ .../ui/card/card-description.svelte | 13 +++ src/lib/components/ui/card/card-footer.svelte | 13 +++ src/lib/components/ui/card/card-header.svelte | 13 +++ src/lib/components/ui/card/card-title.svelte | 17 +++ src/lib/components/ui/card/card.svelte | 21 ++++ src/lib/components/ui/card/index.ts | 24 ++++ .../dropdown-menu-checkbox-item.svelte | 34 ++++++ .../dropdown-menu-content.svelte | 22 ++++ .../dropdown-menu/dropdown-menu-item.svelte | 30 +++++ .../dropdown-menu/dropdown-menu-label.svelte | 16 +++ .../dropdown-menu-radio-group.svelte | 11 ++ .../dropdown-menu-radio-item.svelte | 34 ++++++ .../dropdown-menu-separator.svelte | 11 ++ .../dropdown-menu-shortcut.svelte | 13 +++ .../dropdown-menu-sub-content.svelte | 25 +++++ .../dropdown-menu-sub-trigger.svelte | 31 +++++ src/lib/components/ui/dropdown-menu/index.ts | 48 ++++++++ src/lib/components/ui/input/index.ts | 29 +++++ src/lib/components/ui/input/input.svelte | 41 +++++++ src/lib/components/ui/sheet/index.ts | 106 ++++++++++++++++++ .../components/ui/sheet/sheet-content.svelte | 37 ++++++ .../ui/sheet/sheet-description.svelte | 13 +++ .../components/ui/sheet/sheet-footer.svelte | 13 +++ .../components/ui/sheet/sheet-header.svelte | 13 +++ .../components/ui/sheet/sheet-overlay.svelte | 20 ++++ .../components/ui/sheet/sheet-portal.svelte | 13 +++ .../components/ui/sheet/sheet-title.svelte | 13 +++ src/lib/server/db/index.ts | 15 +-- src/lib/utils.ts | 53 +++++++++ src/routes/+layout.svelte | 7 +- src/routes/+page.svelte | 62 ---------- svelte.config.js | 5 +- tailwind.config.ts | 92 +++++++++------ 45 files changed, 1062 insertions(+), 163 deletions(-) create mode 100644 components.json create mode 100644 src/lib/components/channel.svelte create mode 100644 src/lib/components/mainLayout.svelte create mode 100644 src/lib/components/ui/badge/badge.svelte create mode 100644 src/lib/components/ui/badge/index.ts create mode 100644 src/lib/components/ui/button/button.svelte create mode 100644 src/lib/components/ui/button/index.ts create mode 100644 src/lib/components/ui/card/card-content.svelte create mode 100644 src/lib/components/ui/card/card-description.svelte create mode 100644 src/lib/components/ui/card/card-footer.svelte create mode 100644 src/lib/components/ui/card/card-header.svelte create mode 100644 src/lib/components/ui/card/card-title.svelte create mode 100644 src/lib/components/ui/card/card.svelte create mode 100644 src/lib/components/ui/card/index.ts create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts create mode 100644 src/lib/components/ui/input/index.ts create mode 100644 src/lib/components/ui/input/input.svelte create mode 100644 src/lib/components/ui/sheet/index.ts create mode 100644 src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 src/lib/utils.ts diff --git a/bun.lockb b/bun.lockb index b4d6c32b7097a47ce89d6eb010567474aed52520..66ef4ee3c5e9e869f62d11e659367b6c870b34d3 100755 GIT binary patch delta 47041 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

m(d+18@rkts(C~ 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°i! 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 delta 46927 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 diff --git a/components.json b/components.json new file mode 100644 index 0000000..20958c8 --- /dev/null +++ b/components.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "style": "new-york", + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app.css", + "baseColor": "stone" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils" + }, + "typescript": true +} diff --git a/package.json b/package.json index fd4f8d2..314149e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "chatapp", + "name": "svchat", "private": true, "version": "0.0.1", "type": "module", @@ -7,38 +7,43 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "start": "PORT=3005 tsm ./prodServer.ts", + "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "format": "prettier --write .", "lint": "prettier --check . && eslint ." }, "devDependencies": { - "@eslint/compat": "^1.2.3", - "@sveltejs/adapter-node": "^5.2.11", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^4.0.0", + "@eslint/compat": "^1.2.5", + "@eslint/js": "^9.18.0", + "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", "autoprefixer": "^10.4.20", - "eslint": "^9.7.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.36.0", - "globals": "^15.0.0", - "prettier": "^3.3.2", - "prettier-plugin-svelte": "^3.2.6", - "prettier-plugin-tailwindcss": "^0.6.5", + "bits-ui": "^0.22.0", + "clsx": "^2.1.1", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-svelte": "^2.46.1", + "globals": "^15.14.0", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.10", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "tailwindcss": "^3.4.9", + "tailwind-merge": "^3.0.1", + "tailwind-variants": "^0.3.1", + "tailwindcss": "^3.4.17", "typescript": "^5.0.0", - "typescript-eslint": "^8.0.0", - "vite": "^5.4.11" + "typescript-eslint": "^8.20.0", + "vite": "^6.0.0" }, "dependencies": { + "lucide-svelte": "^0.474.0", + "socket.io": "^4.8.1", "@types/express": "^5.0.0", "cassandra-driver": "^4.7.2", - "daisyui": "^4.12.23", "express": "^4.21.2", - "socket.io": "^4.8.1", "socket.io-client": "^4.8.1", "tsm": "^2.3.0", "uuid": "^11.0.4" diff --git a/src/app.css b/src/app.css index 3f9d957..6746b56 100644 --- a/src/app.css +++ b/src/app.css @@ -1,10 +1,58 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities'; +@tailwind base; +@tailwind components; +@tailwind utilities; -.abs-centered { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 142.1 76.2% 36.3%; + --primary-foreground: 355.7 100% 97.3%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 72.22% 50.59%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 142.1 76.2% 36.3%; + --radius: 0.3rem; + } + .dark { + --background: 20 14.3% 4.1%; + --foreground: 0 0% 95%; + --card: 24 9.8% 10%; + --card-foreground: 0 0% 95%; + --popover: 0 0% 9%; + --popover-foreground: 0 0% 95%; + --primary: 142.1 70.6% 45.3%; + --primary-foreground: 144.9 80.4% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 15%; + --muted-foreground: 240 5% 64.9%; + --accent: 12 6.5% 15.1%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 142.4 71.8% 29.2%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } } diff --git a/src/app.html b/src/app.html index 7c9830c..84ffad1 100644 --- a/src/app.html +++ b/src/app.html @@ -1,31 +1,12 @@ - - + + %sveltekit.head% - - -

%sveltekit.body%
+ +
%sveltekit.body%
diff --git a/src/lib/components/channel.svelte b/src/lib/components/channel.svelte new file mode 100644 index 0000000..dd9f7f0 --- /dev/null +++ b/src/lib/components/channel.svelte @@ -0,0 +1,20 @@ + + + + {#if unread} + + {:else} + + {/if} + {channelName} + diff --git a/src/lib/components/mainLayout.svelte b/src/lib/components/mainLayout.svelte new file mode 100644 index 0000000..b302c9e --- /dev/null +++ b/src/lib/components/mainLayout.svelte @@ -0,0 +1,40 @@ + + +
+ +
+
+
+

bello

+
+
+
+
+
diff --git a/src/lib/components/ui/badge/badge.svelte b/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 0000000..c2eae1c --- /dev/null +++ b/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/badge/index.ts b/src/lib/components/ui/badge/index.ts new file mode 100644 index 0000000..502ad3e --- /dev/null +++ b/src/lib/components/ui/badge/index.ts @@ -0,0 +1,19 @@ +import { type VariantProps, tv } from 'tailwind-variants'; + +export { default as Badge } from './badge.svelte'; +export const badgeVariants = tv({ + base: 'focus:ring-ring inline-flex select-none items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2', + variants: { + variant: { + default: 'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent shadow', + secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent', + destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent shadow', + outline: 'text-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, +}); + +export type Variant = VariantProps['variant']; diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..2e4b156 --- /dev/null +++ b/src/lib/components/ui/button/button.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..affba83 --- /dev/null +++ b/src/lib/components/ui/button/index.ts @@ -0,0 +1,48 @@ +import type { Button as ButtonPrimitive } from 'bits-ui'; +import { type VariantProps, tv } from 'tailwind-variants'; +import Root from './button.svelte'; + +const buttonVariants = tv({ + base: 'focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50', + variants: { + variant: { + default: 'bg-primary text-primary-foreground hover:bg-primary/90 shadow', + destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm', + outline: 'border-input bg-background hover:bg-accent hover:text-accent-foreground border shadow-sm', + secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-sm', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline', + }, + size: { + default: 'h-9 px-4 py-2', + sm: 'h-8 rounded-md px-3 text-xs', + lg: 'h-10 rounded-md px-8', + icon: 'h-9 w-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, +}); + +type Variant = VariantProps['variant']; +type Size = VariantProps['size']; + +type Props = ButtonPrimitive.Props & { + variant?: Variant; + size?: Size; +}; + +type Events = ButtonPrimitive.Events; + +export { + Root, + type Props, + type Events, + // + Root as Button, + type Props as ButtonProps, + type Events as ButtonEvents, + buttonVariants, +}; diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..e2dce55 --- /dev/null +++ b/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..72ff678 --- /dev/null +++ b/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,13 @@ + + +

+ +

diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..3d6a4b6 --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..c9822c5 --- /dev/null +++ b/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..bed9ca4 --- /dev/null +++ b/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,17 @@ + + + + + diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..2b8296a --- /dev/null +++ b/src/lib/components/ui/card/card.svelte @@ -0,0 +1,21 @@ + + + +
+ +
diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..1432839 --- /dev/null +++ b/src/lib/components/ui/card/index.ts @@ -0,0 +1,24 @@ +import Root from './card.svelte'; +import Content from './card-content.svelte'; +import Description from './card-description.svelte'; +import Footer from './card-footer.svelte'; +import Header from './card-header.svelte'; +import Title from './card-title.svelte'; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, +}; + +export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..b976af4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..a9f8d73 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..ef74d45 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,30 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..37647b6 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..06a8337 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..acfdb3a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..0d46384 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..454af6c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..1955384 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..7e4bc9d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,31 @@ + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..22001e4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,48 @@ +import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; +import Item from './dropdown-menu-item.svelte'; +import Label from './dropdown-menu-label.svelte'; +import Content from './dropdown-menu-content.svelte'; +import Shortcut from './dropdown-menu-shortcut.svelte'; +import RadioItem from './dropdown-menu-radio-item.svelte'; +import Separator from './dropdown-menu-separator.svelte'; +import RadioGroup from './dropdown-menu-radio-group.svelte'; +import SubContent from './dropdown-menu-sub-content.svelte'; +import SubTrigger from './dropdown-menu-sub-trigger.svelte'; +import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; + +export { + Sub, + Root, + Item, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as DropdownMenu, + Sub as DropdownMenuSub, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + Group as DropdownMenuGroup, + Content as DropdownMenuContent, + Trigger as DropdownMenuTrigger, + Shortcut as DropdownMenuShortcut, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + RadioGroup as DropdownMenuRadioGroup, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + CheckboxItem as DropdownMenuCheckboxItem, +}; diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..1d669f9 --- /dev/null +++ b/src/lib/components/ui/input/index.ts @@ -0,0 +1,29 @@ +import Root from './input.svelte'; + +export type FormInputEvent = T & { + currentTarget: EventTarget & HTMLInputElement; +}; +export type InputEvents = { + blur: FormInputEvent; + change: FormInputEvent; + click: FormInputEvent; + focus: FormInputEvent; + focusin: FormInputEvent; + focusout: FormInputEvent; + keydown: FormInputEvent; + keypress: FormInputEvent; + keyup: FormInputEvent; + mouseover: FormInputEvent; + mouseenter: FormInputEvent; + mouseleave: FormInputEvent; + mousemove: FormInputEvent; + paste: FormInputEvent; + input: FormInputEvent; + wheel: FormInputEvent; +}; + +export { + Root, + // + Root as Input, +}; diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..ef65e2a --- /dev/null +++ b/src/lib/components/ui/input/input.svelte @@ -0,0 +1,41 @@ + + + diff --git a/src/lib/components/ui/sheet/index.ts b/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..ffd7444 --- /dev/null +++ b/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,106 @@ +import { Dialog as SheetPrimitive } from 'bits-ui'; +import { type VariantProps, tv } from 'tailwind-variants'; + +import Portal from './sheet-portal.svelte'; +import Overlay from './sheet-overlay.svelte'; +import Content from './sheet-content.svelte'; +import Header from './sheet-header.svelte'; +import Footer from './sheet-footer.svelte'; +import Title from './sheet-title.svelte'; +import Description from './sheet-description.svelte'; + +const Root = SheetPrimitive.Root; +const Close = SheetPrimitive.Close; +const Trigger = SheetPrimitive.Trigger; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; + +export const sheetVariants = tv({ + base: 'bg-background fixed z-50 gap-4 p-6 shadow-lg', + variants: { + side: { + top: 'inset-x-0 top-0 border-b ', + bottom: 'inset-x-0 bottom-0 border-t', + left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm', + right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm', + }, + }, + defaultVariants: { + side: 'right', + }, +}); + +export const sheetTransitions = { + top: { + in: { + y: '-100%', + duration: 500, + opacity: 1, + }, + out: { + y: '-100%', + duration: 300, + opacity: 1, + }, + }, + bottom: { + in: { + y: '100%', + duration: 500, + opacity: 1, + }, + out: { + y: '100%', + duration: 300, + opacity: 1, + }, + }, + left: { + in: { + x: '-100%', + duration: 500, + opacity: 1, + }, + out: { + x: '-100%', + duration: 300, + opacity: 1, + }, + }, + right: { + in: { + x: '100%', + duration: 500, + opacity: 1, + }, + out: { + x: '100%', + duration: 300, + opacity: 1, + }, + }, +}; + +export type Side = VariantProps['side']; diff --git a/src/lib/components/ui/sheet/sheet-content.svelte b/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..1937f26 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,37 @@ + + + + + + + + + Close + + + diff --git a/src/lib/components/ui/sheet/sheet-description.svelte b/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..ba17548 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/sheet/sheet-footer.svelte b/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..c625327 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/sheet/sheet-header.svelte b/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..ac2ca13 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/sheet/sheet-overlay.svelte b/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..52b450a --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-portal.svelte b/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 0000000..e6cc867 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/sheet/sheet-title.svelte b/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..b8d0128 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index 2b7640c..5edf507 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -1,17 +1,5 @@ import cassandra from 'cassandra-driver'; -function reverseArray(array: cassandra.types.Row[]) { - let left = null; - let right = null; - const length = array.length; - for (left = 0, right = length - 1; left < right; left += 1, right -= 1) { - const temporary = array[left]; - array[left] = array[right]; - array[right] = temporary; - } - return array; -} - async function createChannel(client: cassandra.Client, channelName: string) { try { await client.execute(` @@ -40,7 +28,7 @@ async function storeMessage(client: cassandra.Client, channelName: string, conte } } -async function getMessages(client: cassandra.Client, channelName: string, limit: number) { +async function getMessages(client: cassandra.Client, channelName: string, limit: number): Promise { try { const res = await client.execute( `SELECT * FROM channels.channel_${channelName} WHERE channel_name = '${channelName}' ORDER BY timestamp DESC LIMIT ${limit}`, @@ -49,6 +37,7 @@ async function getMessages(client: cassandra.Client, channelName: string, limit: } catch (e) { // @ts-expect-error I don't like this thing yelling at me console.log(`Error fetching messages: ${e.message}`); + return; } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..362d630 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,53 @@ +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, + }; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 34832d6..dd9063f 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,6 +1,11 @@ -{@render children()} + + {@render children()} + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 96a1efd..e69de29 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,62 +0,0 @@ - - -{#snippet message(messages: TypeMessage[])} - {#each messages as message} - - {/each} -{/snippet} - -
-
-

SVChat

-
-
-
- {@render message(log)} - {@render message(data.messages)} -
-
- - -
-
diff --git a/svelte.config.js b/svelte.config.js index a9692c1..4f546cd 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-node'; +import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ @@ -12,6 +12,9 @@ const config = { // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), + alias: { + '@/*': './path/to/lib/*', + }, }, }; diff --git a/tailwind.config.ts b/tailwind.config.ts index 108883c..7c1b0d9 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,46 +1,64 @@ +import { fontFamily } from 'tailwindcss/defaultTheme'; import type { Config } from 'tailwindcss'; -import daisyui from 'daisyui'; -export default { +const config: Config = { + darkMode: ['class'], content: ['./src/**/*.{html,js,svelte,ts}'], - plugins: [daisyui], + safelist: ['dark'], theme: { - fontSize: { - sm: '0.750rem', - base: '1rem', - xl: '1.333rem', - '2xl': '1.777rem', - '3xl': '2.369rem', - '4xl': '3.158rem', - '5xl': '4.210rem', + container: { + center: true, + padding: '2rem', + screens: { + '2xl': '1400px', + }, }, - fontFamily: { - heading: 'IBM Plex Sans', - body: 'IBM Plex Sans', - }, - fontWeight: { - normal: '400', - bold: '700', - }, - }, - daisyui: { - themes: [ - { - light: { - "primary": "#5fb979", - "secondary": "#9fdfb3", - "accent": "#66db89", - "neutral": "#1b3222", - "base-100": "#f2f8f4", + 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) / )', }, - dark: { - "primary": "#46a05f", - "secondary": "#206034", - "accent": "#249947", - "neutral": "#1b3222", - "base-100": "#2D2D2D", + 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], + }, + }, }, -} satisfies Config; +}; + +export default config;