UNPKG

@liveblocks/react-ui

Version:

A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.

498 lines (485 loc) 16.3 kB
import * as react from 'react'; import { ElementType, ComponentPropsWithoutRef, ReactNode, ComponentType, FormEvent } from 'react'; import { CommentBody as CommentBody$1, CommentAttachment, CommentMixedAttachment } from '@liveblocks/core'; type Direction = "ltr" | "rtl"; type SlotProp = { /** * Replace the rendered element by the one passed as a child. */ asChild?: boolean; }; type ComponentPropsWithSlot<TElement extends ElementType<any>> = ComponentPropsWithoutRef<TElement> & SlotProp; type ComposerBodyText = { bold?: boolean; italic?: boolean; strikethrough?: boolean; code?: boolean; text: string; }; type ComposerBodyMark = keyof Omit<ComposerBodyText, "text">; type ComposerBodyMarks = { [K in ComposerBodyMark]: boolean; }; type CommentMentionProps = ComponentPropsWithSlot<"span">; type CommentBodyMentionProps = { /** * The mention's user ID. */ userId: string; }; type CommentLinkProps = ComponentPropsWithSlot<"a">; interface CommentBodyLinkProps { /** * The link's absolute URL. * * @example "https://example.com" */ href: string; /** * The link's content. * * @example "www.example.com", "a link", etc. */ children: ReactNode; } interface CommentBodyComponents { /** * The component used to display mentions. */ Mention: ComponentType<CommentBodyMentionProps>; /** * The component used to display links. */ Link: ComponentType<CommentBodyLinkProps>; } interface CommentBodyProps extends Omit<ComponentPropsWithSlot<"div">, "children"> { /** * The comment body to display. * If not defined, the component will render `null`. */ body?: CommentBody$1; /** * The components displayed within the comment body. */ components?: Partial<CommentBodyComponents>; } /** * Displays mentions within `Comment.Body`. * * @example * <Comment.Mention>@{userId}</Comment.Mention> */ declare const CommentMention: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & SlotProp & react.RefAttributes<HTMLSpanElement>>; /** * Displays links within `Comment.Body`. * * @example * <Comment.Link href={href}>{children}</Comment.Link> */ declare const CommentLink: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & SlotProp & react.RefAttributes<HTMLAnchorElement>>; /** * Displays a comment body. * * @example * <Comment.Body body={comment.body} /> */ declare const CommentBody: react.ForwardRefExoticComponent<CommentBodyProps & react.RefAttributes<HTMLDivElement>>; declare namespace index$1 { export { CommentBody as Body, CommentLink as Link, CommentMention as Mention, }; } interface ComposerEditorMentionProps { /** * Whether the mention is selected. */ isSelected: boolean; /** * The mention's user ID. */ userId: string; } interface ComposerEditorLinkProps { /** * The link's absolute URL. * * @example "https://example.com" */ href: string; /** * The link's content. * * @example "www.example.com", "a link", etc. */ children: ReactNode; } type ComposerEditorMentionSuggestionsProps = { /** * The list of suggested user IDs. */ userIds: string[]; /** * The currently selected user ID. */ selectedUserId?: string; }; type ComposerEditorFloatingToolbarProps = Record<string, never>; type ComposerMentionProps = ComponentPropsWithSlot<"span">; type ComposerLinkProps = ComponentPropsWithSlot<"a">; type ComposerFloatingToolbarProps = ComponentPropsWithSlot<"div">; type ComposerSuggestionsListProps = ComponentPropsWithSlot<"ul">; interface ComposerSuggestionsListItemProps extends ComponentPropsWithSlot<"li"> { /** * The suggestion's value. */ value: string; } interface ComposerEditorComponents { /** * The component used to display mentions. */ Mention: ComponentType<ComposerEditorMentionProps>; /** * The component used to display mention suggestions. */ MentionSuggestions: ComponentType<ComposerEditorMentionSuggestionsProps>; /** * The component used to display links. */ Link: ComponentType<ComposerEditorLinkProps>; /** * The component used to display a floating toolbar attached to the selection. */ FloatingToolbar?: ComponentType<ComposerEditorFloatingToolbarProps>; } interface ComposerEditorProps extends Omit<ComponentPropsWithoutRef<"div">, "defaultValue"> { /** * The reading direction of the editor and related elements. */ dir?: Direction; /** * The editor's initial value. */ defaultValue?: CommentBody$1; /** * The text to display when the editor is empty. */ placeholder?: string; /** * Whether the editor is disabled. */ disabled?: boolean; /** * Whether to focus the editor on mount. */ autoFocus?: boolean; /** * The components displayed within the editor. */ components?: Partial<ComposerEditorComponents>; } interface ComposerFormProps extends ComponentPropsWithSlot<"form"> { /** * The event handler called when the form is submitted. */ onComposerSubmit?: (comment: ComposerSubmitComment, event: FormEvent<HTMLFormElement>) => Promise<void> | void; /** * Whether the composer is disabled. */ disabled?: boolean; /** * The composer's initial attachments. */ defaultAttachments?: CommentAttachment[]; /** * Whether to create attachments when pasting files into the editor. */ pasteFilesAsAttachments?: boolean; /** * When `preventUnsavedChanges` is set on your Liveblocks client (or set on * <LiveblocksProvider>), then closing a browser tab will be prevented when * there are unsaved changes. * * By default, that will include draft texts or attachments that are (being) * uploaded via this composer, but not submitted yet. * * If you want to prevent unsaved changes with Liveblocks, but not for this * composer, you can opt-out this composer instance by setting this prop to * `false`. */ preventUnsavedChanges?: boolean; } type ComposerSubmitProps = ComponentPropsWithSlot<"button">; type ComposerAttachFilesProps = ComponentPropsWithSlot<"button">; interface ComposerMarkToggleProps extends ComponentPropsWithSlot<"button"> { /** * The text mark to toggle. */ mark: ComposerBodyMark; /** * The event handler called when the mark is toggled. */ onValueChange?: (mark: ComposerBodyMark) => void; } interface ComposerAttachmentsDropAreaProps extends ComponentPropsWithSlot<"div"> { disabled?: boolean; } interface ComposerSubmitComment { /** * The submitted comment's body. */ body: CommentBody$1; /** * The submitted comment's uploaded attachments. */ attachments: CommentAttachment[]; } /** * Displays a floating toolbar attached to the selection within `Composer.Editor`. * * @example * <Composer.FloatingToolbar> * <Composer.MarkToggle mark="bold">Bold</Composer.MarkToggle> * <Composer.MarkToggle mark="italic">Italic</Composer.MarkToggle> * </Composer.FloatingToolbar> */ declare const ComposerFloatingToolbar: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & SlotProp & react.RefAttributes<HTMLDivElement>>; /** * Displays mentions within `Composer.Editor`. * * @example * <Composer.Mention>@{userId}</Composer.Mention> */ declare const ComposerMention: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & SlotProp & react.RefAttributes<HTMLSpanElement>>; /** * Displays links within `Composer.Editor`. * * @example * <Composer.Link href={href}>{children}</Composer.Link> */ declare const ComposerLink: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, "ref"> & SlotProp & react.RefAttributes<HTMLAnchorElement>>; /** * Contains suggestions within `Composer.Editor`. */ declare const ComposerSuggestions: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & SlotProp & react.RefAttributes<HTMLDivElement>>; /** * Displays a list of suggestions within `Composer.Editor`. * * @example * <Composer.SuggestionsList> * {userIds.map((userId) => ( * <Composer.SuggestionsListItem key={userId} value={userId}> * @{userId} * </Composer.SuggestionsListItem> * ))} * </Composer.SuggestionsList> */ declare const ComposerSuggestionsList: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & SlotProp & react.RefAttributes<HTMLUListElement>>; /** * Displays a suggestion within `Composer.SuggestionsList`. * * @example * <Composer.SuggestionsListItem key={userId} value={userId}> * @{userId} * </Composer.SuggestionsListItem> */ declare const ComposerSuggestionsListItem: react.ForwardRefExoticComponent<ComposerSuggestionsListItemProps & react.RefAttributes<HTMLLIElement>>; /** * Displays the composer's editor. * * @example * <Composer.Editor placeholder="Write a comment…" /> */ declare const ComposerEditor: react.ForwardRefExoticComponent<ComposerEditorProps & react.RefAttributes<HTMLDivElement>>; /** * Surrounds the composer's content and handles submissions. * * @example * <Composer.Form onComposerSubmit={({ body }) => {}}> * <Composer.Editor /> * <Composer.Submit /> * </Composer.Form> */ declare const ComposerForm: react.ForwardRefExoticComponent<ComposerFormProps & react.RefAttributes<HTMLFormElement>>; /** * A button to submit the composer. * * @example * <Composer.Submit>Send</Composer.Submit> */ declare const ComposerSubmit: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & SlotProp & react.RefAttributes<HTMLButtonElement>>; /** * A button which opens a file picker to create attachments. * * @example * <Composer.AttachFiles>Attach files</Composer.AttachFiles> */ declare const ComposerAttachFiles: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLProps<react.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & SlotProp & react.RefAttributes<HTMLButtonElement>>; /** * A drop area which accepts files to create attachments. * * @example * <Composer.AttachmentsDropArea> * Drop files here * </Composer.AttachmentsDropArea> */ declare const ComposerAttachmentsDropArea: react.ForwardRefExoticComponent<ComposerAttachmentsDropAreaProps & react.RefAttributes<HTMLDivElement>>; /** * A toggle button which toggles a specific text mark. * * @example * <Composer.MarkToggle mark="bold"> * Bold * </Composer.MarkToggle> */ declare const ComposerMarkToggle: react.ForwardRefExoticComponent<ComposerMarkToggleProps & react.RefAttributes<HTMLButtonElement>>; declare namespace index { export { ComposerAttachFiles as AttachFiles, ComposerAttachmentsDropArea as AttachmentsDropArea, ComposerEditor as Editor, ComposerFloatingToolbar as FloatingToolbar, ComposerForm as Form, ComposerLink as Link, ComposerMarkToggle as MarkToggle, ComposerMention as Mention, ComposerSubmit as Submit, ComposerSuggestions as Suggestions, ComposerSuggestionsList as SuggestionsList, ComposerSuggestionsListItem as SuggestionsListItem, }; } type ComposerContext = { /** * Whether the composer is currently disabled. */ isDisabled: boolean; /** * Whether the composer can currently be submitted. */ canSubmit: boolean; /** * Whether the editor is currently focused. */ isFocused: boolean; /** * Whether the editor is currently empty. */ isEmpty: boolean; /** * Submit the composer programmatically. */ submit: () => void; /** * Clear the composer programmatically. */ clear: () => void; /** * Select the editor programmatically. */ select: () => void; /** * Focus the editor programmatically. */ focus: () => void; /** * Blur the editor programmatically. */ blur: () => void; /** * Which text marks are currently active and which aren't. */ marks: ComposerBodyMarks; /** * Toggle a specific text mark. */ toggleMark: (mark: ComposerBodyMark) => void; /** * Start creating a mention at the current selection. */ createMention: () => void; /** * Insert text at the current selection. */ insertText: (text: string) => void; /** * Open a file picker programmatically to create attachments. */ attachFiles: () => void; /** * The composer's current attachments. */ attachments: CommentMixedAttachment[]; /** * Remove an attachment by its ID. */ removeAttachment: (attachmentId: string) => void; }; declare const ComposerContext: react.Context<ComposerContext | null>; declare function useComposer(): ComposerContext; declare class AttachmentTooLargeError extends Error { origin: "client" | "server"; name: string; constructor(message: string, origin?: "client" | "server"); } interface FileSizeProps extends Omit<ComponentPropsWithSlot<"span">, "children"> { /** * The file size to display. */ size: number; /** * A function to format the displayed file size. */ children?: (size: number, locale?: string) => ReactNode; /** * The locale used when formatting the file size. */ locale?: string; } /** * Displays a formatted file size. * * @example * <FileSize size={100000} /> */ declare const FileSize: react.ForwardRefExoticComponent<FileSizeProps & react.RefAttributes<HTMLSpanElement>>; interface TimestampProps extends Omit<ComponentPropsWithSlot<"time">, "children" | "title"> { /** * The date to display. */ date: Date | string | number; /** * A function to format the displayed date. */ children?: (date: Date, locale?: string) => ReactNode; /** * The `title` attribute's value or a function to format it. */ title?: string | ((date: Date, locale?: string) => string); /** * The interval in milliseconds at which the component will re-render. * Can be set to `false` to disable re-rendering. */ interval?: number | false; /** * The locale used when formatting the date. */ locale?: string; } /** * Displays a formatted date, and automatically re-renders to support relative * formatting. Defaults to relative formatting for recent dates and a short * absolute formatting for older ones. * * @example * <Timestamp date={new Date()} /> * * @example * <Timestamp date={new Date()} title={(date) => date.toISOString()} interval={false}> * {(date) => date.toLocaleDateString()} * </Timestamp> */ declare const Timestamp: react.ForwardRefExoticComponent<TimestampProps & react.RefAttributes<HTMLTimeElement>>; export { AttachmentTooLargeError, index$1 as Comment, CommentBodyComponents, CommentBodyLinkProps, CommentBodyMentionProps, CommentBodyProps, CommentLinkProps, CommentMentionProps, index as Composer, ComposerAttachFilesProps, ComposerAttachmentsDropAreaProps, ComposerBodyMark, ComposerBodyMarks, ComposerContext, ComposerEditorComponents, ComposerEditorFloatingToolbarProps, ComposerEditorLinkProps, ComposerEditorMentionProps, ComposerEditorMentionSuggestionsProps, ComposerEditorProps, ComposerFloatingToolbarProps, ComposerFormProps, ComposerLinkProps, ComposerMarkToggleProps, ComposerMentionProps, ComposerSubmitComment, ComposerSubmitProps, ComposerSuggestionsListItemProps, ComposerSuggestionsListProps, FileSize, FileSizeProps, Timestamp, TimestampProps, useComposer };