UNPKG

@talkjs/web-components

Version:

Provides chat UI components for TalkJS.

524 lines (436 loc) 16.1 kB
import { AudioBlock } from '@talkjs/core'; import { ConversationSnapshot } from '@talkjs/core'; 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 extends BaseChatboxProps { photoUrl: string; } export declare interface BaseChatboxProps { common: CommonChatboxProps; } /** * 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 extends BaseChatboxProps { 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; } export declare interface ContentBlockProps extends BaseChatboxProps { message: MessageSnapshot; } export declare interface ConversationImageProps extends BaseChatboxProps { } export { ConversationSnapshot } 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 function Editor({ placeholder, disabled, className, characterLimit, spellcheck, }: EditorProps): JSX.Element; export declare interface EditorController extends EditorState { send(): void; shareLocation(): void; attachFile(): void; toggleEmojiPicker(): void; } export declare interface EditorProps { characterLimit?: number; disabled?: boolean; placeholder?: string; className?: string; spellcheck?: boolean; } declare interface EditorState { isTyping: boolean; atTextLimit: boolean; isEmpty: boolean; characterCount: number; showEmojiPicker: boolean; } export declare function EmojiPicker(props: EmojiPickerProps): JSX.Element; export declare interface EmojiPickerProps { colorScheme: "light" | "dark"; } 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 extends BaseChatboxProps { } export declare function html(strings: TemplateStringsArray, ...args: any[]): ReactElement; export declare interface IconProps extends BaseChatboxProps { 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; } /** * MenuButton component that renders a dropdown menu triggered by a button. * * Usage: * <MenuButton * menuComponent={YourMenuComponent} * menuProps={{ prop1: value1, prop2: value2 }} * aria-label="Message actions" * > * <Icon type="horizontalDots" /> * </MenuButton> * * All props except for menuComponent and menuProps are passed to the button element. * * The menuComponent should be a component that renders the dropdown content. * The menuProps are passed to the menuComponent. * * The menu component shouod render the MenuItem component for each menu item it wants to include. * * This is meant as a reuseable and accessible dropdown menu. We're using Radix for this, because they fulli implement * the ARIA Menu Button pattern, but without adding any styles, so we can completely customise the look and feel. */ export declare function MenuButton<T extends object>(props: MenuButtonProps<T>): JSX.Element; export declare type MenuButtonProps<T extends object> = { menuComponent: React.ComponentType<T>; menuProps: T; children: React.ReactNode; } & React.HTMLAttributes<HTMLButtonElement>; 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 extends BaseChatboxProps { } export declare function MessageContent(props: MessageContentProps): JSX.Element; export declare interface MessageContentProps extends BaseChatboxProps { message: MessageSnapshot; messageStatus: MessageStatus; className?: string; } export declare interface MessageDividerProps extends BaseChatboxProps { isReadMarker: boolean; isDayMarker: boolean; timestamp?: number; } export declare interface MessageFieldProps extends BaseChatboxProps { referencedMessage: MessageSnapshot | undefined; permissions: UserPermissions; editor?: EditorController; editMessageId: string | undefined; } export declare interface MessageListFooterProps extends BaseChatboxProps { } export declare interface MessagePermissions extends UserPermissions { canDeleteMessage: boolean; canReplyToMessage: boolean; canEditMessage: boolean; } export declare interface MessageProps extends BaseChatboxProps { message: MessageSnapshot; messageStatus: MessageStatus; permissions: MessagePermissions; } export { MessageSnapshot } export declare type MessageStatus = "sending" | "sent" | "everyoneRead"; export { ParticipantSnapshot } export declare interface ReferencedMessageProps extends BaseChatboxProps { referencedMessage: ReferencedMessageSnapshot; } export { ReferencedMessageSnapshot } export declare interface ReplyBarProps extends BaseChatboxProps { referencedMessage: MessageSnapshot; } export { TalkSession } declare function Text_2({ block, 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; } 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>; 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>; } 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 extends BaseChatboxProps { 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 { 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; } } declare global { namespace JSX { interface IntrinsicElements { "t-chatbox": typeof UnthemedChatbox; } } }