Adrien Denat commited on
Commit
b2387f6
1 Parent(s): ffa4f55

Add tailwind prettier (#123)

Browse files
.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 h-full">
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 my-4">
19
  <pre
20
- class="overflow-auto scrollbar-custom scrollbar-thumb-gray-500 hover:scrollbar-thumb-gray-400 dark:scrollbar-thumb-white/10 dark:hover:scrollbar-thumb-white/20 px-5"><code
21
  class="language-{lang}">{@html highlightedCode || code.replaceAll("<", "&lt;")}</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("<", "&lt;")}</code
22
  ></pre>
23
  <CopyToClipBoardBtn
src/lib/components/CopyToClipBoardBtn.svelte CHANGED
@@ -35,7 +35,7 @@
35
  </script>
36
 
37
  <button
38
- class="btn text-sm rounded-lg border py-2 px-2 shadow-sm border-gray-200 active:shadow-inner dark:border-gray-600 hover:border-gray-300 dark:hover:border-gray-400 transition-all {classNames}
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="md:hidden flex items-center h-12 border-b px-4 justify-between dark:border-gray-800 bg-gray-50 dark:bg-gray-800/70"
34
  >
35
  <button
36
  type="button"
37
- class="flex items-center justify-center w-9 h-9 -ml-3 shrink-0"
38
  on:click={() => dispatch("toggle", true)}
39
  aria-label="Open menu"
40
  bind:this={openEl}><CarbonTextAlignJustify /></button
41
  >
42
- <span class="px-4 truncate">{title}</span>
43
- <a href={base || "/"} class="flex items-center justify-center w-9 h-9 -mr-3 shrink-0"
44
  ><CarbonAdd /></a
45
  >
46
  </nav>
47
  <nav
48
- class="fixed inset-0 z-50 grid grid-rows-[auto,auto,1fr,auto] grid-cols-1 max-h-screen bg-white dark:bg-gray-900 bg-gradient-to-l from-gray-50 dark:from-gray-800/30 {isOpen
49
  ? 'block'
50
  : 'hidden'}"
51
  >
52
- <div class="flex items-center px-4 h-12">
53
  <button
54
  type="button"
55
- class="flex items-center justify-center ml-auto w-9 h-9 -mr-3"
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 max-sm:pt-0 sticky top-0 px-3 py-3.5 flex items-center justify-between">
25
- <a class="rounded-xl font-semibold text-lg flex items-center" href="{PUBLIC_ORIGIN}{base}/">
26
  <Logo classNames="mr-1 text-3xl" />
27
  HuggingChat
28
  </a>
29
  <a
30
  href={base || "/"}
31
- class="flex border py-0.5 px-2 rounded-lg shadow-sm hover:shadow-none bg-white dark:bg-gray-700 dark:border-gray-600 text-center"
32
  >
33
  New Chat
34
  </a>
35
  </div>
36
  <div
37
- class="flex flex-col overflow-y-auto scrollbar-custom px-3 pb-3 pt-2 gap-1 bg-gradient-to-l from-gray-50 dark:from-gray-800/30 rounded-r-xl"
38
  >
