Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Poll components

Poll renders the poll of a message. It provides PollContext and renders the poll's content: the question, the options and the buttons. MessageContent renders it for every message with a poll_id, with the poll from client.polls.fromState(message.poll_id). CreatePoll is the form that creates a poll from the composer. Polls explains how polls are created, voted on and kept current.

Best practices

  • Read live poll data from poll.state, with usePollState() or useStateStore(poll.state, selector). message.poll is only the copy that came with the message.
  • Replace parts through the override keys below, and keep Poll, which provides the context.
  • Render poll parts inside a message, in a Channel or a Thread. The vote button reads the user's capabilities from the channel, and the buttons read the poll and the message from PollContext.
  • To show the poll's screens in your navigation instead of in modals, pass onPress to the buttons, as Change the buttons shows. Render the screen's component, such as PollResults, with the message and poll it receives.
  • Keep option texts short, so the message stays readable.

Basic usage

Poll renders without your help in every message that carries a poll. To show one elsewhere, render it with the message and the poll from the client:

src/PinnedPoll.tsx
import type { LocalMessage } from "stream-chat";
import { Poll, useChatContext } from "stream-chat-react-native";

export const PinnedPoll = ({ message }: { message: LocalMessage }) => {
  const { client } = useChatContext();
  const poll = message.poll_id
    ? client.polls.fromState(message.poll_id)
    : undefined;

  if (!poll) return null;

  return <Poll message={message} poll={poll} />;
};

Render it inside the Channel or Thread of the message.

Poll UI customization

Poll is built from these parts. The ones with an override key are replaced through WithComponents.

Part Override key Rendered by Shows
PollContent PollContent Poll The whole poll: PollHeader, the first five options, ShowAllOptionsButton and PollButtons. The key has no default: without it, Poll renders the exported PollContent.
PollHeader PollHeader PollContent The question, and "Select one", "Select up to 3", "Select one or more" or "Poll has ended"
PollOption none PollContent One option: VoteButton, the text, the avatars of the latest voters, the vote count and a bar
VoteButton none PollOption A checkbox, or a radio button when only one vote is allowed, while the user can vote
ShowAllOptionsButton none PollContent "+3 More Options", when the poll has more than five options. Opens PollAllOptions in a PollModal
PollButtons PollButtons PollContent ViewResultsButton, EndVoteButton, SuggestOptionButton, AddCommentButton and ShowAllCommentsButton
PollAllOptionsContent PollAllOptionsContent PollAllOptions The question and every option, with their vote buttons
PollResultsContent PollResultsContent PollResults The question and the options sorted by votes, each with its five latest votes
PollOptionFullResultsContent PollOptionFullResultsContent PollOptionFullResults Every vote for one option, loaded a page at a time
PollAnswersListContent PollAnswersListContent PollAnswersList The comments, loaded a page at a time, with a button under the user's own comment to update it
CreatePollContent CreatePollContent CreatePoll The poll creation form. The key has no default: without it, CreatePoll renders the exported CreatePollContent

The buttons of PollButtons, and when each shows:

Button Shows when Opens
ViewResultsButton always PollResults in a PollModal
EndVoteButton the poll is open and the user created it nothing: it closes the poll
SuggestOptionButton the poll is open and allows suggestions a PollInputDialog for the new option
AddCommentButton the poll is open and allows comments a PollInputDialog with the user's comment
ShowAllCommentsButton the poll has comments PollAnswersList in a PollModal

In PollResultsContent, an option with more than five votes has ShowAllVotesButton, "Show All", when the user has the query-poll-votes capability. It opens PollOptionFullResults. VoteButton shows while the user has cast-poll-vote and the poll is open; pressing it casts the vote, or removes it when the user already voted for the option.

Replace a part

This PollContent shows three options, and keeps the SDK's header and buttons:

src/pollOverrides.tsx
import { StyleSheet, View } from "react-native";
import {
  PollButtons,
  PollHeader,
  PollOption,
  usePollState,
} from "stream-chat-react-native";
import type { ComponentOverrides } from "stream-chat-react-native";

const ThreeOptionPollContent = () => {
  const { options } = usePollState();

  return (
    <View style={styles.container}>
      <PollHeader />
      {options.slice(0, 3).map((option) => (
        <PollOption key={option.id} option={option} />
      ))}
      <PollButtons />
    </View>
  );
};

