@talkjs/react-components
Version:
Provides chat UI components for TalkJS.
626 lines (525 loc) • 19 kB
TypeScript
import { AudioBlock } from '@talkjs/core';
import { ConversationSnapshot } from '@talkjs/core';
import { default as default_2 } from 'react';
import { EditMessageParams } from '@talkjs/core';
import { EditTextMessageParams } from '@talkjs/core';
import { FileBlock } from '@talkjs/core';
import { FileToken } from '@talkjs/core';
import { ImageBlock } from '@talkjs/core';
import { LocationBlock } from '@talkjs/core';
import { MessageSnapshot } from '@talkjs/core';
import { ParticipantSnapshot } from '@talkjs/core';
import type * as React_2 from 'react';
import { ReactElement } from 'react';
import { ReferencedMessageSnapshot } from '@talkjs/core';
import { SendMessageParams } from '@talkjs/core';
import { SendTextMessageParams } from '@talkjs/core';
import { TalkSession } from '@talkjs/core';
import { TextBlock } from '@talkjs/core';
import { TypingSnapshot } from '@talkjs/core';
import { UserSnapshot } from '@talkjs/core';
import { VideoBlock } from '@talkjs/core';
import { VoiceBlock } from '@talkjs/core';
declare type AppId = Brand<string, "App ID">;
declare interface AppMetadata {
id: AppId;
name: string;
defaultLocale: string;
custom: Record<string, string>;
}
export { AudioBlock }
export declare interface AudioBlockProps extends ContentBlockProps {
block: AudioBlock;
downloadUrl?: string;
}
/**
* Audio player based on wavesurfer.
*
* @remarks
* Wavesurfer is designed to make SoundCloud-style sound wave players. It has no
* UI elements other than the actual sound waves, but it does abstract away all
* the audio playing browser internals very nicely.
*
* Also, it has some additional settings that let us turn the sound wave display
* into a series of nice rounded bars. Less signal, but also less distraction. I
* kinda like it!
*/
export declare function AudioPlayer({ src, onError, filename, className, }: AudioPlayerProps): JSX.Element;
export declare interface AudioPlayerProps {
src: string;
filename: string;
onError?: () => void;
className?: string;
}
export declare interface AvatarProps {
common: CommonChatboxProps | CommonConversationListProps;
photoUrl: string;
}
/**
* Brands a base type `T`.
*
* @example
* ```ts
* type UserId = Brand<string, "UserId">;
* type MessageId = Brand<string, "MessageId">;
*
* const a: UserId = "abc" as UserId; // works
* const b: UserId = "abc"; // error
* const c: UserId = "abc" as MessageId; // error
* ```
*/
declare type Brand<T, B extends string> = T & Branding<B>;
declare interface Branding<B extends string> {
__tag: Record<B, true>;
}
export declare interface Chatbox {
deleteMessage(messageId: string): Promise<void>;
setEditing(messageId: string | null): void;
editMessage(messageId: string, params: EditTextMessageParams | EditMessageParams): Promise<void>;
sendMessage(params: SendTextMessageParams | SendMessageParams): Promise<void>;
sendFileMessage(message: {
fileToken: FileToken;
custom?: Record<string, string>;
}): Promise<void>;
sendLocationMessage(message: {
location: Coordinates;
custom?: Record<string, string>;
}): Promise<void>;
setReferencedMessage(messageId: string | null): void;
getMessageFieldText: () => string;
setMessageFieldText: (text: string) => void;
}
export declare interface ChatHeaderProps {
common: CommonChatboxProps;
isUserConnected: {
[userId: string]: boolean;
};
permissions: UserPermissions;
}
export declare interface CommonChatboxProps {
app: AppMetadata;
currentUser: UserSnapshot;
t: Translation;
chatbox: Chatbox;
themeCustom?: any;
device: DeviceFeatures;
theme: Theme;
conversation: ConversationSnapshot;
participants: ParticipantSnapshot[];
typing: TypingSnapshot;
session: TalkSession;
}
export declare interface CommonConversationListProps {
app: AppMetadata;
currentUser: UserSnapshot;
t: Translation;
themeCustom?: any;
device: DeviceFeatures;
theme: Theme;
conversationList: ConversationList;
session: TalkSession;
}
export declare interface CompactMessageContentProps {
common: CommonChatboxProps | CommonConversationListProps;
message: MessageSnapshot | ReferencedMessageSnapshot;
}
export declare interface ContentBlockProps {
common: CommonChatboxProps;
message: MessageSnapshot;
}
export declare interface ConversationImageProps {
common: CommonChatboxProps | CommonConversationListProps;
conversation: ConversationSnapshot;
participants: ParticipantSnapshot[];
}
export declare interface ConversationList {
selectConversation(conversationId: string): void;
}
export declare interface ConversationListItemProps {
common: CommonConversationListProps;
conversation: ConversationSnapshot;
participants: ParticipantSnapshot[];
isSelected: boolean;
}
export { ConversationSnapshot }
export declare interface Coordinates {
latitude: number;
longitude: number;
}
export declare interface Coordinates {
latitude: number;
longitude: number;
}
export declare function daysBetween(from: number, to: number): number;
export declare interface DeviceFeatures {
/**
* True if the browser supports IndexedDB, which the emoji picker depends on.
*/
supportsEmojiPicker: boolean;
/**
* True if the user agents reports this device as mobile (incl tablets).
*/
isMobile: boolean;
}
export declare interface DeviceFeatures {
/**
* True if the browser supports IndexedDB, which the emoji picker depends on.
*/
supportsEmojiPicker: boolean;
/**
* True if the user agents reports this device as mobile (incl tablets).
*/
isMobile: boolean;
}
export declare function Editor({ placeholder, disabled, className, characterLimit, spellcheck, }: EditorProps): JSX.Element;
export declare interface EditorController {
isTyping: boolean;
atTextLimit: boolean;
isEmpty: boolean;
characterCount: number;
showEmojiPicker: boolean;
send(): void;
shareLocation(): void;
attachFile(): void;
toggleEmojiPicker(): void;
}
export declare interface EditorProps {
characterLimit?: number;
disabled?: boolean;
placeholder?: string;
className?: string;
spellcheck?: boolean;
}
export declare function EmojiPicker(props: EmojiPickerProps): JSX.Element;
export declare interface EmojiPickerProps {
colorScheme: "light" | "dark";
}
/**
* Shows a bar with emoji suggestions when the user types eg `:bla`. Shown if `query` is non-empty.
*
* Uses the IndexedDB-backed emoji database from "emoji-picker-element".
*/
export declare function EmojiSuggestBar(props: EmojiSuggestBarProps): JSX.Element;
export declare interface EmojiSuggestBarProps {
}
export { FileBlock }
export declare interface FileBlockProps extends ContentBlockProps {
block: FileBlock;
downloadUrl?: string;
}
export declare function formatDuration(seconds: number): string;
export declare function formatFilesize(bytes: number): string;
export declare function getFilename(block: FileBlock): string | undefined;
export declare function getGoogleMapsUrls({ latitude, longitude }: Coordinates): {
imageUrl: string;
linkUrl: string;
};
export declare function getPhotoUrlWithFallback(user: UserSnapshot): string;
export declare function getRandomColor(id: string): string;
export declare interface GroupChatImageProps {
common: CommonChatboxProps | CommonConversationListProps;
participants: ParticipantSnapshot[];
}
export declare function html(strings: TemplateStringsArray, ...args: any[]): ReactElement;
export declare interface IconProps {
common: CommonChatboxProps | CommonConversationListProps;
type: "attach" | "chevronLeft" | "left" | "chevronRight" | "right" | "chevronUp" | "up" | "chevronDown" | "down" | "close" | "emoji" | "locationPin" | "more" | "plus" | "search" | "send" | "spinner" | "play" | "pause" | "updown" | "addEmoji" | "microphone" | "mic" | "stop" | "download" | "location" | "email" | "movie" | "image" | "attachment" | "horizontalDots" | "verticalDots" | "reply" | "back";
className?: string;
}
export { ImageBlock }
export declare interface ImageBlockProps extends ContentBlockProps {
block: ImageBlock;
downloadUrl?: string;
}
export { LocationBlock }
export declare interface LocationBlockProps extends ContentBlockProps {
block: LocationBlock;
}
export declare function MentionSuggestList(props: MentionSuggestListProps): JSX.Element | null;
export declare interface MentionSuggestList {
keydown(key: string): boolean;
}
export declare interface MentionSuggestListProps {
}
export declare function MenuItem(props: MenuItemProps): JSX.Element;
export declare type MenuItemProps = React.HTMLAttributes<HTMLDivElement> & {
onSelect?: () => void;
disabled?: boolean;
textValue?: string;
};
export declare interface MessageActionMenuProps {
common: CommonChatboxProps;
message: MessageSnapshot;
permissions: MessagePermissions;
}
export declare function MessageContent(props: MessageContentProps): JSX.Element;
export declare interface MessageContentProps {
common: CommonChatboxProps;
message: MessageSnapshot;
messageStatus: MessageStatus;
className?: string;
}
export declare interface MessageDividerProps {
common: CommonChatboxProps;
isReadMarker: boolean;
isDayMarker: boolean;
timestamp?: number;
}
export declare interface MessageFieldProps {
common: CommonChatboxProps;
referencedMessage: MessageSnapshot | undefined;
permissions: UserPermissions;
editor: EditorController;
editMessageId: string | undefined;
}
export declare interface MessageListFooterProps {
common: CommonChatboxProps;
}
export declare interface MessagePermissions extends UserPermissions {
canDeleteMessage: boolean;
canReplyToMessage: boolean;
canEditMessage: boolean;
canAddReaction: boolean;
}
export declare interface MessagePermissions extends UserPermissions {
canDeleteMessage: boolean;
canReplyToMessage: boolean;
canEditMessage: boolean;
}
export declare interface MessageProps {
common: CommonChatboxProps;
message: MessageSnapshot;
messageStatus: MessageStatus;
permissions: MessagePermissions;
}
export { MessageSnapshot }
export declare type MessageStatus = "sending" | "sent" | "everyoneRead";
export { ParticipantSnapshot }
/**
* PopoverButton component that renders a popover triggered by a button.
*
* Usage:
* <PopoverButton
* popoverComponent={YourMenuComponent}
* popoverProps={{ prop1: value1, prop2: value2 }}
* aria-label="..."
* >
* <Icon type="horizontalDots" />
* </MenuButton>
*
* All props except for menuComponent and popoverProps are passed to the button element.
*
* the popoverComponent will also receive a closePopover prop. It's a function you can call to close the popover.
*/
export declare function PopoverButton<T extends object>(props: PopoverButtonProps<T>): JSX.Element;
export declare type PopoverButtonProps<T extends object> = {
popoverComponent: React.ComponentType<T>;
popoverProps: T;
children: React.ReactNode;
type?: "menu" | "popover";
} & React.HTMLAttributes<HTMLButtonElement>;
export declare function ReactionPicker(props: ReactionPickerProps): JSX.Element;
export declare type ReactionPickerProps = default_2.HTMLAttributes<HTMLDivElement> & {
messageId: string;
colorScheme: "light" | "dark";
};
export declare interface ReferencedMessageProps {
common: CommonChatboxProps;
referencedMessage: ReferencedMessageSnapshot;
}
export { ReferencedMessageSnapshot }
export declare interface ReplyBarProps {
common: CommonChatboxProps;
referencedMessage: MessageSnapshot;
}
export { TalkSession }
declare function Text_2({ block, nonInteractive, className, }: TextProps): ReactElement;
export { Text_2 as Text }
export { TextBlock }
export declare interface TextBlockProps extends ContentBlockProps {
block: TextBlock;
}
export declare interface TextProps {
block: TextBlock;
className?: string;
nonInteractive?: boolean;
}
export declare interface Theme {
Avatar: React_2.ComponentType<AvatarProps>;
ConversationImage: React_2.ComponentType<ConversationImageProps>;
GroupChatImage: React_2.ComponentType<GroupChatImageProps>;
ReferencedMessage: React_2.ComponentType<ReferencedMessageProps>;
ReplyBar: React_2.ComponentType<ReplyBarProps>;
TimeAgo: React_2.ComponentType<TimeAgoProps>;
MessageActionMenu: React_2.ComponentType<MessageActionMenuProps>;
CompactMessageContent: React_2.ComponentType<CompactMessageContentProps>;
ChatHeader: React_2.ComponentType<ChatHeaderProps>;
Message: React_2.ComponentType<MessageProps>;
MessageField: React_2.ComponentType<MessageFieldProps>;
Icon: React_2.ComponentType<IconProps>;
MessageDivider: React_2.ComponentType<MessageDividerProps>;
MessageListFooter: React_2.ComponentType<MessageListFooterProps>;
TextBlock: React_2.ComponentType<TextBlockProps>;
FileBlock: React_2.ComponentType<FileBlockProps>;
LocationBlock: React_2.ComponentType<LocationBlockProps>;
ImageBlock: React_2.ComponentType<ImageBlockProps>;
AudioBlock: React_2.ComponentType<AudioBlockProps>;
VoiceBlock: React_2.ComponentType<VoiceBlockProps>;
VideoBlock: React_2.ComponentType<VideoBlockProps>;
ConversationListItem: React_2.ComponentType<ConversationListItemProps>;
}
export declare interface TimeAgo {
/**
* An amount of milliseconds after which the values in `long` and `short` _may_ have changed.
* If undefined, the values will not change within any meaningful period.
*/
changeTimeout?: number | undefined;
long: string;
short: string;
}
export declare interface TimeAgoProps {
common: CommonChatboxProps;
timestamp: number;
}
export declare type Translation = TranslationData & TranslationStrings;
declare interface TranslationData {
locale: string;
}
declare interface TranslationStrings {
YESTERDAY: string;
TODAY: string;
DAYS: string;
HOURS: string;
MINUTES: string;
JUST_NOW: string;
LOCATION: string;
CANCEL: string;
INBOX: string;
DESKTOP_NOTIFICATIONS: string;
DESKTOP_NOTIFICATIONS_ERROR: string;
DESKTOP_NOTIFICATIONS_DEMO_TITLE: (appName: string) => string;
DESKTOP_NOTIFICATIONS_DEMO_BODY: string;
SEND_BUTTON_TEXT: string;
ENTRYBOX_TEXT_LIMIT: string;
ENTRYBOX_PLACEHOLDER: string;
ENTRYBOX_PLACEHOLDER_CHAT_CLOSED: string;
ENTRYBOX_PLACEHOLDER_CHAT_READONLY: string;
MESSAGELIST_LOADING_OLDER: string;
MESSAGELIST_SHOW_OLDER: string;
MESSAGELIST_NEW_MARKER: string;
MESSAGE_SENT_VIA_EMAIL: string;
YOU_MARKER: string;
UPLOAD_IN_PROGRESS: string;
UPLOAD_SEND_FILE: string;
UPLOAD_SHARE_LOCATION: string;
UPLOAD_ERROR: string;
SHARE_LOCATION_ERROR: string;
LOADING: string;
HUB_EMPTY: string;
HUB_SHOW_EARLIER: string;
INBOX_NO_CHATS_TITLE: string;
INBOX_NO_CHATS_BODY: string;
ENABLE_TRANSLATION: string;
DISABLE_TRANSLATION: string;
SEARCH_PLACEHOLDER_TEXT: string;
SEARCH_SEARCHING: string;
SEARCH_NO_RESULTS: string;
SEARCH_NO_MORE_RESULTS: string;
CHAT_NOT_FOUND: string;
DELETE_MESSAGE: string;
DELETION_EXPLANATION: string;
EDIT_MESSAGE: string;
SAVE: string;
EDITED_INDICATOR: string;
REPLY_TO_MESSAGE: string;
REPLY_TO_ARIA_LABEL: (senderName: string, content: string) => string;
REPLY_MODE_LEAVE_ARIA_LABEL: string;
ADD_REACTION: string;
AUTH_EXPIRED_OVERLAY_TITLE: string;
AUTH_EXPIRED_OVERLAY_DESCRIPTION: string;
VOICE_MESSAGE: string;
LEAVE_CONVERSATION: string;
MARK_CONVERSATION_AS_UNREAD: string;
STATUS_INDICATOR_ONLINE: string;
STATUS_INDICATOR_OFFLINE: string;
CONTACT_INFORMATION_HIDDEN: string;
}
/**
* Formats a time in the past in a twitter-like fashion.
*/
export declare function twitterAgo(now: number, ts: number, t: Translation): TimeAgo;
export { TypingSnapshot }
/**
* returns "Yesterday", "Last Monday", "Tuesday, March 31" or "Monday, March 31 2014", depending on which is most appropriate.
* @param ts number - unix timestamp (milliseconds)
*/
export declare function userFriendlyDate(ts: number, t: Translation): string;
export declare interface UserPermissions {
showTypingIndicator: boolean;
canShareFile: boolean;
canShareLocation: boolean;
canMention: boolean;
showOnlineStatus: boolean;
canSendVoiceMessage: boolean;
canLeaveConversation: boolean;
canMarkConversationAsUnread: boolean;
}
export declare interface UserPermissions {
showTypingIndicator: boolean;
canShareFile: boolean;
canShareLocation: boolean;
canMention: boolean;
showOnlineStatus: boolean;
canSendVoiceMessage: boolean;
canLeaveConversation: boolean;
canMarkConversationAsUnread: boolean;
}
export { UserSnapshot }
/**
*
* This hooks triggers only when a human-readable timestamp needs to be updated.
* For example, you could use it to display that a messages was updated X
* minutes or Y hours ago.
*
* @public
*/
export declare function useTimeAgo(timestamp: number, t: Translation): TimeAgo;
export { VideoBlock }
export declare interface VideoBlockProps extends ContentBlockProps {
block: VideoBlock;
downloadUrl?: string;
}
export { VoiceBlock }
export declare interface VoiceBlockProps extends ContentBlockProps {
block: VoiceBlock;
downloadUrl?: string;
}
export { }
declare global {
namespace JSX {
interface IntrinsicElements {
"emoji-picker": {
class?: string;
ref: React.Ref<HTMLElement>;
};
}
}
interface HTMLElementEventMap {
"emoji-click": EmojiClickEvent;
"skin-tone-change": SkinToneChangeEvent;
}
}
declare global {
interface HTMLElementTagNameMap {
"t-chatbox": ChatboxHTMLElement;
"t-conversation-list": ConversationListHTMLElement;
}
}
declare global {
namespace JSX {
interface IntrinsicElements {
"t-chatbox": typeof UnthemedChatbox;
"t-conversation-list": typeof UnthemedConversationList;
}
}
}