39
  {#each conversations as conv}
40
  <a
41
  data-sveltekit-noscroll
42
  href="{base}/conversation/{conv.id}"
43
- class="group pl-3 pr-2 h-11 rounded-lg flex-none text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-1.5 {conv.id ===
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 md:hidden md:group-hover:flex w-5 h-5 items-center justify-center rounded"
53
  title="Share conversation"
54
  on:click|preventDefault={() =>
55
  dispatch("shareConversation", { id: conv.id, title: conv.title })}
56
  >
57
- <CarbonExport class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 text-xs" />
58
  </button>
59
 
60
  <button
61
  type="button"
62
- class="flex md:hidden md:group-hover:flex w-5 h-5 items-center justify-center rounded"
63
  title="Delete conversation"
64
  on:click|preventDefault={() => dispatch("deleteConversation", conv.id)}
65
  >
66
  <CarbonTrashCan
67
- class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 text-xs"
68
  />
69
  </button>
70
  </a>
71
  {/each}
72
  </div>
73
  <div
74
- class="flex flex-col p-3 gap-2 bg-gradient-to-l from-gray-50 dark:from-gray-800/30 rounded-r-xl mt-0.5 text-sm"
75
  >
76
  <button
77
  on:click={switchTheme}
78
  type="button"
79
- class="group pl-3 pr-2 h-9 rounded-lg flex-none text-gray-500 dark:text-gray-400 dark:hover:bg-gray-700 flex items-center gap-1.5 hover:bg-gray-100"
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 pl-3 pr-2 h-9 rounded-lg flex-none text-gray-500 dark:text-gray-400 dark:hover:bg-gray-700 flex items-center gap-1.5 hover:bg-gray-100"
88
  >
89
  Feedback
90
  </a>
91
  <a
92
  href="{base}/privacy"
93
- class="group pl-3 pr-2 h-9 rounded-lg flex-none text-gray-500 dark:text-gray-400 dark:hover:bg-gray-700 flex items-center gap-1.5 hover:bg-gray-100"
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 rounded-full border w-[41px] h-[41px] shadow-md dark:shadow-gray-950 bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:border-gray-600 transition-all {className}"
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 btn flex rounded-lg border py-1 px-3 shadow-sm bg-white dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:border-gray-600 transition-all
12
  {className}
13
- {visible ? 'opacity-100 visible' : 'opacity-0 invisible'}
14
  "
15
  >
16
- <CarbonPause class="mr-1 -ml-1 w-[1.1875rem] h-[1.25rem] text-gray-400" /> Stop generating
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 md:top-0 bg-gradient-to-bl from-red-500/20 via-red-500/0 to-red-500/0 pt-2 md:pt-5 pr-2 md:pr-8 pl-36 pb-36 z-20 pointer-events-none"
12
  >
13
  <div
14
- class="flex items-center bg-white/90 dark:bg-gray-900/80 rounded-full py-1 px-3 shadow-sm pointer-events-auto"
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 px-2 font-normal leading-tight text-white shadow transition-opacity
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 flex-1 min-w-0">
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 m-0 w-full h-full top-0 resize-none border-0 bg-transparent p-3 focus:ring-0 focus-visible:ring-0 dark:bg-transparent outline-none scrollbar-custom overflow-x-hidden overflow-y-scroll"
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 gap-8 my-auto">
17
  <div class="lg:col-span-1">
18
  <div>
19
- <div class="text-2xl font-semibold mb-3 flex items-center">
20
  <Logo classNames="mr-1 text-yellow-400 text-4xl" />
21
  HuggingChat
22
  <div
23
- class="text-base h-6 px-2 rounded-lg text-gray-400 bg-gray-50 ml-3 flex items-center border border-gray-100 dark:bg-gray-800 dark:border-gray-700/60"
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 rounded-xl overflow-hidden">
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 px-3 py-2 bg-gray-100 rounded-xl text-sm text-gray-600 dark:text-gray-300 dark:bg-gray-800"
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="text-xs mr-1.5 text-gray-400" />
49
  Model
50
  <div class="max-sm:hidden">&nbsp;page</div>
51
  </a>
@@ -55,17 +55,17 @@
55
  rel="noreferrer"
56
  class="flex items-center hover:underline"
57
  >
58
- <CarbonArrowUpRight class="text-xs mr-1.5 text-gray-400" />
59
  Dataset
60
  <div class="max-sm:hidden">&nbsp;page</div>
61
  </a>
62
  <a
63
  href="https://open-assistant.io/"
64
  target="_blank"
65
- class="flex items-center hover:underline ml-auto"
66
  rel="noreferrer"
67
  >
68
- <CarbonEarth class="text-xs mr-1.5 text-gray-400" />
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 gap-3 lg:gap-5">
78
  <button
79
  type="button"
80
- class="text-gray-600 dark:text-gray-300 p-2.5 sm:p-4 bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 hover:bg-gray-100 border dark:border-gray-800 rounded-xl"
81
  on:click={() =>
82
  dispatch(
83
  "message",
@@ -88,7 +88,7 @@
88
  </button>
89
  <button
90
  type="button"
91
- class="text-gray-600 dark:text-gray-300 p-2.5 sm:p-4 bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 hover:bg-gray-100 border dark:border-gray-800 rounded-xl"
92
  on:click={() =>
93
  dispatch(
94
  "message",
@@ -99,7 +99,7 @@
99
  </button>
100
  <button
101
  type="button"
102
- class="text-gray-600 dark:text-gray-300 p-2.5 sm:p-4 bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 hover:bg-gray-100 border dark:border-gray-800 rounded-xl"
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">&nbsp;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">&nbsp;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 w-3 h-3 flex-none rounded-full shadow-lg"
71
  />
72
  <div
73
- class="relative rounded-2xl prose-pre:my-2 px-5 py-3.5 border border-gray-100 bg-gradient-to-br from-gray-50 dark:from-gray-800/40 dark:border-gray-800 text-gray-600 dark:text-gray-300 min-h-[calc(2rem+theme(spacing[3.5])*2)] min-w-[100px]"
74
  >
75
  {#if !message.content}
76
  <IconLoading classNames="absolute inset-0 m-auto" />
77
  {/if}
78
  <div
79
- class="prose max-sm:prose-sm dark:prose-invert prose-pre:bg-gray-800 dark:prose-pre:bg-gray-900 prose-h1:text-lg prose-h2:text-base prose-h3:text-base prose-headings:font-semibold max-w-none"
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 w-3 h-3 flex-none rounded-full" />
96
- <div class="rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400 whitespace-break-spaces">
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="overflow-y-auto h-full scrollbar-custom mr-1"
29
  use:snapScrollToBottom={messages.length ? messages : false}
30
  bind:this={chatContainer}
31
  >
32
- <div class="max-w-3xl xl:max-w-4xl mx-auto px-5 pt-6 flex flex-col gap-5 sm:gap-8 h-full">
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="max-md:hidden bottom-36 right-4 lg:right-10"
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="flex flex-col pointer-events-none [&>*]:pointer-events-auto max-md:border-t dark:border-gray-800 items-center max-md:dark:bg-gray-900 max-md:bg-white bg-gradient-to-t from-white via-white/80 to-white/0 dark:from-gray-900 dark:via-gray-80 dark:to-gray-900/0 justify-center absolute inset-x-0 max-w-3xl xl:max-w-4xl mx-auto px-3.5 sm:px-5 bottom-0 py-4 md:py-8 w-full z-0"
33
  >
34
  <StopGeneratingBtn
35
  visible={loading}
@@ -38,9 +38,9 @@
38
  />
39
  <form
40
  on:submit|preventDefault={handleSubmit}
41
- class="w-full relative flex items-center rounded-xl flex-1 max-w-4xl border bg-gray-100 focus-within:border-gray-300 dark:bg-gray-700 dark:border-gray-600 dark:focus-within:border-gray-500 "
42
  >
43
- <div class="w-full flex flex-1 border-none bg-transparent">
44
  <ChatInput
45
  placeholder="Ask anything"
46
  bind:value={message}
@@ -49,7 +49,7 @@
49
  maxRows={10}
50
  />
51
  <button
52
- class="btn p-1 px-[0.7rem] self-end bg-transparent my-1 h-[2.4rem] text-gray-400 rounded-lg enabled:dark:hover:text-gray-100 enabled:hover:text-gray-700 disabled:opacity-60 dark:disabled:opacity-40 mx-1"
53
  disabled={!message || loading || disabled}
54
  type="submit"
55
  >
@@ -57,7 +57,7 @@
57
  </button>
58
  </div>
59
  </form>
60
- <div class="flex text-xs text-gray-400/90 mt-2 justify-between self-stretch px-1 max-sm:gap-2">
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:underline hover:text-gray-400 dark:max-sm:bg-gray-800 max-sm:bg-gray-50 max-sm:px-2.5 max-sm:rounded-lg"
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 text-gray-800 dark:text-gray-300 bg-gradient-to-t from-gray-200 dark:from-gray-700"
7
  >
8
  <div
9
- class="dark:bg-gray-800 bg-white border rounded-xl pb-2 pt-4 px-8 flex flex-col justify-center align-center text-center -mt-24 dark:border-gray-700"
10
  >
11
- <h1 class="text-5xl mb-2 font-semibold">{$page.status}</h1>
12
- <div class="h-px dark:bg-gray-700 bg-gray-200 -mx-8 my-2" />
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] md:grid-rows-[1fr] md:grid-cols-[280px,1fr] overflow-hidden text-smd dark:text-gray-300"
83
  >
84
  <MobileNav
85
  isOpen={isNavOpen}
@@ -92,7 +92,7 @@
92
  on:deleteConversation={(ev) => deleteConversation(ev.detail)}
93
  />
94
  </MobileNav>
95
- <nav class="max-md:hidden grid grid-rows-[auto,1fr,auto] grid-cols-1 max-h-screen">
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: 'POST',
15
  headers: {
16
- 'Content-Type': 'application/json'
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 overflow-auto">
7
- <div class="mx-auto pt-6 md:pt-12 pb-24 px-4 prose dark:prose-invert">
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 cursor-pointer disabled:cursor-default select-none inline-flex flex-shrink-0 justify-center items-center whitespace-nowrap outline-none focus:ring transition-all;
10
  }
11
  }
12
 
13
  @layer utilities {
14
  .scrollbar-custom {
15
- @apply scrollbar-thin scrollbar-w-1 scrollbar-thumb-rounded-full scrollbar-track-transparent scrollbar-thumb-black/10 dark:scrollbar-thumb-white/10 hover:scrollbar-thumb-black/20 dark:hover:scrollbar-thumb-white/20;
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
  }