// Pass to `WithComponents`, declared once at module scope.
export const pollOverrides: ComponentOverrides = {
  PollContent: ThreeOptionPollContent,
};

const styles = StyleSheet.create({
  container: { gap: 12, padding: 12, width: 256 },
});

The header and the buttons here are the exported defaults, so the PollHeader and PollButtons keys don't apply to this poll. Render the keys' components from useComponentsContext() to keep them. Polls replaces the header.

A part of your own that shows who voted handles anonymous polls itself, as usePollState describes.

Props

Poll

Prop Type Default Description
poll Poll required The poll, a Poll from stream-chat, from client.polls.fromState(pollId).
message LocalMessage required The message that carries the poll. Votes and comments are sent for it.

PollContent, PollHeader, PollButtons, EndVoteButton and CreatePollContent take no props; they read the poll from PollContext or the form from CreatePollContentContext. PollContentProps is exported and has no members.

PollOption

Prop Type Default Description
option PollOptionResponseData required The option.
showProgressBar boolean true Shows the bar under the option, its share of all votes.
forceIncoming boolean none Uses the colors of an incoming message, whoever created the poll. PollAllOptionsContent sets it.

VoteButton

Prop Type Default Description
option PollOptionResponseData required The option the button votes for.
onPress ({ message, poll }: { message: LocalMessage; poll: Poll }) => void none Called on press, in place of casting or removing the vote.
forceIncoming boolean none Uses the colors of an incoming message.
style StyleProp<ViewStyle> none Not applied.

PollVoteButtonProps is the type of these props.

Buttons

ViewResultsButton, ShowAllOptionsButton, SuggestOptionButton, AddCommentButton, ShowAllCommentsButton and AnswerListAddCommentButton take PollButtonProps:

Prop Type Default Description
onPress ({ message, poll }: { message: LocalMessage; poll: Poll }) => void none Called on press with the message and the poll, in place of opening the button's modal or dialog.

ShowAllVotesButton takes ShowAllVotesButtonProps:

Prop Type Default Description
option PollOptionResponseData required The option whose votes it opens.
onPress ({ message, option, poll, }: { message: LocalMessage; option: PollOptionResponseData; poll: Poll; }) => void none Called on press, in place of opening PollOptionFullResults.

GenericPollButton is the button they render, for a button of your own. It takes GenericPollButtonProps, every prop of the SDK's Button made optional, with variant "secondary", type "ghost" and size "sm" by default. Its main props are label, onPress, LeadingIcon, TrailingIcon, iconOnly, selected, variant ("primary", "secondary" or "destructive"), type ("solid", "outline" or "ghost"), size ("sm", "md" or "lg"), accessibilityLabelKey and accessibilityLabelParams; see Buttons and inputs.

Poll screens

Each screen takes the message and the poll, provides PollContext with them, and renders its content override. A screen of your own renders them with what a button's onPress received.

Component Props Renders
PollResults message: LocalMessage, poll: Poll, additionalScrollViewProps?: Partial<ScrollViewProps> PollResultsContent
PollAllOptions message: LocalMessage, poll: Poll, additionalScrollViewProps?: Partial<ScrollViewProps> PollAllOptionsContent
PollAnswersList message: LocalMessage, poll: Poll, additionalFlatListProps?: Partial<FlatListProps<PollVoteResponseData>> PollAnswersListContent
PollOptionFullResults message: LocalMessage, poll: Poll, option: PollOptionResponseData, additionalFlatListProps?: Partial<FlatListProps<PollVoteClass>> PollOptionFullResultsContent

The content overrides get the same props without message and poll: additionalScrollViewProps, additionalFlatListProps and, for PollOptionFullResultsContent, option. The additional props are spread onto the ScrollView or FlatList after the SDK's own, so they replace them. PollResultsProps, PollAllOptionsContentProps, PollAnswersListProps and PollOptionFullResultsProps are the screens' prop types. PollVoteClass is PollVoteResponseData from stream-chat.

