> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-rn-guide-message-privately.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Reaction List

> Standalone panel showing who reacted to a message, with emoji tab filtering, pagination, and optimistic removal for the current user.

<Accordion title="AI Integration Quick Reference">
  ```json theme={null}
  {
    "component": "CometChatReactionList",
    "package": "@cometchat/chat-uikit-react",
    "import": "import { CometChatReactionList } from \"@cometchat/chat-uikit-react\";",
    "description": "Standalone panel showing who reacted to a message, with emoji tab filtering, pagination, and optimistic removal for the current user.",
    "cssRootClass": ".cometchat-reaction-list",
    "primaryOutput": {
      "prop": "onItemClick",
      "type": "(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void"
    },
    "props": {
      "data": {
        "message": { "type": "CometChat.BaseMessage", "note": "Required. The message to show reactions for." },
        "reactionsRequestBuilder": { "type": "CometChat.ReactionsRequestBuilder" }
      },
      "callbacks": {
        "onItemClick": { "type": "(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void", "note": "Fires only for current user's reactions (to remove)." },
        "onEmpty": { "type": "() => void", "note": "Fires when all reactions are removed. Parent should close the panel." },
        "onError": { "type": "(error: unknown) => void" }
      }
    },
    "types": {
      "CometChatReactionListRootProps": "Root provider props",
      "CometChatReactionListTabsProps": "Emoji tab bar props",
      "CometChatReactionListItemsProps": "Scrollable reactor list props",
      "CometChatReactionListLoadingStateProps": "Shimmer loading state props",
      "CometChatReactionListErrorStateProps": "Error state props",
      "CometChatReactionListEmptyStateProps": "Empty state props",
      "CometChatReactionListContextValue": "Full context value"
    }
  }
  ```
</Accordion>

## Where It Fits

`CometChatReactionList` is a **standalone** component — it manages its own state and does not depend on `CometChatReactions.Root` context. It is distinct from `CometChatReactions.List`, which is a sub-component of `CometChatReactions`.

