Skip to content

Commit 6686701

Browse files
authored
123-poc-wc-events (#124)
2 parents 212c98c + bfcfd26 commit 6686701

File tree

11 files changed

+458
-144
lines changed

11 files changed

+458
-144
lines changed

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
"type": "module",
120120
"dependencies": {
121121
"@floating-ui/dom": "^1.6.12",
122+
"@smallstack/utils": "^3.0.10",
122123
"@sveltejs/kit": "^2.8.1",
123124
"date-fns": "^4.1.0",
124125
"i18next": "^23.16.8",

src/lib/docs/ComponentPage.svelte

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
22
import type { Snippet } from "svelte";
33
import ComponentPageCard from "./ComponentPageCard.svelte";
4+
5+
import type { ComponentPropDefinition } from "./component-prop-definition";
46
import ComponentPageHeader from "./ComponentPageHeader.svelte";
57
68
let {
@@ -14,12 +16,7 @@
1416
description?: string;
1517
demoComponent?: Snippet;
1618
features?: Snippet;
17-
props?: Array<{
18-
name: string;
19-
type: string;
20-
default: string;
21-
description: string;
22-
}>;
19+
props?: Array<ComponentPropDefinition>;
2320
} = $props();
2421
</script>
2522

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface ComponentPropDefinition {
2+
name: string;
3+
type: string;
4+
default: string;
5+
description: string;
6+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<svelte:options
2+
customElement={{
3+
tag: "sui-chat-window",
4+
shadow: "none",
5+
props: {
6+
messages: { type: "Array", reflect: true },
7+
users: { type: "Array" },
8+
meId: { type: "String" },
9+
threads: { type: "Array" }
10+
}
11+
}}
12+
/>
13+
14+
<script lang="ts">
15+
import { createEventDispatcher, onMount } from "svelte";
16+
import type { ChatThread } from "./chat-message";
17+
import MessageThread from "./MessageThread.svelte";
18+
19+
const messageEventDispatcher = createEventDispatcher();
20+
21+
let {
22+
threads = [],
23+
meId,
24+
showAvatars = "always",
25+
currentThreadId,
26+
sendMessage
27+
}: {
28+
threads?: ChatThread[];
29+
meId: string;
30+
showAvatars?: "never" | "always" | "change";
31+
currentThreadId?: string;
32+
sendMessage: (threadId: string, message: string) => void;
33+
} = $props();
34+
let newChatMessage = $state("");
35+
let sidePanelOpen = $state(false);
36+
37+
onMount(() => {
38+
if (!currentThreadId && threads.length > 0) currentThreadId = threads[0].id;
39+
});
40+
let currentThread = $derived(threads?.find((thread) => thread.id === currentThreadId));
41+
42+
function executeSendMessage() {
43+
if (sendMessage) sendMessage(currentThreadId, newChatMessage);
44+
else messageEventDispatcher("message", newChatMessage);
45+
newChatMessage = "";
46+
}
47+
</script>
48+
49+
<div class="flex flex-row gap-2 text-primary-content min-h-64">
50+
{#if threads && threads.length > 0}
51+
<div
52+
class="flex flex-col bg-primary bg-opacity-90 rounded p-2 text-primary-content items-start {sidePanelOpen
53+
? 'w-64'
54+
: 'w-14'}"
55+
>
56+
<div class="grow flex flex-col gap-2 items-start">
57+
{#each threads as thread}
58+
<button
59+
class="flex flex-row gap-2"
60+
onclick={() => {
61+
currentThreadId = thread.id;
62+
sidePanelOpen = false;
63+
}}
64+
>
65+
<img
66+
src={thread.avatarUrl}
67+
alt={thread.name}
68+
class="avatar rounded-full w-10 h-10 {thread.id === currentThreadId
69+
? 'bg-secondary'
70+
: 'bg-primary'}"
71+
/>
72+
{#if sidePanelOpen}
73+
<div class="flex flex-col gap-0 justify-center items-start h-full">
74+
<span class="font-bold truncate">{thread.name}</span>
75+
<span class="text-xs truncate text-gray-500"
76+
>{thread.messages[thread.messages.length - 1].text}</span
77+
>
78+
</div>
79+
{/if}
80+
</button>
81+
{/each}
82+
</div>
83+
<button onclick={() => (sidePanelOpen = !sidePanelOpen)} class="btn btn-circle btn-ghost btn-sm m-1">
84+
<svg
85+
xmlns="http://www.w3.org/2000/svg"
86+
x="0px"
87+
y="0px"
88+
width="16"
89+
height="16"
90+
viewBox="0 0 50 50"
91+
>
92+
<path
93+
fill="currentColor"
94+
d="M 0 7.5 L 0 12.5 L 50 12.5 L 50 7.5 Z M 0 22.5 L 0 27.5 L 50 27.5 L 50 22.5 Z M 0 37.5 L 0 42.5 L 50 42.5 L 50 37.5 Z"
95+
></path>
96+
</svg>
97+
</button>
98+
</div>
99+
{/if}
100+
<div class="flex flex-col gap-2 grow">
101+
{#if currentThread}
102+
<div class="grow">
103+
<MessageThread
104+
messages={currentThread.messages}
105+
users={currentThread.users}
106+
{meId}
107+
{showAvatars}
108+
/>
109+
</div>
110+
<div class="join">
111+
<input
112+
type="string"
113+
class="join-item input input-bordered grow"
114+
bind:value={newChatMessage}
115+
onkeydown={(e) => e.key === "Enter" && executeSendMessage()}
116+
/>
117+
<button class="join-item btn" disabled={newChatMessage === ""} onclick={executeSendMessage}>
118+
Send
119+
</button>
120+
</div>
121+
{/if}
122+
</div>
123+
</div>

src/lib/modules/chat/MessageThread.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<svelte:options
22
customElement={{
3-
tag: "sui-chat-window",
3+
tag: "sui-message-thread",
44
shadow: "none",
55
props: {
66
messages: { type: "Array", reflect: true },
77
users: { type: "Array" },
88
meId: { type: "String" }
9-
}
9+
},
10+
1011
}}
1112
/>
1213

src/lib/modules/chat/chat-message.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,11 @@ export interface ChatUser {
1010
name: string;
1111
avatarUrl: string;
1212
}
13+
14+
export interface ChatThread {
15+
id: string;
16+
avatarUrl: string;
17+
name: string;
18+
users: ChatUser[];
19+
messages: ChatMessage[];
20+
}

src/routes/+layout.svelte

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100
text: "Chat Module",
101101
icon: "fas fa-comments",
102102
entries: [
103+
{
104+
text: "Message Thread",
105+
link: "/modules/chat/message-thread"
106+
},
103107
{
104108
text: "Chat Window",
105109
link: "/modules/chat/chat-window"

0 commit comments

Comments
 (0)