# rn-instant-message-composer URL: /docs/native/docyrus/instant-message-composer SMS and WhatsApp composer with a channel switcher, phone recipient chips, SMS segment counter, emoji and WhatsApp attachments. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-instant-message-composer ``` **Dependencies:** - [@emoji-mart/data](https://www.npmjs.com/package/@emoji-mart/data) - **Channel switcher.** A segmented control for `availableChannels`. It is locked when `onChannelChange` is omitted. - **Recipients.** Phone chips (`phone-pad` keyboard). A `,`, `;`, newline or return commits a number, and invalid numbers show as red chips. - **Body.** A plain multiline input. SMS defaults to a 1,600 character limit and shows `{length} chars ยท {parts} SMS` (160 characters for a single message, 153 per concatenated part). WhatsApp has no limit and shows a formatting tip. - **Emoji.** Opens the [rn-emoji-picker](/docs/native/components/emoji-picker) sheet and inserts at the caret. - **Attachments.** Only shown for WhatsApp. Send is enabled once every recipient is valid and there is a body or an attachment. ## Usage ```tsx import { InstantMessageComposer } from '@/components/docyrus-native/instant-message-composer'; ``` Wire it to Docyrus with [`useDocyrusInstantMessageComposer`](/docs/native/hooks/use-docyrus-instant-message-composer), or use [rn-instant-message-compose-dialog](/docs/native/docyrus/instant-message-compose-dialog). ## API Reference | Prop | Type | Default | Description | |------|------|---------|-------------| | `ref` | `Ref` | - | focus / blur / insertText | | `variant` | `'default' \| 'outline' \| 'minimal'` | `'default'` | Visual style | | `size` | `'sm' \| 'default' \| 'lg'` | `'default'` | Size | | `channel` | `'sms' \| 'whatsapp'` | - | Active channel (required) | | `onChannelChange` | `(channel: InstantMessageChannel) => void` | - | Channel switch callback โ€” omit to lock the channel | | `availableChannels` | `ReadonlyArray` | `['sms', 'whatsapp']` | Channels in the switcher | | `recipients` | `string[]` | - | Recipient phone numbers (required) | | `onRecipientsChange` | `(recipients: string[]) => void` | - | Recipients change callback (required) | | `body` | `string` | - | Message body (required) | | `onBodyChange` | `(body: string) => void` | - | Body change callback (required) | | `onSend` | `() => void` | - | Send handler | | `onAttach` | `() => void` | - | Attach handler (WhatsApp) | | `onDiscard` | `() => void` | - | Discard handler (shows Cancel) | | `sending` | `boolean` | `false` | Sending state | | `disabled` | `boolean` | `false` | Disables all interactions | | `attachments` | `InstantMessageAttachment[]` | - | Attachments to display (WhatsApp) | | `onRemoveAttachment` | `(index: number) => void` | - | Remove-attachment handler | | `maxLength` | `number \| null` | `by channel` | Body limit โ€” 1600 for SMS, unlimited for WhatsApp; null disables | | `helper` | `ReactNode` | - | Helper row above the body | | `className` | `string` | - | Container classes | ### Ref (`InstantMessageComposerHandle`) | Method | Description | |--------|-------------| | `focus()` / `blur()` | Body focus | | `insertText(text)` | Insert at the caret | ## Helpers | Export | Description | |--------|-------------| | `smsParts(length)` | SMS segment count | | `isValidPhone(value)` | Recipient chip validation (6โ€“18 digits, optional `+`) | ## Type Exports | Type | Description | |------|-------------| | `InstantMessageComposerProps` | Props | | `InstantMessageComposerHandle` | Ref handle | | `InstantMessageChannel` | `'sms' \| 'whatsapp'` | | `InstantMessageAttachment` | `{ name, size }` | | `InstantMessageComposerVariant` / `InstantMessageComposerSize` | Variant / size unions | ## Differences from web - `ref` is a handle instead of the root element; `className` replaces the div attributes.