<Info>
  **Live Preview** — interact with the reaction list component.

  [Open in Storybook ↗](https://storybook.cometchat.io/react/?path=/story/components-misc-reaction-list--default)
</Info>

<iframe src="https://storybook.cometchat.io/react/iframe.html?id=components-misc-reaction-list--default&viewMode=story&shortcuts=false&singleStory=true" className="w-full rounded-xl" loading="lazy" style={{height: "350px", border: "1px solid #e0e0e0"}} title="CometChat Reaction List — Default" allow="clipboard-write" />

Use `CometChatReactionList` when you want to show a dedicated panel (e.g., inside a popover or bottom sheet) listing all users who reacted to a message, with tab filtering by emoji and the ability for the current user to remove their own reaction.

The parent component (typically `CometChatMessageList`) owns the SDK reaction add/remove calls and passes an updated `message` prop when reactions change.

```tsx lines theme={null}
import { CometChatReactionList } from "@cometchat/chat-uikit-react";

function ReactionPanel({ message, onClose }) {
  return (
    <CometChatReactionList
      message={message}
      onItemClick={(reaction, msg) => {
        // Parent calls SDK to remove the reaction
        CometChat.removeReaction(String(msg.getId()), reaction.getReaction());
      }}
      onEmpty={onClose}
    />
  );
}
```

## Minimal Render

```tsx lines theme={null}
import { CometChatReactionList } from "@cometchat/chat-uikit-react";

function Demo({ message }) {
  return <CometChatReactionList message={message} />;
}
```

Root CSS class: `.cometchat-reaction-list`

## Sub-Components

`CometChatReactionList` is a compound component with these sub-components:

| Sub-Component  | Purpose                                                                                 |
| -------------- | --------------------------------------------------------------------------------------- |
| `Root`         | Context provider. Receives message and config. Renders default layout when no children. |
| `Tabs`         | Emoji tab bar — "All" tab plus one tab per unique emoji. Keyboard navigable.            |
| `Items`        | Scrollable list of users who reacted. IntersectionObserver pagination.                  |
| `LoadingState` | Shimmer loading placeholder. Self-hides when not loading.                               |
| `ErrorState`   | Error message with retry button. Self-hides when not in error state.                    |
| `EmptyState`   | Empty message. Self-hides when not empty.                                               |

### Custom Layout

Compose sub-components to customize the layout:

```tsx lines theme={null}
<CometChatReactionList.Root message={message} onItemClick={handleRemove}>
  <CometChatReactionList.Tabs />
  <CometChatReactionList.LoadingState />
  <CometChatReactionList.ErrorState />
  <CometChatReactionList.EmptyState />
  <CometChatReactionList.Items />
</CometChatReactionList.Root>
```

### Custom Header

Add a custom header above the tabs:

```tsx lines theme={null}
<CometChatReactionList.Root message={message}>
  <div className="my-header">Reactions</div>
  <CometChatReactionList.Tabs />
  <CometChatReactionList.Items />
</CometChatReactionList.Root>
```

## Actions and Events

### Callback Props

#### onItemClick

Called when a reaction item is clicked. Only fires for the **current user's own reactions** — non-current-user items are read-only. The parent should call the SDK to remove the reaction.

```tsx lines theme={null}
<CometChatReactionList
  message={message}
  onItemClick={(reaction, msg) => {
    CometChat.removeReaction(String(msg.getId()), reaction.getReaction())
      .then(() => console.log("Reaction removed"))
      .catch(console.error);
  }}
/>
```

#### onEmpty

Called when all reactions are removed (after optimistic removal). The parent should close the panel.

```tsx lines theme={null}
const [showPanel, setShowPanel] = useState(true);

{showPanel && (
  <CometChatReactionList
    message={message}
    onEmpty={() => setShowPanel(false)}
  />
)}
```

#### onError

Called when an error occurs during reaction fetching.

```tsx lines theme={null}
<CometChatReactionList
  message={message}
  onError={(error) => console.error("Reaction list error:", error)}
/>
```

## Behavior Details

### Emoji Tabs

* "All" tab shows every reactor across all emojis.
* Per-emoji tabs show only reactors for that emoji.
* Tab counts update optimistically when the current user removes a reaction.
* Keyboard navigation: `ArrowLeft` / `ArrowRight` to move between tabs, `Enter` / `Space` to select.

### Reactor Items

* Each item shows: avatar, name (or "You" for the current user), "Click to remove" hint (current user only), and the emoji.
* Current user items: `cursor: pointer`, `tabIndex={0}`, clickable via `Enter` / `Space`.
* Non-current-user items: `cursor: default`, `tabIndex={-1}`, not interactive.

### Pagination

Reactions are fetched in pages (default limit: 30). An `IntersectionObserver` sentinel at the bottom of the list triggers `fetchMore()` when the user scrolls near the bottom.

### Optimistic Removal

When the current user clicks their reaction:

1. The reaction is removed from the list immediately (optimistic update).
2. `onItemClick` is called so the parent can call the SDK.
3. If no reactions remain, `onEmpty` is called.

The component does **not** call the SDK itself — the parent owns that responsibility.

### Custom Request Builder

Pass a custom `ReactionsRequestBuilder` to control the fetch limit or other parameters:

```tsx lines theme={null}
import { CometChat } from "@cometchat/chat-sdk-javascript";

const builder = new CometChat.ReactionsRequestBuilder().setLimit(50);

<CometChatReactionList
  message={message}
  reactionsRequestBuilder={builder}
/>
```

## CSS Architecture

The component uses CSS custom properties provided by the UI Kit.

### Key Selectors

| Target              | Selector                                            |
| ------------------- | --------------------------------------------------- |
| Root                | `.cometchat-reaction-list`                          |
| Tabs bar            | `.cometchat-reaction-list__tabs`                    |
| Tab button          | `.cometchat-reaction-list__tabs-tab`                |
| Tab (active)        | `.cometchat-reaction-list__tabs-tab--active`        |
| Tab emoji           | `.cometchat-reaction-list__tabs-tab-emoji`          |
| Tab emoji (active)  | `.cometchat-reaction-list__tabs-tab-emoji--active`  |
| Tab count           | `.cometchat-reaction-list__tabs-tab-count`          |
| Tab count (active)  | `.cometchat-reaction-list__tabs-tab-count--active`  |
| Items list          | `.cometchat-reaction-list__list`                    |
| List item           | `.cometchat-reaction-list__list-item`               |
| Item (current user) | `.cometchat-reaction-list__list-item--current-user` |
| Item (read-only)    | `.cometchat-reaction-list__list-item--readonly`     |
| Item avatar         | `.cometchat-reaction-list__item-avatar`             |
| Item name           | `.cometchat-reaction-list__item-name`               |
| Item hint           | `.cometchat-reaction-list__item-hint`               |
| Item emoji          | `.cometchat-reaction-list__item-emoji`              |
| Shimmer             | `.cometchat-reaction-list__shimmer`                 |
| Error               | `.cometchat-reaction-list__error`                   |
| Retry button        | `.cometchat-reaction-list__retry-button`            |
| Empty               | `.cometchat-reaction-list__empty`                   |
| Loading more        | `.cometchat-reaction-list__loading-more`            |
| Spinner             | `.cometchat-reaction-list__spinner`                 |

### Example: Custom styling

```css lines title="App.css" theme={null}
/* Wider panel */
.cometchat-reaction-list {
  width: 320px;
}

/* Custom active tab color */
.cometchat-reaction-list__tabs-tab--active {
  border-bottom-color: var(--my-brand-color);
}

.cometchat-reaction-list__tabs-tab-emoji--active,
.cometchat-reaction-list__tabs-tab-count--active {
  color: var(--my-brand-color);
}
```

## Props

All props are optional unless noted otherwise.

***

### message

The SDK message object to show reactions for. **Required.**

|         |                         |
| ------- | ----------------------- |
| Type    | `CometChat.BaseMessage` |
| Default | —                       |

***

### reactionsRequestBuilder

Custom request builder for fetching reactor details. Controls limit and other fetch parameters.

|         |                                                        |
| ------- | ------------------------------------------------------ |
| Type    | `CometChat.ReactionsRequestBuilder`                    |
| Default | `new CometChat.ReactionsRequestBuilder().setLimit(30)` |

***

### onItemClick

Called when the current user clicks their own reaction item (to remove it). Not called for other users' reactions.

|         |                                                                          |
| ------- | ------------------------------------------------------------------------ |
| Type    | `(reaction: CometChat.Reaction, message: CometChat.BaseMessage) => void` |
| Default | `undefined`                                                              |

***

### onEmpty

Called when all reactions are removed. The parent should close the panel.

|         |              |
| ------- | ------------ |
| Type    | `() => void` |
| Default | `undefined`  |

***

### onError

Error callback for reaction fetching failures.

|         |                            |
| ------- | -------------------------- |
| Type    | `(error: unknown) => void` |
| Default | `undefined`                |

***

### children

Custom sub-components. When omitted, renders the default layout (Tabs + LoadingState + ErrorState + EmptyState + Items).

|         |                |
| ------- | -------------- |
| Type    | `ReactNode`    |
| Default | Default layout |

***

### className

Optional custom CSS class for the root container.

|         |             |
| ------- | ----------- |
| Type    | `string`    |
| Default | `undefined` |

## Accessibility

* Root has `role="dialog"` and `aria-label="Reaction list"`.
* Tab bar has `role="tablist"` with `aria-label="Reaction filters"`.
* Each tab has `role="tab"` and `aria-selected`.
* Items container has `role="list"` with a descriptive `aria-label`.
* Each item has `role="listitem"` and `aria-label` describing the user, emoji, and hint.
* Current user items have `tabIndex={0}` and respond to `Enter` / `Space`.
* Read-only items have `tabIndex={-1}`.
* All interactive elements have `:focus-visible` styles.
* Shimmer respects `prefers-reduced-motion`.
* Spinner respects `prefers-reduced-motion`.
* High contrast mode supported via `@media (prefers-contrast: high)`.
