Blocks
Messaging
Everything people expect from a messaging app, in one block: direct messages, groups and channels in one list, threads, search across everything, and the small things like drafts, receipts and "typing…". On a phone it becomes list, conversation, details, with a way back from each.
Examples
A workspace
Open a conversation and send something: people type back, and your message goes from Sent to Read. Try a thread in #translation, the voice note in Observatory crew, search with filters, and Forward, Pin or Save from a message's menu. Narrow the window to see the phone layout.
Pick a conversation
<script lang="ts">
import { onMount } from 'svelte';
import Button from '#lib/ui/Button.svelte';
import Messaging from '#lib/blocks/messaging/Messaging.svelte';
import { createMock } from '#lib/blocks/messaging/mock.js';
const api = createMock();
// Stops the demo's pretend replies when the example goes away.
onMount(() => () => api.stop());
let failing = $state(false);
let reset: ReturnType<typeof setTimeout> | undefined;
onMount(() => () => clearTimeout(reset));
</script>
<div class="demo">
<div class="frame"><Messaging {api} label="Bayt al-Hikma" initial="crew" /></div>
<Button
variant="secondary"
size="sm"
onclick={() => {
api.failNext();
failing = true;
clearTimeout(reset);
reset = setTimeout(() => (failing = false), 1500);
}}>{failing ? 'The next request will fail' : 'Fail the next request'}</Button
>
</div>
<style>
.demo {
display: grid;
justify-items: start;
gap: 1rem;
inline-size: 100%;
}
.frame {
inline-size: 100%;
block-size: min(40rem, 85dvh);
}
</style>A new workspace
Before anyone has written: start a direct message or a named group.
Pick a conversation
<script lang="ts">
import { onMount } from 'svelte';
import Messaging from '#lib/blocks/messaging/Messaging.svelte';
import { createMock } from '#lib/blocks/messaging/mock.js';
const api = createMock({ empty: true });
onMount(() => () => api.stop());
</script>
<div class="frame"><Messaging {api} label="New workspace" /></div>
<style>
.frame {
inline-size: 100%;
block-size: 30rem;
}
</style>Installation
npx sinaui add blocks/messagingCopy src/lib/blocks/messaging/, with the Chat component and what it needs, plus Checkbox, Dialog, EmptyState, Input, SearchField, Segmented, Select, Skeleton and Switch. Icons come from @hugeicons/core-free-icons.
mock.ts is a pretend backend for trying it out. Write the MessagingApi interface in api.ts over your own server and pass that to <Messaging api={…} /> instead.
What's included
- One list for direct messages, groups and channels: pinned first, unread in bold with counts, an @ for mentions, muted ones quieter, and archived ones out of the way.
- Search every message, or one conversation, by words, person, date, or whether it has a picture, file or link. A result opens its conversation at that message.
- Threads beside the conversation, or full screen on a phone.
- Forward to another conversation, pin, save for later, edit with a visible history, and delete for yourself or for everyone.
- Pictures, files, voice messages and link previews; read receipts, "seen by" in groups, typing and last seen.
- Details for each conversation: members and who's online, pinned messages, shared pictures and files, notifications, pin and archive.
- Unsent text is kept per conversation while you move between them.
- Loading, empty and error states everywhere, with a way to try again.
Keyboard
Everything in Chat's keyboard table, plus Tab through the list, the conversation and its details, and Escape to close a dialog.