PollResultsItem renders one option in the results, with option: PollOptionResponseData and its index: number in the sorted list. PollAnswerListItem renders one comment, with answer: PollVoteResponseData; it hides the author of another user's comment in an anonymous poll, and renders AnswerListAddCommentButton under the user's own.

PollModal

PollModal is the React Native Modal the buttons open their screens in. It presents as a page sheet on iOS and draws under the system bars on Android.

Prop Type Default Description
visible boolean none Whether the modal is open.
onRequestClose () => void none Called when the user dismisses it, such as with the Android back button.
animationType ModalProps['animationType'] "slide" How it opens.
children ReactNode none The screen.

PollModalHeader is the header of the screens:

Prop Type Default Description
title string required The title.
onPress () => void required Called by the close button.

PollInputDialog is the dialog of SuggestOptionButton and AddCommentButton:

Prop Type Default Description
visible boolean required Whether the dialog is open.
title string required The title.
placeholder string required The input's placeholder.
onSubmit (text: string) => void required Called with the text when the user submits.
closeDialog () => void required Closes the dialog.
initialValue string "" The text the input starts with.

CreatePoll

CreatePoll provides CreatePollContentContext and renders the CreatePollContent override, or the default form. MessageComposer renders it in a PollModal while the poll creation dialog is open. When it unmounts, it resets the composer's pollComposer.

Prop Type Default Description
sendMessage () => Promise<void> required Sends the composer's message after the poll is created. MessageComposer passes sendMessage from MessageInputContext.
closePollCreationDialog () => void none Called to close the form, after a send or by the back button of its header.
createPollOptionGap number 8 The gap between the options of the form, in points.

The default form has a header with a back button and a send button, the question, the options, which the user can drag to reorder, and switches for multiple votes with a maximum, anonymous voting, suggested options and comments. Each field writes into messageComposer.pollComposer. The SDK exports CreatePollOptions, the list of options, and MultipleVotesSettings, the multiple-votes switch and its maximum, for a form of your own built from them; the question field and the header aren't exported.

PollContext

Poll and the poll screens provide PollContext. usePollContext() reads it, and throws outside one.

Value Type Description
poll Poll The Poll instance from client.polls.
message LocalMessage The message that carries the poll.

PollContext and PollContextProvider, which takes a value of this type, are exported too. The poll's state is in poll.state; Poll hooks lists its fields and what usePollState() returns.

CreatePollContentContext

CreatePoll provides CreatePollContentContext. useCreatePollContentContext() reads it, and throws outside CreatePoll.

Value Type Description
createAndSendPoll () => Promise<void> Creates the poll with MessageComposer.createPoll(), sends the message with sendMessage(), and closes the form. When either step throws, it logs the error and leaves the form open.
sendMessage () => Promise<void> The CreatePoll prop.
closePollCreationDialog () => void Closes the form. It marks the form as closing for one frame, so the fields leave without their exit animations, then calls the CreatePoll prop.
createPollOptionGap number The CreatePoll prop, 8 by default.
modalStateStore StateStore<CreatePollModalState> A store with isClosing, true while the form closes. MultipleVotesSettings reads it to skip its exit animation.

A CreatePollContent of your own reads the form's data from useMessageComposer().pollComposer and calls createAndSendPoll() and closePollCreationDialog() from here. Create polls from your own UI replaces the whole sheet instead.

Examples

Show the user's votes

src/MyVotes.tsx
import { Text } from "react-native";
import { usePollState } from "stream-chat-react-native";

export const MyVotes = () => {
  const { options, ownVotesByOptionId } = usePollState();
  const chosen = options.filter((option) => ownVotesByOptionId[option.id]);

  if (!chosen.length) return <Text>You haven't voted yet.</Text>;

  return (
    <Text>You voted for {chosen.map(({ text }) => text).join(", ")}.</Text>
  );
};

Render it inside a poll part, for example in your own PollContent.

Hook Returns
usePollContext() { poll, message }; throws outside a Poll
usePollState() the poll's state, and addOption, addComment and endVote
usePollStateStore(selector) a selection of poll.state
usePollAnswersPagination() the poll's comments, a page at a time
usePollOptionVotesPagination({ option }) the votes for one option, a page at a time
useCreatePollContentContext() the values above; throws outside CreatePoll

See Poll hooks.