Skip to content
kerfjsGitHub

Composer

Where a message is written: text, attachments, emoji and @mentions.

SourcePackage @kerf-js/veneer

Preview

tsx
import { state } from '@kerf-js/core'import { Composer, Stack, Text } from '@kerf-js/veneer'import type {  ComposerFile,  ComposerSend} from '@kerf-js/veneer'import type { Peer } from '@kerf-js/veneer'export function Attach() {  const files = state<ComposerFile[]>([])  const sent = state('')  const send = (m: ComposerSend) => {    sent.value = m.text    files.value = []  }  return (    <Stack gap="related">      <Composer        label="Message #deploys"        placeholder="Message #deploys"        mentions={PEERS}        files={files.value}        onAttach={() =>          (files.value = [            ...files.value,            {              id: `f${files.value.length}`,              name: 'latency-graph.png',            },          ])        }        onRemoveFile={(file) =>          (files.value = files.value.filter(            (f) => f !== file,          ))        }        onEmoji={(insert) => insert('πŸš€')}        onSend={send}      />      <Text subtle>        {sent.value          ? `Sent: ${sent.value}`          : 'Type @ to mention someone.'}      </Text>    </Stack>  )}const PEOPLE = [  {    id: 'mara',    name: 'Mara Lindqvist',    email: 'mara@kerf.dev',    role: 'Owner',    team: 'Platform',    initials: 'ML',  },  {    id: 'jun',    name: 'Jun Tanaka',    email: 'jun@kerf.dev',    role: 'Admin',    team: 'Platform',    initials: 'JT',  },  {    id: 'priya',    name: 'Priya Raman',    email: 'priya@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'PR',  },  {    id: 'tomas',    name: 'TomΓ‘s Oliveira',    email: 'tomas@kerf.dev',    role: 'Member',    team: 'Web',    initials: 'TO',  },  {    id: 'lena',    name: 'Lena Fischer',    email: 'lena@kerf.dev',    role: 'Member',    team: 'Data',    initials: 'LF',  },  {    id: 'noor',    name: 'Noor Haddad',    email: 'noor@kerf.dev',    role: 'Viewer',    team: 'Data',    initials: 'NH',  },  {    id: 'sam',    name: 'Sam Okafor',    email: 'sam@kerf.dev',    role: 'Member',    team: 'Mobile',    initials: 'SO',  },  {    id: 'ines',    name: 'InΓ©s Vidal',    email: 'ines@kerf.dev',    role: 'Viewer',    team: 'Mobile',    initials: 'IV',  },]const PEERS: Peer[] = PEOPLE.map((p, i) => ({  id: p.id,  name: p.name,  color: i + 1,}))

Installation

npm install @kerf-js/veneer

Usage

tsx
import { Composer } from '@kerf-js/veneer'

Accessibility

Enter
Sends
ShiftEnter
Adds a line
↑↓
Moves through suggestions
Esc
Closes the suggestions, then the quote

API Reference

PropTypeDefaultDescription
labelstringβ€”The textarea's name: "Message #calendar-engine".
placeholderstringβ€”Shown while empty.
quoteState<QuoteDraftValue | null>β€”The quote being drafted, for a Thread to fill.
mentionsMentionable[]β€”People to suggest after @.
filesComposerFile[]β€”Attached files.
compactbooleanfalseHides the keyboard hint.
input((el: HTMLTextAreaElement) => void)β€”Reaches the textarea, for focus.
EventTypeDefaultDescription
onSend(m: ComposerSend) => voidβ€”Called with the text and any quote.
onRemoveFile((f: ComposerFile) => void)β€”Removes one.
onAttach(() => void)β€”Shows the attach button.
onEmoji((insert: (text: string) => void) => void)β€”The emoji slot: open a picker, then call insert with what was picked.
onTyping(() => void)β€”Called as people type.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="composer"] [data-part="sr-only"]

sr-only

RelatedThreadMentions input