Spaces:
Runtime error
Runtime error
Adrien Denat
commited on
Commit
•
b2387f6
1
Parent(s):
ffa4f55
Add tailwind prettier (#123)
Browse files* add tailwind-prettier plugin
* lint all project files
- .prettierrc +1 -1
- package-lock.json +75 -0
- package.json +1 -0
- src/app.html +1 -1
- src/lib/components/CodeBlock.svelte +2 -2
- src/lib/components/CopyToClipBoardBtn.svelte +1 -1
- src/lib/components/MobileNav.svelte +7 -7
- src/lib/components/NavMenu.svelte +13 -13
- src/lib/components/ScrollToBottomBtn.svelte +1 -1
- src/lib/components/StopGeneratingBtn.svelte +3 -3
- src/lib/components/Toast.svelte +2 -2
- src/lib/components/Tooltip.svelte +1 -1
- src/lib/components/chat/ChatInput.svelte +3 -3
- src/lib/components/chat/ChatIntroduction.svelte +13 -13
- src/lib/components/chat/ChatMessage.svelte +5 -5
- src/lib/components/chat/ChatMessages.svelte +3 -3
- src/lib/components/chat/ChatWindow.svelte +6 -6
- src/routes/+error.svelte +4 -4
- src/routes/+layout.svelte +2 -2
- src/routes/+page.svelte +3 -3
- src/routes/privacy/+page.svelte +2 -2
- src/styles/main.css +2 -2
.prettierrc
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"useTabs": true,
|
3 |
"trailingComma": "es5",
|
4 |
"printWidth": 100,
|
5 |
-
"plugins": ["prettier-plugin-svelte"],
|
6 |
"pluginSearchDirs": ["."],
|
7 |
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
8 |
}
|
|
|
2 |
"useTabs": true,
|
3 |
"trailingComma": "es5",
|
4 |
"printWidth": 100,
|
5 |
+
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
|
6 |
"pluginSearchDirs": ["."],
|
7 |
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
8 |
}
|
package-lock.json
CHANGED
@@ -34,6 +34,7 @@
|
|
34 |
"eslint-plugin-svelte3": "^4.0.0",
|
35 |
"prettier": "^2.8.0",
|
36 |
"prettier-plugin-svelte": "^2.8.1",
|
|
|
37 |
"svelte": "^3.54.0",
|
38 |
"svelte-check": "^3.0.1",
|
39 |
"tslib": "^2.4.1",
|
@@ -3135,6 +3136,80 @@
|
|
3135 |
"svelte": "^3.2.0"
|
3136 |
}
|
3137 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3138 |
"node_modules/punycode": {
|
3139 |
"version": "2.3.0",
|
3140 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
|
|
34 |
"eslint-plugin-svelte3": "^4.0.0",
|
35 |
"prettier": "^2.8.0",
|
36 |
"prettier-plugin-svelte": "^2.8.1",
|
37 |
+
"prettier-plugin-tailwindcss": "^0.2.7",
|
38 |
"svelte": "^3.54.0",
|
39 |
"svelte-check": "^3.0.1",
|
40 |
"tslib": "^2.4.1",
|
|
|
3136 |
"svelte": "^3.2.0"
|
3137 |
}
|
3138 |
},
|
3139 |
+
"node_modules/prettier-plugin-tailwindcss": {
|
3140 |
+
"version": "0.2.7",
|
3141 |
+
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.7.tgz",
|
3142 |
+
"integrity": "sha512-jQopIOgjLpX+y8HeD56XZw7onupRTC0cw7eKKUimI7vhjkPF5/1ltW5LyqaPtSyc8HvEpvNZsvvsGFa2qpa59w==",
|
3143 |
+
"dev": true,
|
3144 |
+
"engines": {
|
3145 |
+
"node": ">=12.17.0"
|
3146 |
+
},
|
3147 |
+
"peerDependencies": {
|
3148 |
+
"@ianvs/prettier-plugin-sort-imports": "*",
|
3149 |
+
"@prettier/plugin-php": "*",
|
3150 |
+
"@prettier/plugin-pug": "*",
|
3151 |
+
"@shopify/prettier-plugin-liquid": "*",
|
3152 |
+
"@shufo/prettier-plugin-blade": "*",
|
3153 |
+
"@trivago/prettier-plugin-sort-imports": "*",
|
3154 |
+
"prettier": ">=2.2.0",
|
3155 |
+
"prettier-plugin-astro": "*",
|
3156 |
+
"prettier-plugin-css-order": "*",
|
3157 |
+
"prettier-plugin-import-sort": "*",
|
3158 |
+
"prettier-plugin-jsdoc": "*",
|
3159 |
+
"prettier-plugin-organize-attributes": "*",
|
3160 |
+
"prettier-plugin-organize-imports": "*",
|
3161 |
+
"prettier-plugin-style-order": "*",
|
3162 |
+
"prettier-plugin-svelte": "*",
|
3163 |
+
"prettier-plugin-twig-melody": "*"
|
3164 |
+
},
|
3165 |
+
"peerDependenciesMeta": {
|
3166 |
+
"@ianvs/prettier-plugin-sort-imports": {
|
3167 |
+
"optional": true
|
3168 |
+
},
|
3169 |
+
"@prettier/plugin-php": {
|
3170 |
+
"optional": true
|
3171 |
+
},
|
3172 |
+
"@prettier/plugin-pug": {
|
3173 |
+
"optional": true
|
3174 |
+
},
|
3175 |
+
"@shopify/prettier-plugin-liquid": {
|
3176 |
+
"optional": true
|
3177 |
+
},
|
3178 |
+
"@shufo/prettier-plugin-blade": {
|
3179 |
+
"optional": true
|
3180 |
+
},
|
3181 |
+
"@trivago/prettier-plugin-sort-imports": {
|
3182 |
+
"optional": true
|
3183 |
+
},
|
3184 |
+
"prettier-plugin-astro": {
|
3185 |
+
"optional": true
|
3186 |
+
},
|
3187 |
+
"prettier-plugin-css-order": {
|
3188 |
+
"optional": true
|
3189 |
+
},
|
3190 |
+
"prettier-plugin-import-sort": {
|
3191 |
+
"optional": true
|
3192 |
+
},
|
3193 |
+
"prettier-plugin-jsdoc": {
|
3194 |
+
"optional": true
|
3195 |
+
},
|
3196 |
+
"prettier-plugin-organize-attributes": {
|
3197 |
+
"optional": true
|
3198 |
+
},
|
3199 |
+
"prettier-plugin-organize-imports": {
|
3200 |
+
"optional": true
|
3201 |
+
},
|
3202 |
+
"prettier-plugin-style-order": {
|
3203 |
+
"optional": true
|
3204 |
+
},
|
3205 |
+
"prettier-plugin-svelte": {
|
3206 |
+
"optional": true
|
3207 |
+
},
|
3208 |
+
"prettier-plugin-twig-melody": {
|
3209 |
+
"optional": true
|
3210 |
+
}
|
3211 |
+
}
|
3212 |
+
},
|
3213 |
"node_modules/punycode": {
|
3214 |
"version": "2.3.0",
|
3215 |
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
package.json
CHANGED
@@ -24,6 +24,7 @@
|
|
24 |
"eslint-plugin-svelte3": "^4.0.0",
|
25 |
"prettier": "^2.8.0",
|
26 |
"prettier-plugin-svelte": "^2.8.1",
|
|
|
27 |
"svelte": "^3.54.0",
|
28 |
"svelte-check": "^3.0.1",
|
29 |
"tslib": "^2.4.1",
|
|
|
24 |
"eslint-plugin-svelte3": "^4.0.0",
|
25 |
"prettier": "^2.8.0",
|
26 |
"prettier-plugin-svelte": "^2.8.1",
|
27 |
+
"prettier-plugin-tailwindcss": "^0.2.7",
|
28 |
"svelte": "^3.54.0",
|
29 |
"svelte-check": "^3.0.1",
|
30 |
"tslib": "^2.4.1",
|
src/app.html
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
</script>
|
16 |
%sveltekit.head%
|
17 |
</head>
|
18 |
-
<body data-sveltekit-preload-data="hover" class="dark:bg-gray-900
|
19 |
<div class="contents h-full">%sveltekit.body%</div>
|
20 |
</body>
|
21 |
</html>
|
|
|
15 |
</script>
|
16 |
%sveltekit.head%
|
17 |
</head>
|
18 |
+
<body data-sveltekit-preload-data="hover" class="h-full dark:bg-gray-900">
|
19 |
<div class="contents h-full">%sveltekit.body%</div>
|
20 |
</body>
|
21 |
</html>
|
src/lib/components/CodeBlock.svelte
CHANGED
@@ -15,9 +15,9 @@
|
|
15 |
});
|
16 |
</script>
|
17 |
|
18 |
-
<div class="group relative rounded-lg
|
19 |
<pre
|
20 |
-
class="overflow-auto
|
21 |
class="language-{lang}">{@html highlightedCode || code.replaceAll("<", "<")}</code
|
22 |
></pre>
|
23 |
<CopyToClipBoardBtn
|
|
|
15 |
});
|
16 |
</script>
|
17 |
|
18 |
+
<div class="group relative my-4 rounded-lg">
|
19 |
<pre
|
20 |
+
class="scrollbar-custom overflow-auto px-5 scrollbar-thumb-gray-500 hover:scrollbar-thumb-gray-400 dark:scrollbar-thumb-white/10 dark:hover:scrollbar-thumb-white/20"><code
|
21 |
class="language-{lang}">{@html highlightedCode || code.replaceAll("<", "<")}</code
|
22 |
></pre>
|
23 |
<CopyToClipBoardBtn
|
src/lib/components/CopyToClipBoardBtn.svelte
CHANGED
@@ -35,7 +35,7 @@
|
|
35 |
</script>
|
36 |
|
37 |
<button
|
38 |
-
class="btn
|
39 |
{!isSuccess && 'text-gray-200 dark:text-gray-200'}
|
40 |
{isSuccess && 'text-green-500'}
|
41 |
"
|
|
|
35 |
</script>
|
36 |
|
37 |
<button
|
38 |
+
class="btn rounded-lg border border-gray-200 px-2 py-2 text-sm shadow-sm transition-all hover:border-gray-300 active:shadow-inner dark:border-gray-600 dark:hover:border-gray-400 {classNames}
|
39 |
{!isSuccess && 'text-gray-200 dark:text-gray-200'}
|
40 |
{isSuccess && 'text-green-500'}
|
41 |
"
|
src/lib/components/MobileNav.svelte
CHANGED
@@ -30,29 +30,29 @@
|
|
30 |
</script>
|
31 |
|
32 |
<nav
|
33 |
-
class="
|
34 |
>
|
35 |
<button
|
36 |
type="button"
|
37 |
-
class="flex
|
38 |
on:click={() => dispatch("toggle", true)}
|
39 |
aria-label="Open menu"
|
40 |
bind:this={openEl}><CarbonTextAlignJustify /></button
|
41 |
>
|
42 |
-
<span class="px-4
|
43 |
-
<a href={base || "/"} class="flex
|
44 |
><CarbonAdd /></a
|
45 |
>
|
46 |
</nav>
|
47 |
<nav
|
48 |
-
class="fixed inset-0 z-50 grid grid-rows-[auto,auto,1fr,auto]
|
49 |
? 'block'
|
50 |
: 'hidden'}"
|
51 |
>
|
52 |
-
<div class="flex items-center px-4
|
53 |
<button
|
54 |
type="button"
|
55 |
-
class="
|
56 |
on:click={() => dispatch("toggle", false)}
|
57 |
aria-label="Close menu"
|
58 |
bind:this={closeEl}><CarbonClose /></button
|
|
|
30 |
</script>
|
31 |
|
32 |
<nav
|
33 |
+
class="flex h-12 items-center justify-between border-b bg-gray-50 px-4 dark:border-gray-800 dark:bg-gray-800/70 md:hidden"
|
34 |
>
|
35 |
<button
|
36 |
type="button"
|
37 |
+
class="-ml-3 flex h-9 w-9 shrink-0 items-center justify-center"
|
38 |
on:click={() => dispatch("toggle", true)}
|
39 |
aria-label="Open menu"
|
40 |
bind:this={openEl}><CarbonTextAlignJustify /></button
|
41 |
>
|
42 |
+
<span class="truncate px-4">{title}</span>
|
43 |
+
<a href={base || "/"} class="-mr-3 flex h-9 w-9 shrink-0 items-center justify-center"
|
44 |
><CarbonAdd /></a
|
45 |
>
|
46 |
</nav>
|
47 |
<nav
|
48 |
+
class="fixed inset-0 z-50 grid max-h-screen grid-cols-1 grid-rows-[auto,auto,1fr,auto] bg-white bg-gradient-to-l from-gray-50 dark:bg-gray-900 dark:from-gray-800/30 {isOpen
|
49 |
? 'block'
|
50 |
: 'hidden'}"
|
51 |
>
|
52 |
+
<div class="flex h-12 items-center px-4">
|
53 |
<button
|
54 |
type="button"
|
55 |
+
class="-mr-3 ml-auto flex h-9 w-9 items-center justify-center"
|
56 |
on:click={() => dispatch("toggle", false)}
|
57 |
aria-label="Close menu"
|
58 |
bind:this={closeEl}><CarbonClose /></button
|
src/lib/components/NavMenu.svelte
CHANGED
@@ -21,26 +21,26 @@
|
|
21 |
}> = [];
|
22 |
</script>
|
23 |
|
24 |
-
<div class="flex-none
|
25 |
-
<a class="rounded-xl
|
26 |
<Logo classNames="mr-1 text-3xl" />
|
27 |
HuggingChat
|
28 |
</a>
|
29 |
<a
|
30 |
href={base || "/"}
|
31 |
-
class="flex border py-0.5
|
32 |
>
|
33 |
New Chat
|
34 |
</a>
|
35 |
</div>
|
36 |
<div
|
37 |
-
class="flex flex-col overflow-y-auto
|
38 |
>
|
39 |
{#each conversations as conv}
|
40 |
<a
|
41 |
data-sveltekit-noscroll
|
42 |
href="{base}/conversation/{conv.id}"
|
43 |
-
class="group
|
44 |
$page.params.id
|
45 |
? 'bg-gray-100 dark:bg-gray-700'
|
46 |
: ''}"
|
@@ -49,34 +49,34 @@
|
|
49 |
|
50 |
<button
|
51 |
type="button"
|
52 |
-
class="flex
|
53 |
title="Share conversation"
|
54 |
on:click|preventDefault={() =>
|
55 |
dispatch("shareConversation", { id: conv.id, title: conv.title })}
|
56 |
>
|
57 |
-
<CarbonExport class="text-gray-400
|
58 |
</button>
|
59 |
|
60 |
<button
|
61 |
type="button"
|
62 |
-
class="flex
|
63 |
title="Delete conversation"
|
64 |
on:click|preventDefault={() => dispatch("deleteConversation", conv.id)}
|
65 |
>
|
66 |
<CarbonTrashCan
|
67 |
-
class="text-gray-400
|
68 |
/>
|
69 |
</button>
|
70 |
</a>
|
71 |
{/each}
|
72 |
</div>
|
73 |
<div
|
74 |
-
class="flex flex-col
|
75 |
>
|
76 |
<button
|
77 |
on:click={switchTheme}
|
78 |
type="button"
|
79 |
-
class="group
|
80 |
>
|
81 |
Theme
|
82 |
</button>
|
@@ -84,13 +84,13 @@
|
|
84 |
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions"
|
85 |
target="_blank"
|
86 |
rel="noreferrer"
|
87 |
-
class="group
|
88 |
>
|
89 |
Feedback
|
90 |
</a>
|
91 |
<a
|
92 |
href="{base}/privacy"
|
93 |
-
class="group
|
94 |
>
|
95 |
About & Privacy
|
96 |
</a>
|
|
|
21 |
}> = [];
|
22 |
</script>
|
23 |
|
24 |
+
<div class="sticky top-0 flex flex-none items-center justify-between px-3 py-3.5 max-sm:pt-0">
|
25 |
+
<a class="flex items-center rounded-xl text-lg font-semibold" href="{PUBLIC_ORIGIN}{base}/">
|
26 |
<Logo classNames="mr-1 text-3xl" />
|
27 |
HuggingChat
|
28 |
</a>
|
29 |
<a
|
30 |
href={base || "/"}
|
31 |
+
class="flex rounded-lg border bg-white px-2 py-0.5 text-center shadow-sm hover:shadow-none dark:border-gray-600 dark:bg-gray-700"
|
32 |
>
|
33 |
New Chat
|
34 |
</a>
|
35 |
</div>
|
36 |
<div
|
37 |
+
class="scrollbar-custom flex flex-col gap-1 overflow-y-auto rounded-r-xl bg-gradient-to-l from-gray-50 px-3 pb-3 pt-2 dark:from-gray-800/30"
|
38 |
>
|
39 |
{#each conversations as conv}
|
40 |
<a
|
41 |
data-sveltekit-noscroll
|
42 |
href="{base}/conversation/{conv.id}"
|
43 |
+
class="group flex h-11 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 {conv.id ===
|
44 |
$page.params.id
|
45 |
? 'bg-gray-100 dark:bg-gray-700'
|
46 |
: ''}"
|
|
|
49 |
|
50 |
<button
|
51 |
type="button"
|
52 |
+
class="flex h-5 w-5 items-center justify-center rounded md:hidden md:group-hover:flex"
|
53 |
title="Share conversation"
|
54 |
on:click|preventDefault={() =>
|
55 |
dispatch("shareConversation", { id: conv.id, title: conv.title })}
|
56 |
>
|
57 |
+
<CarbonExport class="text-xs text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" />
|
58 |
</button>
|
59 |
|
60 |
<button
|
61 |
type="button"
|
62 |
+
class="flex h-5 w-5 items-center justify-center rounded md:hidden md:group-hover:flex"
|
63 |
title="Delete conversation"
|
64 |
on:click|preventDefault={() => dispatch("deleteConversation", conv.id)}
|
65 |
>
|
66 |
<CarbonTrashCan
|
67 |
+
class="text-xs text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"
|
68 |
/>
|
69 |
</button>
|
70 |
</a>
|
71 |
{/each}
|
72 |
</div>
|
73 |
<div
|
74 |
+
class="mt-0.5 flex flex-col gap-2 rounded-r-xl bg-gradient-to-l from-gray-50 p-3 text-sm dark:from-gray-800/30"
|
75 |
>
|
76 |
<button
|
77 |
on:click={switchTheme}
|
78 |
type="button"
|
79 |
+
class="group flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
80 |
>
|
81 |
Theme
|
82 |
</button>
|
|
|
84 |
href="https://huggingface.co/spaces/huggingchat/chat-ui/discussions"
|
85 |
target="_blank"
|
86 |
rel="noreferrer"
|
87 |
+
class="group flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
88 |
>
|
89 |
Feedback
|
90 |
</a>
|
91 |
<a
|
92 |
href="{base}/privacy"
|
93 |
+
class="group flex h-9 flex-none items-center gap-1.5 rounded-lg pl-3 pr-2 text-gray-500 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700"
|
94 |
>
|
95 |
About & Privacy
|
96 |
</a>
|
src/lib/components/ScrollToBottomBtn.svelte
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
<button
|
29 |
transition:fade={{ duration: 150 }}
|
30 |
on:click={() => scrollNode.scrollTo({ top: scrollNode.scrollHeight, behavior: "smooth" })}
|
31 |
-
class="btn absolute flex
|
32 |
><IconChevron classNames="mt-[2px]" /></button
|
33 |
>
|
34 |
{/if}
|
|
|
28 |
<button
|
29 |
transition:fade={{ duration: 150 }}
|
30 |
on:click={() => scrollNode.scrollTo({ top: scrollNode.scrollHeight, behavior: "smooth" })}
|
31 |
+
class="btn absolute flex h-[41px] w-[41px] rounded-full border bg-white shadow-md transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:shadow-gray-950 dark:hover:bg-gray-600 {className}"
|
32 |
><IconChevron classNames="mt-[2px]" /></button
|
33 |
>
|
34 |
{/if}
|
src/lib/components/StopGeneratingBtn.svelte
CHANGED
@@ -8,10 +8,10 @@
|
|
8 |
<button
|
9 |
type="button"
|
10 |
on:click
|
11 |
-
class="absolute
|
12 |
{className}
|
13 |
-
{visible ? 'opacity-100
|
14 |
"
|
15 |
>
|
16 |
-
<CarbonPause class="
|
17 |
</button>
|
|
|
8 |
<button
|
9 |
type="button"
|
10 |
on:click
|
11 |
+
class="btn absolute flex rounded-lg border bg-white px-3 py-1 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:bg-gray-600
|
12 |
{className}
|
13 |
+
{visible ? 'visible opacity-100' : 'invisible opacity-0'}
|
14 |
"
|
15 |
>
|
16 |
+
<CarbonPause class="-ml-1 mr-1 h-[1.25rem] w-[1.1875rem] text-gray-400" /> Stop generating
|
17 |
</button>
|
src/lib/components/Toast.svelte
CHANGED
@@ -8,10 +8,10 @@
|
|
8 |
|
9 |
<div
|
10 |
transition:fade={{ duration: 300 }}
|
11 |
-
class="fixed right-0 top-12
|
12 |
>
|
13 |
<div
|
14 |
-
class="flex items-center bg-white/90
|
15 |
>
|
16 |
<IconDazzled classNames="text-2xl mr-2" />
|
17 |
<h2 class="font-semibold">{message}</h2>
|
|
|
8 |
|
9 |
<div
|
10 |
transition:fade={{ duration: 300 }}
|
11 |
+
class="pointer-events-none fixed right-0 top-12 z-20 bg-gradient-to-bl from-red-500/20 via-red-500/0 to-red-500/0 pb-36 pl-36 pr-2 pt-2 md:top-0 md:pr-8 md:pt-5"
|
12 |
>
|
13 |
<div
|
14 |
+
class="pointer-events-auto flex items-center rounded-full bg-white/90 px-3 py-1 shadow-sm dark:bg-gray-900/80"
|
15 |
>
|
16 |
<IconDazzled classNames="text-2xl mr-2" />
|
17 |
<h2 class="font-semibold">{message}</h2>
|
src/lib/components/Tooltip.svelte
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
|
7 |
<div
|
8 |
class="
|
9 |
-
pointer-events-none absolute rounded bg-black py-1
|
10 |
{position}
|
11 |
{classNames}
|
12 |
"
|
|
|
6 |
|
7 |
<div
|
8 |
class="
|
9 |
+
pointer-events-none absolute rounded bg-black px-2 py-1 font-normal leading-tight text-white shadow transition-opacity
|
10 |
{position}
|
11 |
{classNames}
|
12 |
"
|
src/lib/components/chat/ChatInput.svelte
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
export let disabled = false;
|
9 |
export let autofocus = false;
|
10 |
|
11 |
-
const dispatch = createEventDispatcher<{submit: void}>();
|
12 |
|
13 |
$: minHeight = `${1 + minRows * 1.5}em`;
|
14 |
$: maxHeight = maxRows ? `${1 + maxRows * 1.5}em` : `auto`;
|
@@ -24,7 +24,7 @@
|
|
24 |
let textareaElement: HTMLTextAreaElement;
|
25 |
</script>
|
26 |
|
27 |
-
<div class="relative
|
28 |
<pre
|
29 |
class="invisible py-3"
|
30 |
aria-hidden="true"
|
@@ -34,7 +34,7 @@
|
|
34 |
enterkeyhint="send"
|
35 |
tabindex="0"
|
36 |
rows="1"
|
37 |
-
class="absolute
|
38 |
bind:value
|
39 |
bind:this={textareaElement}
|
40 |
{disabled}
|
|
|
8 |
export let disabled = false;
|
9 |
export let autofocus = false;
|
10 |
|
11 |
+
const dispatch = createEventDispatcher<{ submit: void }>();
|
12 |
|
13 |
$: minHeight = `${1 + minRows * 1.5}em`;
|
14 |
$: maxHeight = maxRows ? `${1 + maxRows * 1.5}em` : `auto`;
|
|
|
24 |
let textareaElement: HTMLTextAreaElement;
|
25 |
</script>
|
26 |
|
27 |
+
<div class="relative min-w-0 flex-1">
|
28 |
<pre
|
29 |
class="invisible py-3"
|
30 |
aria-hidden="true"
|
|
|
34 |
enterkeyhint="send"
|
35 |
tabindex="0"
|
36 |
rows="1"
|
37 |
+
class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0 dark:bg-transparent"
|
38 |
bind:value
|
39 |
bind:this={textareaElement}
|
40 |
{disabled}
|
src/lib/components/chat/ChatIntroduction.svelte
CHANGED
@@ -13,14 +13,14 @@
|
|
13 |
const dispatch = createEventDispatcher<{ message: string }>();
|
14 |
</script>
|
15 |
|
16 |
-
<div class="grid lg:grid-cols-3
|
17 |
<div class="lg:col-span-1">
|
18 |
<div>
|
19 |
-
<div class="
|
20 |
<Logo classNames="mr-1 text-yellow-400 text-4xl" />
|
21 |
HuggingChat
|
22 |
<div
|
23 |
-
class="
|
24 |
>
|
25 |
v0
|
26 |
</div>
|
@@ -31,13 +31,13 @@
|
|
31 |
</div>
|
32 |
</div>
|
33 |
<div class="lg:col-span-2 lg:pl-24">
|
34 |
-
<div class="border dark:border-gray-800
|
35 |
<div class="p-3">
|
36 |
<div class="text-sm text-gray-600 dark:text-gray-400">Current Model</div>
|
37 |
<div class="font-semibold">{PUBLIC_MODEL_NAME}</div>
|
38 |
</div>
|
39 |
<div
|
40 |
-
class="flex items-center gap-5
|
41 |
>
|
42 |
<a
|
43 |
href="https://huggingface.co/{PUBLIC_MODEL_ID}"
|
@@ -45,7 +45,7 @@
|
|
45 |
rel="noreferrer"
|
46 |
class="flex items-center hover:underline"
|
47 |
>
|
48 |
-
<CarbonArrowUpRight class="
|
49 |
Model
|
50 |
<div class="max-sm:hidden"> page</div>
|
51 |
</a>
|
@@ -55,17 +55,17 @@
|
|
55 |
rel="noreferrer"
|
56 |
class="flex items-center hover:underline"
|
57 |
>
|
58 |
-
<CarbonArrowUpRight class="
|
59 |
Dataset
|
60 |
<div class="max-sm:hidden"> page</div>
|
61 |
</a>
|
62 |
<a
|
63 |
href="https://open-assistant.io/"
|
64 |
target="_blank"
|
65 |
-
class="flex items-center hover:underline
|
66 |
rel="noreferrer"
|
67 |
>
|
68 |
-
<CarbonEarth class="
|
69 |
Open Assistant Website
|
70 |
</a>
|
71 |
</div>
|
@@ -74,10 +74,10 @@
|
|
74 |
{#if PUBLIC_DISABLE_INTRO_TILES !== "true"}
|
75 |
<div class="lg:col-span-3 lg:mt-12">
|
76 |
<p class="mb-3 text-gray-600 dark:text-gray-300">Examples</p>
|
77 |
-
<div class="grid lg:grid-cols-3
|
78 |
<button
|
79 |
type="button"
|
80 |
-
class="
|
81 |
on:click={() =>
|
82 |
dispatch(
|
83 |
"message",
|
@@ -88,7 +88,7 @@
|
|
88 |
</button>
|
89 |
<button
|
90 |
type="button"
|
91 |
-
class="
|
92 |
on:click={() =>
|
93 |
dispatch(
|
94 |
"message",
|
@@ -99,7 +99,7 @@
|
|
99 |
</button>
|
100 |
<button
|
101 |
type="button"
|
102 |
-
class="
|
103 |
on:click={() => dispatch("message", "How do I make a delicious lemon cheesecake?")}
|
104 |
>
|
105 |
"Assist in a task"
|
|
|
13 |
const dispatch = createEventDispatcher<{ message: string }>();
|
14 |
</script>
|
15 |
|
16 |
+
<div class="my-auto grid gap-8 lg:grid-cols-3">
|
17 |
<div class="lg:col-span-1">
|
18 |
<div>
|
19 |
+
<div class="mb-3 flex items-center text-2xl font-semibold">
|
20 |
<Logo classNames="mr-1 text-yellow-400 text-4xl" />
|
21 |
HuggingChat
|
22 |
<div
|
23 |
+
class="ml-3 flex h-6 items-center rounded-lg border border-gray-100 bg-gray-50 px-2 text-base text-gray-400 dark:border-gray-700/60 dark:bg-gray-800"
|
24 |
>
|
25 |
v0
|
26 |
</div>
|
|
|
31 |
</div>
|
32 |
</div>
|
33 |
<div class="lg:col-span-2 lg:pl-24">
|
34 |
+
<div class="overflow-hidden rounded-xl border dark:border-gray-800">
|
35 |
<div class="p-3">
|
36 |
<div class="text-sm text-gray-600 dark:text-gray-400">Current Model</div>
|
37 |
<div class="font-semibold">{PUBLIC_MODEL_NAME}</div>
|
38 |
</div>
|
39 |
<div
|
40 |
+
class="flex items-center gap-5 rounded-xl bg-gray-100 px-3 py-2 text-sm text-gray-600 dark:bg-gray-800 dark:text-gray-300"
|
41 |
>
|
42 |
<a
|
43 |
href="https://huggingface.co/{PUBLIC_MODEL_ID}"
|
|
|
45 |
rel="noreferrer"
|
46 |
class="flex items-center hover:underline"
|
47 |
>
|
48 |
+
<CarbonArrowUpRight class="mr-1.5 text-xs text-gray-400" />
|
49 |
Model
|
50 |
<div class="max-sm:hidden"> page</div>
|
51 |
</a>
|
|
|
55 |
rel="noreferrer"
|
56 |
class="flex items-center hover:underline"
|
57 |
>
|
58 |
+
<CarbonArrowUpRight class="mr-1.5 text-xs text-gray-400" />
|
59 |
Dataset
|
60 |
<div class="max-sm:hidden"> page</div>
|
61 |
</a>
|
62 |
<a
|
63 |
href="https://open-assistant.io/"
|
64 |
target="_blank"
|
65 |
+
class="ml-auto flex items-center hover:underline"
|
66 |
rel="noreferrer"
|
67 |
>
|
68 |
+
<CarbonEarth class="mr-1.5 text-xs text-gray-400" />
|
69 |
Open Assistant Website
|
70 |
</a>
|
71 |
</div>
|
|
|
74 |
{#if PUBLIC_DISABLE_INTRO_TILES !== "true"}
|
75 |
<div class="lg:col-span-3 lg:mt-12">
|
76 |
<p class="mb-3 text-gray-600 dark:text-gray-300">Examples</p>
|
77 |
+
<div class="grid gap-3 lg:grid-cols-3 lg:gap-5">
|
78 |
<button
|
79 |
type="button"
|
80 |
+
class="rounded-xl border bg-gray-50 p-2.5 text-gray-600 hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700 sm:p-4"
|
81 |
on:click={() =>
|
82 |
dispatch(
|
83 |
"message",
|
|
|
88 |
</button>
|
89 |
<button
|
90 |
type="button"
|
91 |
+
class="rounded-xl border bg-gray-50 p-2.5 text-gray-600 hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700 sm:p-4"
|
92 |
on:click={() =>
|
93 |
dispatch(
|
94 |
"message",
|
|
|
99 |
</button>
|
100 |
<button
|
101 |
type="button"
|
102 |
+
class="rounded-xl border bg-gray-50 p-2.5 text-gray-600 hover:bg-gray-100 dark:border-gray-800 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700 sm:p-4"
|
103 |
on:click={() => dispatch("message", "How do I make a delicious lemon cheesecake?")}
|
104 |
>
|
105 |
"Assist in a task"
|
src/lib/components/chat/ChatMessage.svelte
CHANGED
@@ -67,16 +67,16 @@
|
|
67 |
<img
|
68 |
alt=""
|
69 |
src="https://huggingface.co/avatars/2edb18bd0206c16b433841a47f53fa8e.svg"
|
70 |
-
class="mt-5
|
71 |
/>
|
72 |
<div
|
73 |
-
class="relative
|
74 |
>
|
75 |
{#if !message.content}
|
76 |
<IconLoading classNames="absolute inset-0 m-auto" />
|
77 |
{/if}
|
78 |
<div
|
79 |
-
class="prose max-
|
80 |
bind:this={contentEl}
|
81 |
>
|
82 |
{#each tokens as token}
|
@@ -92,8 +92,8 @@
|
|
92 |
{/if}
|
93 |
{#if message.from === "user"}
|
94 |
<div class="flex items-start justify-start gap-4 max-sm:text-sm">
|
95 |
-
<div class="mt-5
|
96 |
-
<div class="rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400
|
97 |
{message.content.trim()}
|
98 |
</div>
|
99 |
</div>
|
|
|
67 |
<img
|
68 |
alt=""
|
69 |
src="https://huggingface.co/avatars/2edb18bd0206c16b433841a47f53fa8e.svg"
|
70 |
+
class="mt-5 h-3 w-3 flex-none rounded-full shadow-lg"
|
71 |
/>
|
72 |
<div
|
73 |
+
class="relative min-h-[calc(2rem+theme(spacing[3.5])*2)] min-w-[100px] rounded-2xl border border-gray-100 bg-gradient-to-br from-gray-50 px-5 py-3.5 text-gray-600 prose-pre:my-2 dark:border-gray-800 dark:from-gray-800/40 dark:text-gray-300"
|
74 |
>
|
75 |
{#if !message.content}
|
76 |
<IconLoading classNames="absolute inset-0 m-auto" />
|
77 |
{/if}
|
78 |
<div
|
79 |
+
class="prose max-w-none dark:prose-invert max-sm:prose-sm prose-headings:font-semibold prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900"
|
80 |
bind:this={contentEl}
|
81 |
>
|
82 |
{#each tokens as token}
|
|
|
92 |
{/if}
|
93 |
{#if message.from === "user"}
|
94 |
<div class="flex items-start justify-start gap-4 max-sm:text-sm">
|
95 |
+
<div class="mt-5 h-3 w-3 flex-none rounded-full" />
|
96 |
+
<div class="whitespace-break-spaces rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400">
|
97 |
{message.content.trim()}
|
98 |
</div>
|
99 |
</div>
|
src/lib/components/chat/ChatMessages.svelte
CHANGED
@@ -25,11 +25,11 @@
|
|
25 |
</script>
|
26 |
|
27 |
<div
|
28 |
-
class="
|
29 |
use:snapScrollToBottom={messages.length ? messages : false}
|
30 |
bind:this={chatContainer}
|
31 |
>
|
32 |
-
<div class="
|
33 |
{#each messages as message, i}
|
34 |
<ChatMessage loading={loading && i === messages.length - 1} {message} />
|
35 |
{:else}
|
@@ -41,7 +41,7 @@
|
|
41 |
<div class="h-32 flex-none" />
|
42 |
</div>
|
43 |
<ScrollToBottomBtn
|
44 |
-
class="
|
45 |
scrollNode={chatContainer}
|
46 |
/>
|
47 |
</div>
|
|
|
25 |
</script>
|
26 |
|
27 |
<div
|
28 |
+
class="scrollbar-custom mr-1 h-full overflow-y-auto"
|
29 |
use:snapScrollToBottom={messages.length ? messages : false}
|
30 |
bind:this={chatContainer}
|
31 |
>
|
32 |
+
<div class="mx-auto flex h-full max-w-3xl flex-col gap-5 px-5 pt-6 sm:gap-8 xl:max-w-4xl">
|
33 |
{#each messages as message, i}
|
34 |
<ChatMessage loading={loading && i === messages.length - 1} {message} />
|
35 |
{:else}
|
|
|
41 |
<div class="h-32 flex-none" />
|
42 |
</div>
|
43 |
<ScrollToBottomBtn
|
44 |
+
class="bottom-36 right-4 max-md:hidden lg:right-10"
|
45 |
scrollNode={chatContainer}
|
46 |
/>
|
47 |
</div>
|
src/lib/components/chat/ChatWindow.svelte
CHANGED
@@ -29,7 +29,7 @@
|
|
29 |
<div class="relative min-h-0 min-w-0">
|
30 |
<ChatMessages {loading} {pending} {messages} on:message />
|
31 |
<div
|
32 |
-
class="
|
33 |
>
|
34 |
<StopGeneratingBtn
|
35 |
visible={loading}
|
@@ -38,9 +38,9 @@
|
|
38 |
/>
|
39 |
<form
|
40 |
on:submit|preventDefault={handleSubmit}
|
41 |
-
class="w-full
|
42 |
>
|
43 |
-
<div class="w-full flex
|
44 |
<ChatInput
|
45 |
placeholder="Ask anything"
|
46 |
bind:value={message}
|
@@ -49,7 +49,7 @@
|
|
49 |
maxRows={10}
|
50 |
/>
|
51 |
<button
|
52 |
-
class="btn
|
53 |
disabled={!message || loading || disabled}
|
54 |
type="submit"
|
55 |
>
|
@@ -57,7 +57,7 @@
|
|
57 |
</button>
|
58 |
</div>
|
59 |
</form>
|
60 |
-
<div class="
|
61 |
<p>
|
62 |
Model: <a
|
63 |
href="https://huggingface.co/{PUBLIC_MODEL_ID}"
|
@@ -69,7 +69,7 @@
|
|
69 |
</p>
|
70 |
{#if messages.length}
|
71 |
<button
|
72 |
-
class="flex flex-none items-center hover:
|
73 |
type="button"
|
74 |
on:click={() => dispatch("share")}
|
75 |
>
|
|
|
29 |
<div class="relative min-h-0 min-w-0">
|
30 |
<ChatMessages {loading} {pending} {messages} on:message />
|
31 |
<div
|
32 |
+
class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
|
33 |
>
|
34 |
<StopGeneratingBtn
|
35 |
visible={loading}
|
|
|
38 |
/>
|
39 |
<form
|
40 |
on:submit|preventDefault={handleSubmit}
|
41 |
+
class="relative flex w-full max-w-4xl flex-1 items-center rounded-xl border bg-gray-100 focus-within:border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:focus-within:border-gray-500 "
|
42 |
>
|
43 |
+
<div class="flex w-full flex-1 border-none bg-transparent">
|
44 |
<ChatInput
|
45 |
placeholder="Ask anything"
|
46 |
bind:value={message}
|
|
|
49 |
maxRows={10}
|
50 |
/>
|
51 |
<button
|
52 |
+
class="btn mx-1 my-1 h-[2.4rem] self-end rounded-lg bg-transparent p-1 px-[0.7rem] text-gray-400 disabled:opacity-60 enabled:hover:text-gray-700 dark:disabled:opacity-40 enabled:dark:hover:text-gray-100"
|
53 |
disabled={!message || loading || disabled}
|
54 |
type="submit"
|
55 |
>
|
|
|
57 |
</button>
|
58 |
</div>
|
59 |
</form>
|
60 |
+
<div class="mt-2 flex justify-between self-stretch px-1 text-xs text-gray-400/90 max-sm:gap-2">
|
61 |
<p>
|
62 |
Model: <a
|
63 |
href="https://huggingface.co/{PUBLIC_MODEL_ID}"
|
|
|
69 |
</p>
|
70 |
{#if messages.length}
|
71 |
<button
|
72 |
+
class="flex flex-none items-center hover:text-gray-400 hover:underline max-sm:rounded-lg max-sm:bg-gray-50 max-sm:px-2.5 dark:max-sm:bg-gray-800"
|
73 |
type="button"
|
74 |
on:click={() => dispatch("share")}
|
75 |
>
|
src/routes/+error.svelte
CHANGED
@@ -3,13 +3,13 @@
|
|
3 |
</script>
|
4 |
|
5 |
<div
|
6 |
-
class="flex items-center justify-center
|
7 |
>
|
8 |
<div
|
9 |
-
class="
|
10 |
>
|
11 |
-
<h1 class="text-5xl
|
12 |
-
<div class="h-px
|
13 |
<h2 class="text-lg">{$page.error?.message}</h2>
|
14 |
</div>
|
15 |
</div>
|
|
|
3 |
</script>
|
4 |
|
5 |
<div
|
6 |
+
class="flex items-center justify-center bg-gradient-to-t from-gray-200 text-gray-800 dark:from-gray-700 dark:text-gray-300"
|
7 |
>
|
8 |
<div
|
9 |
+
class="align-center -mt-24 flex flex-col justify-center rounded-xl border bg-white px-8 pb-2 pt-4 text-center dark:border-gray-700 dark:bg-gray-800"
|
10 |
>
|
11 |
+
<h1 class="mb-2 text-5xl font-semibold">{$page.status}</h1>
|
12 |
+
<div class="-mx-8 my-2 h-px bg-gray-200 dark:bg-gray-700" />
|
13 |
<h2 class="text-lg">{$page.error?.message}</h2>
|
14 |
</div>
|
15 |
</div>
|
src/routes/+layout.svelte
CHANGED
@@ -79,7 +79,7 @@
|
|
79 |
</svelte:head>
|
80 |
|
81 |
<div
|
82 |
-
class="grid h-full w-screen grid-cols-1 grid-rows-[auto,1fr]
|
83 |
>
|
84 |
<MobileNav
|
85 |
isOpen={isNavOpen}
|
@@ -92,7 +92,7 @@
|
|
92 |
on:deleteConversation={(ev) => deleteConversation(ev.detail)}
|
93 |
/>
|
94 |
</MobileNav>
|
95 |
-
<nav class="max-
|
96 |
<NavMenu
|
97 |
conversations={data.conversations}
|
98 |
on:shareConversation={(ev) => shareConversation(ev.detail.id, ev.detail.title)}
|
|
|
79 |
</svelte:head>
|
80 |
|
81 |
<div
|
82 |
+
class="grid h-full w-screen grid-cols-1 grid-rows-[auto,1fr] overflow-hidden text-smd dark:text-gray-300 md:grid-cols-[280px,1fr] md:grid-rows-[1fr]"
|
83 |
>
|
84 |
<MobileNav
|
85 |
isOpen={isNavOpen}
|
|
|
92 |
on:deleteConversation={(ev) => deleteConversation(ev.detail)}
|
93 |
/>
|
94 |
</MobileNav>
|
95 |
+
<nav class="grid max-h-screen grid-cols-1 grid-rows-[auto,1fr,auto] max-md:hidden">
|
96 |
<NavMenu
|
97 |
conversations={data.conversations}
|
98 |
on:shareConversation={(ev) => shareConversation(ev.detail.id, ev.detail.title)}
|
src/routes/+page.svelte
CHANGED
@@ -11,10 +11,10 @@
|
|
11 |
try {
|
12 |
loading = true;
|
13 |
const res = await fetch(`${base}/conversation`, {
|
14 |
-
method:
|
15 |
headers: {
|
16 |
-
|
17 |
-
}
|
18 |
});
|
19 |
|
20 |
if (!res.ok) {
|
|
|
11 |
try {
|
12 |
loading = true;
|
13 |
const res = await fetch(`${base}/conversation`, {
|
14 |
+
method: "POST",
|
15 |
headers: {
|
16 |
+
"Content-Type": "application/json",
|
17 |
+
},
|
18 |
});
|
19 |
|
20 |
if (!res.ok) {
|
src/routes/privacy/+page.svelte
CHANGED
@@ -3,8 +3,8 @@
|
|
3 |
import privacy from "../../../PRIVACY.md?raw";
|
4 |
</script>
|
5 |
|
6 |
-
<div class="p-6
|
7 |
-
<div class="mx-auto
|
8 |
{@html marked(privacy, { gfm: true })}
|
9 |
</div>
|
10 |
</div>
|
|
|
3 |
import privacy from "../../../PRIVACY.md?raw";
|
4 |
</script>
|
5 |
|
6 |
+
<div class="overflow-auto p-6">
|
7 |
+
<div class="prose mx-auto px-4 pb-24 pt-6 dark:prose-invert md:pt-12">
|
8 |
{@html marked(privacy, { gfm: true })}
|
9 |
</div>
|
10 |
</div>
|
src/styles/main.css
CHANGED
@@ -6,12 +6,12 @@
|
|
6 |
|
7 |
@layer components {
|
8 |
.btn {
|
9 |
-
@apply
|
10 |
}
|
11 |
}
|
12 |
|
13 |
@layer utilities {
|
14 |
.scrollbar-custom {
|
15 |
-
@apply scrollbar-thin scrollbar-
|
16 |
}
|
17 |
}
|
|
|
6 |
|
7 |
@layer components {
|
8 |
.btn {
|
9 |
+
@apply inline-flex flex-shrink-0 cursor-pointer select-none items-center justify-center whitespace-nowrap outline-none transition-all focus:ring disabled:cursor-default;
|
10 |
}
|
11 |
}
|
12 |
|
13 |
@layer utilities {
|
14 |
.scrollbar-custom {
|
15 |
+
@apply scrollbar-thin scrollbar-track-transparent scrollbar-thumb-black/10 scrollbar-thumb-rounded-full scrollbar-w-1 hover:scrollbar-thumb-black/20 dark:scrollbar-thumb-white/10 dark:hover:scrollbar-thumb-white/20;
|
16 |
}
|
17 |
}
|