> ## Documentation Index
> Fetch the complete documentation index at: https://www.cometchat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Groups

> Searchable, scrollable list of all available groups with icon, name, member count, and group type indicator.

<Accordion title="AI Integration Quick Reference">
  ```json theme={null}
  {
    "component": "CometChatGroups",
    "package": "@cometchat/chat-uikit-react",
    "import": "import { CometChatGroups } from \"@cometchat/chat-uikit-react\";",
    "cssImport": "import \"@cometchat/chat-uikit-react/css-variables.css\";",
    "description": "Searchable, scrollable list of all available groups with icon, name, member count, and group type indicator.",
    "cssRootClass": ".cometchat-groups",
    "primaryOutput": {
      "prop": "onItemClick",
      "type": "(group: CometChat.Group) => void"
    },
    "props": {
      "data": {
        "groupsRequestBuilder": {
          "type": "CometChat.GroupsRequestBuilder",
          "default": "SDK default (30 per page)",
          "note": "Pass the builder, not the result of .build()"
        },
        "searchRequestBuilder": {
          "type": "CometChat.GroupsRequestBuilder",
          "default": "undefined"
        },
        "activeGroup": {
          "type": "CometChat.Group",
          "default": "undefined"
        }
      },
      "callbacks": {
        "onItemClick": "(group: CometChat.Group) => void",
        "onSelect": "(group: CometChat.Group, selected: boolean) => void",
        "onError": "((error: CometChat.CometChatException) => void) | null"
      },
      "visibility": {
        "hideSearch": { "type": "boolean", "default": false },
        "hideError": { "type": "boolean", "default": false },
        "hideGroupType": { "type": "boolean", "default": false },
        "showScrollbar": { "type": "boolean", "default": false }
      },
      "selection": {
        "selectionMode": {
          "type": "SelectionMode",
          "values": ["SelectionMode.single (0)", "SelectionMode.multiple (1)", "SelectionMode.none (2)"],
          "default": "SelectionMode.none"
        }
      },
      "viewSlots": {
        "itemView": "(group: CometChat.Group) => JSX.Element",
        "leadingView": "(group: CometChat.Group) => JSX.Element",
        "titleView": "(group: CometChat.Group) => JSX.Element",
        "subtitleView": "(group: CometChat.Group) => JSX.Element",
        "trailingView": "(group: CometChat.Group) => JSX.Element",
        "headerView": "JSX.Element",
        "loadingView": "JSX.Element",
        "emptyView": "JSX.Element",
        "errorView": "JSX.Element",
        "options": "(group: CometChat.Group) => CometChatOption[]"
      }
    },
    "events": [
      {
        "name": "CometChatGroupEvents.ccGroupCreated",
        "payload": "CometChat.Group",
        "description": "New group created"
      },
      {
        "name": "CometChatGroupEvents.ccGroupDeleted",
        "payload": "CometChat.Group",
        "description": "Group deleted"
      },
      {
        "name": "CometChatGroupEvents.ccGroupMemberJoined",
        "payload": "IGroupMemberJoined",
        "description": "User joins a group"
      },
      {
        "name": "CometChatGroupEvents.ccGroupLeft",
        "payload": "IGroupLeft",
        "description": "User leaves a group"
      },
      {
        "name": "CometChatGroupEvents.ccGroupMemberAdded",
        "payload": "IGroupMemberAdded",
        "description": "Members added to a group"
      },
      {
        "name": "CometChatGroupEvents.ccGroupMemberScopeChanged",
        "payload": "IGroupMemberScopeChanged",
        "description": "Member scope changed"
      },
      {
        "name": "CometChatGroupEvents.ccGroupMemberKicked",
        "payload": "IGroupMemberKickedBanned",
        "description": "Member kicked"
      },
      {
        "name": "CometChatGroupEvents.ccGroupMemberBanned",
        "payload": "IGroupMemberKickedBanned",
        "description": "Member banned"
      },
      {
        "name": "CometChatGroupEvents.ccOwnershipChanged",
        "payload": "IOwnershipChanged",
        "description": "Ownership transferred"
      }
    ],
    "sdkListeners": [
      "onGroupMemberJoined",
      "onGroupMemberLeft",
      "onMemberAddedToGroup",
      "onGroupMemberKicked",
      "onGroupMemberBanned",
      "onGroupMemberScopeChanged"
    ],
    "compositionExample": {
      "description": "Group directory wired to message view",
      "components": [
        "CometChatGroups",
        "CometChatMessageHeader",
        "CometChatMessageList",
        "CometChatMessageComposer"
      ],
      "flow": "onItemClick emits CometChat.Group -> pass to MessageHeader, MessageList, MessageComposer"
    },
    "types": {
      "CometChatOption": {
        "id": "string | undefined",
        "title": "string | undefined",
        "iconURL": "string | undefined",
        "onClick": "(() => void) | undefined"
      },
      "SelectionMode": {
        "single": 0,
        "multiple": 1,
        "none": 2
      }
    }
  }
  ```
</Accordion>

## Where It Fits

`CometChatGroups` is a directory list component. It renders available groups and emits the selected `CometChat.Group` via `onItemClick`. Wire it to `CometChatMessageHeader`, `CometChatMessageList`, and `CometChatMessageComposer` to build a group chat layout.

```tsx lines theme={null}
import { useState } from "react";
import {
  CometChatGroups,
  CometChatMessageHeader,
  CometChatMessageList,
  CometChatMessageComposer,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";
import "@cometchat/chat-uikit-react/css-variables.css";

function GroupChatApp() {
  const [selectedGroup, setSelectedGroup] = useState<CometChat.Group>();

  return (
    <div style={{ display: "flex", height: "100vh", width: "100vw" }}>
      <div style={{ width: 480, height: "100%" }}>
        <CometChatGroups
          onItemClick={(group: CometChat.Group) => setSelectedGroup(group)}
        />
      </div>
      {selectedGroup ? (
        <div style={{ flex: 1, display: "flex", flexDirection: "column" }}>
          <CometChatMessageHeader group={selectedGroup} />
          <CometChatMessageList group={selectedGroup} />
          <CometChatMessageComposer group={selectedGroup} />
        </div>
      ) : (
        <div style={{ flex: 1, display: "grid", placeItems: "center", background: "#F5F5F5", color: "#727272" }}>
          Select a group
        </div>
      )}
    </div>
  );
}
```

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/udim9ku6wPsRNXGs/images/e06ce245-groups_overview_web_screens-76f09cda3f72c774c46829a547f37f3d.png?fit=max&auto=format&n=udim9ku6wPsRNXGs&q=85&s=c45a801d787787896865fa5a7ac8632a" width="1280" height="800" data-path="images/e06ce245-groups_overview_web_screens-76f09cda3f72c774c46829a547f37f3d.png" />
</Frame>

***

## Minimal Render

```tsx lines theme={null}
import { CometChatGroups } from "@cometchat/chat-uikit-react";
import "@cometchat/chat-uikit-react/css-variables.css";

function GroupsDemo() {
  return (
    <div style={{ width: "100%", height: "100%" }}>
      <CometChatGroups />
    </div>
  );
}

export default GroupsDemo;
```

Root CSS class: `.cometchat-groups`

***

## Filtering Groups

Pass a `CometChat.GroupsRequestBuilder` to `groupsRequestBuilder`. Pass the builder instance — not the result of `.build()`.

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

function FilteredGroups() {
  return (
    <CometChatGroups
      groupsRequestBuilder={
        new CometChat.GroupsRequestBuilder()
          .joinedOnly(true)
          .setLimit(10)
      }
    />
  );
}
```

### Filter Recipes

| Recipe               | Code                                                              |
| -------------------- | ----------------------------------------------------------------- |
| Joined groups only   | `new CometChat.GroupsRequestBuilder().joinedOnly(true)`           |
| Limit to 10 per page | `new CometChat.GroupsRequestBuilder().setLimit(10)`               |
| Search by keyword    | `new CometChat.GroupsRequestBuilder().setSearchKeyword("design")` |
| Filter by tags       | `new CometChat.GroupsRequestBuilder().setTags(["vip"])`           |
| With tags data       | `new CometChat.GroupsRequestBuilder().withTags(true)`             |

Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom.

The `searchRequestBuilder` prop accepts a separate `GroupsRequestBuilder` for filtering when the search bar is active.

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

function SearchFilteredGroups() {
  return (
    <CometChatGroups
      searchRequestBuilder={
        new CometChat.GroupsRequestBuilder()
          .setLimit(5)
          .setSearchKeyword("team")
      }
    />
  );
}
```

Refer to [GroupsRequestBuilder](/sdk/javascript/retrieve-groups) for the full builder API.

***

## Actions and Events

### Callback Props

#### onItemClick

Fires when a group row is tapped. Primary navigation hook — set the active group and render the message view.

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

function GroupsWithClick() {
  const handleItemClick = (group: CometChat.Group) => {
    console.log("Selected:", group.getGuid());
  };

  return <CometChatGroups onItemClick={handleItemClick} />;
}
```

#### onSelect

Fires when a group is checked/unchecked in multi-select mode. Requires `selectionMode` to be set.

```tsx lines theme={null}
import { useState } from "react";
import {
  CometChatGroups,
  SelectionMode,
} from "@cometchat/chat-uikit-react";
import { CometChat } from "@cometchat/chat-sdk-javascript";

function BatchSelectGroups() {
  const [selected, setSelected] = useState<Set<string>>(new Set());

  const handleSelect = (group: CometChat.Group, isSelected: boolean) => {
    setSelected((prev) => {
      const next = new Set(prev);
      const id = group.getGuid();
      isSelected ? next.add(id) : next.delete(id);
      return next;
    });
  };

  return (
    <CometChatGroups
      selectionMode={SelectionMode.multiple}
      onSelect={handleSelect}
    />
  );
}
```

#### onError

Fires on internal errors (network failure, auth issue, SDK exception).

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

function GroupsWithErrorHandler() {
  return (
    <CometChatGroups
      onError={(error: CometChat.CometChatException) => {
        console.error("CometChatGroups error:", error);
      }}
    />
  );
}
```

### Global UI Events

`CometChatGroupEvents` emits events subscribable from anywhere in the application. Subscribe in a `useEffect` and unsubscribe on cleanup.

| Event                       | Fires when                     | Payload                    |
| --------------------------- | ------------------------------ | -------------------------- |
| `ccGroupCreated`            | A new group is created         | `CometChat.Group`          |
| `ccGroupDeleted`            | A group is deleted             | `CometChat.Group`          |
| `ccGroupMemberJoined`       | A user joins a group           | `IGroupMemberJoined`       |
| `ccGroupLeft`               | A user leaves a group          | `IGroupLeft`               |
| `ccGroupMemberAdded`        | Members are added to a group   | `IGroupMemberAdded`        |
| `ccGroupMemberScopeChanged` | A member's scope changes       | `IGroupMemberScopeChanged` |
| `ccGroupMemberKicked`       | A member is kicked             | `IGroupMemberKickedBanned` |
| `ccGroupMemberBanned`       | A member is banned             | `IGroupMemberKickedBanned` |
| `ccGroupMemberUnbanned`     | A member is unbanned           | `IGroupMemberUnBanned`     |
| `ccOwnershipChanged`        | Group ownership is transferred | `IOwnershipChanged`        |

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

function useGroupEvents() {
  useEffect(() => {
    const createdSub = CometChatGroupEvents.ccGroupCreated.subscribe(
      (group: CometChat.Group) => {
        console.log("Group created:", group.getName());
      }
    );
    const deletedSub = CometChatGroupEvents.ccGroupDeleted.subscribe(
      (group: CometChat.Group) => {
        console.log("Group deleted:", group.getName());
      }
    );
    const memberAddedSub = CometChatGroupEvents.ccGroupMemberAdded.subscribe(
      (item) => {
        console.log("Members added to:", item.userAddedIn.getName());
      }
    );
    const leftSub = CometChatGroupEvents.ccGroupLeft.subscribe(
      (item) => {
        console.log("User left group:", item.leftGroup.getName());
      }
    );

    return () => {
      createdSub?.unsubscribe();
      deletedSub?.unsubscribe();
      memberAddedSub?.unsubscribe();
      leftSub?.unsubscribe();
    };
  }, []);
}
```

### SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required.

| SDK Listener                | Internal behavior                                                        |
| --------------------------- | ------------------------------------------------------------------------ |
| `onGroupMemberJoined`       | Updates member count, sets `hasJoined` if current user joined            |
| `onGroupMemberLeft`         | Updates member count, sets `hasJoined(false)` if current user left       |
| `onMemberAddedToGroup`      | Updates member count, adds group to list if current user was added       |
| `onGroupMemberKicked`       | Updates member count, sets `hasJoined(false)` if current user was kicked |
| `onGroupMemberBanned`       | Removes group if current user was banned, otherwise updates member count |
| `onGroupMemberScopeChanged` | Updates scope if current user's scope changed, updates member count      |

<Note>
  In React 18 StrictMode, `useEffect` runs twice on mount in development. The component handles listener cleanup internally, but any additional listeners added alongside the component need cleanup in the `useEffect` return function to avoid duplicate event handling.
</Note>

***

## Custom View Slots

Each slot replaces a section of the default UI. Slots that accept a group parameter receive the `CometChat.Group` object for that row.

| Slot           | Signature                                       | Replaces                     |
| -------------- | ----------------------------------------------- | ---------------------------- |
| `itemView`     | `(group: CometChat.Group) => JSX.Element`       | Entire list item row         |
| `leadingView`  | `(group: CometChat.Group) => JSX.Element`       | Avatar / left section        |
| `titleView`    | `(group: CometChat.Group) => JSX.Element`       | Name / title text            |
| `subtitleView` | `(group: CometChat.Group) => JSX.Element`       | Member count subtitle        |
| `trailingView` | `(group: CometChat.Group) => JSX.Element`       | Right section                |
| `headerView`   | `JSX.Element`                                   | Entire header bar            |
| `loadingView`  | `JSX.Element`                                   | Loading spinner              |
| `emptyView`    | `JSX.Element`                                   | Empty state                  |
| `errorView`    | `JSX.Element`                                   | Error state                  |
| `options`      | `(group: CometChat.Group) => CometChatOption[]` | Context menu / hover actions |

### itemView

Replace the entire list item row.

Default:

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/qrEt0CwYkpwR_jD-/images/d7c86ab4-groups_listItemView_default_web_screens-76f09cda3f72c774c46829a547f37f3d.png?fit=max&auto=format&n=qrEt0CwYkpwR_jD-&q=85&s=2ee744a6d8dc0f079016fb48bf264ebc" width="1280" height="800" data-path="images/d7c86ab4-groups_listItemView_default_web_screens-76f09cda3f72c774c46829a547f37f3d.png" />
</Frame>

Customized:

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/CrArf1QwUPg5EvCC/images/2c6dea55-groups_listItemView_custom_web_screens-a982a860cd750f68bb9409701f0e2267.png?fit=max&auto=format&n=CrArf1QwUPg5EvCC&q=85&s=67251734f07f8bb0a5ac46bfc968d243" width="1280" height="800" data-path="images/2c6dea55-groups_listItemView_custom_web_screens-a982a860cd750f68bb9409701f0e2267.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatGroups } from "@cometchat/chat-uikit-react";

    function CustomItemViewGroups() {
      const getItemView = (group: CometChat.Group) => {
        return (
          <div className="group-list-item">
            <div className="group-list-item__title-wrapper">
              <div className="group-list-item__title">{group.getName()}</div>
              <div className="group-list-item__tail">JOIN</div>
            </div>
            <div className="group-list-item__subtitle">
              {group.getMembersCount()} Members • {group.getDescription()}
            </div>
          </div>
        );
      };

      return <CometChatGroups itemView={getItemView} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .group-list-item {
      display: flex;
      flex-direction: column;
      text-align: left;
      min-width: 240px;
      padding: 8px 16px;
      gap: 4px;
      flex: 1 0 0;
      border-right: 1px solid #f5f5f5;
      background: #fff;
    }

    .group-list-item:hover {
      background-color: #f5f5f5;
    }

    .group-list-item__title-wrapper {
      display: flex;
      justify-content: space-between;
      align-items: center;
      align-self: stretch;
    }

    .group-list-item__title {
      overflow: hidden;
      color: #141414;
      text-overflow: ellipsis;
      font: 500 16px Roboto;
    }

    .group-list-item__tail {
      display: flex;
      padding: 4px 12px;
      justify-content: center;
      align-items: center;
      border-radius: 1000px;
      background: #edeafa;
      overflow: hidden;
      color: #6852d6;
      text-overflow: ellipsis;
      font: 700 12px Roboto;
    }

    .group-list-item__subtitle {
      overflow: hidden;
      color: #727272;
      text-overflow: ellipsis;
      white-space: nowrap;
      font: 400 14px Roboto;
    }
    ```
  </Tab>
</Tabs>

### titleView

Replace the name / title text. Group type badge inline example.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/t35Dbaum6Rkuz_d5/images/1407ea86-groups_custom_titleview_web_screens-54ca7045e948a252b07729ffc10dbc15.png?fit=max&auto=format&n=t35Dbaum6Rkuz_d5&q=85&s=f3e711a8a0c380686cfa852c55a7f5c8" width="1280" height="800" data-path="images/1407ea86-groups_custom_titleview_web_screens-54ca7045e948a252b07729ffc10dbc15.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatGroups } from "@cometchat/chat-uikit-react";

    function GroupTypeTitleGroups() {
      const getTitleView = (group: CometChat.Group) => {
        return (
          <div className={`groups__title-view groups__title-view-${group.getType()}`}>
            <span className="groups__title-view-name">{group.getName()}</span>
            <span className="groups__title-view-type">{group.getType()}</span>
          </div>
        );
      };

      return <CometChatGroups titleView={getTitleView} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .groups__title-view {
      display: flex;
      align-items: center;
      gap: 4px;
      align-self: stretch;
    }

    .groups__title-view-name {
      overflow: hidden;
      color: #141414;
      text-overflow: ellipsis;
      font: 500 16px Roboto;
    }

    .groups__title-view-type {
      color: #fff;
      font: 600 8px Roboto;
      display: flex;
      height: 15px;
      padding: 1px 3px;
      justify-content: center;
      align-items: center;
      gap: 4px;
      border-radius: 7px;
      background: #09c26f;
    }

    .groups__title-view-public .groups__title-view-type {
      background: #0b7bea;
    }
    ```
  </Tab>
</Tabs>

### subtitleView

Replace the member count subtitle text.

Default:

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/aledzZZMtw_sXx4U/images/fc8a44f2-groups_subtitleView_default_web_screens-ce55d4824eab1d506f7ff5b8b2bd3f03.png?fit=max&auto=format&n=aledzZZMtw_sXx4U&q=85&s=18d98223da4c64fcda695947c40bff6e" width="1280" height="800" data-path="images/fc8a44f2-groups_subtitleView_default_web_screens-ce55d4824eab1d506f7ff5b8b2bd3f03.png" />
</Frame>

Customized:

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/qrEt0CwYkpwR_jD-/images/d7df2f29-groups_subtitleView_custom_web_screens-2031bc808b39482f08506ce198d5dd36.png?fit=max&auto=format&n=qrEt0CwYkpwR_jD-&q=85&s=ed1e1cf9dd48408f712a7f9615f3074c" width="1280" height="800" data-path="images/d7df2f29-groups_subtitleView_custom_web_screens-2031bc808b39482f08506ce198d5dd36.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatGroups } from "@cometchat/chat-uikit-react";

    function SubtitleGroups() {
      const getSubtitleView = (group: CometChat.Group) => {
        return (
          <div className="group-subtitle">
            {group.getMembersCount()} Members • {group.getDescription()}
          </div>
        );
      };

      return <CometChatGroups subtitleView={getSubtitleView} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .cometchat .cometchat-groups .group-subtitle {
      overflow: hidden;
      color: #727272;
      text-overflow: ellipsis;
      white-space: nowrap;
      font: 400 14px Roboto;
    }
    ```
  </Tab>
</Tabs>

### leadingView

Replace the avatar / left section. Joined status badge example.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/gHkTur1I2BmQKdRR/images/04d918dc-groups_custom_leadingview_web_screens-41667751c0dc223d0b9d79bb5d891707.png?fit=max&auto=format&n=gHkTur1I2BmQKdRR&q=85&s=248b71f29fa63e6d34511ea87fe2e26e" width="1280" height="800" data-path="images/04d918dc-groups_custom_leadingview_web_screens-41667751c0dc223d0b9d79bb5d891707.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatGroups, CometChatAvatar } from "@cometchat/chat-uikit-react";

    function LeadingViewGroups() {
      const getLeadingView = (group: CometChat.Group) => {
        return (
          <>
            {group.getHasJoined() ? (
              <div className="groups__leading-view groups__leading-view-joined">
                <CometChatAvatar image={group?.getIcon()} name={group?.getName()} />
                <span className="groups__leading-view-info">Joined</span>
              </div>
            ) : (
              <div className="groups__leading-view">
                <CometChatAvatar image={group?.getIcon()} name={group?.getName()} />
                <span className="groups__leading-view-info">Join</span>
              </div>
            )}
          </>
        );
      };

      return <CometChatGroups leadingView={getLeadingView} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .cometchat-groups .cometchat-list-item .groups__leading-view .cometchat-avatar__image,
    .cometchat-groups .cometchat-list-item .groups__leading-view .cometchat-avatar {
      border-radius: 8px;
      height: 48px;
      width: 48px;
    }

    .groups__leading-view-info {
      display: flex;
      width: 48px;
      height: 15px;
      padding: 1px 3px;
      justify-content: center;
      align-items: center;
      color: #fff;
      font: 600 8px/9.6px Roboto;
      background: #ffab00;
      position: absolute;
      bottom: -2px;
    }

    .groups__leading-view-joined .groups__leading-view-info {
      background: #09c26f;
    }

    .groups__leading-view {
      position: relative;
    }
    ```
  </Tab>
</Tabs>

### trailingView

Replace the right section. Join status button example.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/t35Dbaum6Rkuz_d5/images/14ff155c-groups_custom_trailingview_web_screens-e5d40e26cde7b3a1f616a9fbba5961f4.png?fit=max&auto=format&n=t35Dbaum6Rkuz_d5&q=85&s=0d151443d3133be83d91ce73e36e550d" width="1280" height="800" data-path="images/14ff155c-groups_custom_trailingview_web_screens-e5d40e26cde7b3a1f616a9fbba5961f4.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatGroups } from "@cometchat/chat-uikit-react";

    function TrailingViewGroups() {
      const getTrailingView = (group: CometChat.Group) => {
        return (
          <div className="groups__trailing-view">
            {group.getHasJoined() ? "JOINED" : "+ JOIN"}
          </div>
        );
      };

      return <CometChatGroups trailingView={getTrailingView} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .groups__trailing-view {
      display: flex;
      padding: 4px 12px;
      justify-content: center;
      align-items: center;
      border-radius: 1000px;
      background: #edeafa;
      overflow: hidden;
      color: #6852d6;
      text-overflow: ellipsis;
      font: 700 12px Roboto;
    }

    .cometchat-groups .cometchat-list-item__trailing-view {
      width: fit-content;
      height: fit-content;
    }
    ```
  </Tab>
</Tabs>

### headerView

Replace the entire header bar.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/CrArf1QwUPg5EvCC/images/2a85c378-groups_menus_web_screens-46f58c8f27a436e5e27d33c60b59a61f.png?fit=max&auto=format&n=CrArf1QwUPg5EvCC&q=85&s=10c88fc1cef81bce404e64ef586a33e2" width="1280" height="317" data-path="images/2a85c378-groups_menus_web_screens-46f58c8f27a436e5e27d33c60b59a61f.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import {
      CometChatButton,
      CometChatGroups,
      getLocalizedString,
    } from "@cometchat/chat-uikit-react";

    function CustomHeaderGroups() {
      return (
        <CometChatGroups
          headerView={
            <div className="groups__header">
              <div className="groups__header__title">
                {getLocalizedString("GROUPS")}
              </div>
              <CometChatButton onClick={() => { /* handle click */ }} />
            </div>
          }
        />
      );
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .groups__header {
      display: flex;
      width: 100%;
      padding: 8px 16px;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      border-radius: 10px;
      border: 1px solid #e8e8e8;
      background: #edeafa;
    }

    .groups__header__title {
      overflow: hidden;
      color: #141414;
      text-overflow: ellipsis;
      font: 700 24px Roboto;
    }

    .groups__header .cometchat-button .cometchat-button__icon {
      background: #141414;
    }

    .groups__header .cometchat-button {
      width: 24px;
      border: none;
      background: transparent;
      border-radius: 0;
    }
    ```
  </Tab>
</Tabs>

### options

Replace the context menu / hover actions on each group item.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/bKHmaxDqzaJZWwLS/images/45c377f6-groups_options_web_screens-6cc90758cfb5beb7dc70b4293b66ffc0.png?fit=max&auto=format&n=bKHmaxDqzaJZWwLS&q=85&s=3d75be8157e3443e7beedccd93145857" width="1280" height="800" data-path="images/45c377f6-groups_options_web_screens-6cc90758cfb5beb7dc70b4293b66ffc0.png" />
</Frame>

<Tabs>
  <Tab title="TypeScript">
    ```tsx lines theme={null}
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import {
      CometChatOption,
      CometChatGroups,
    } from "@cometchat/chat-uikit-react";

    function CustomOptionsGroups() {
      const getOptions = (group: CometChat.Group) => [
        new CometChatOption({
          title: "Delete",
          id: "delete",
          onClick: () => { /* delete logic */ },
        }),
      ];

      return <CometChatGroups options={getOptions} />;
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css lines theme={null}
    .cometchat .cometchat-groups .cometchat-menu-list__menu {
      background: none;
    }

    .cometchat .cometchat-groups .cometchat-menu-list__main-menu-item-icon {
      background: #f44649;
    }
    ```
  </Tab>
</Tabs>

```ts lines theme={null}
// CometChatOption interface
interface CometChatOption {
  id?: string;       // Unique identifier
  title?: string;    // Display text
  iconURL?: string;  // Icon asset URL
  onClick?: () => void; // Click handler
}
```

***

## Common Patterns

### Custom empty state with CTA

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

function EmptyStateGroups() {
  return (
    <CometChatGroups
      emptyView={
        <div style={{ textAlign: "center", padding: 40 }}>
          <p>No groups available</p>
          <button onClick={() => { /* navigate to create group */ }}>
            Create a group
          </button>
        </div>
      }
    />
  );
}
```

### Hide all chrome — minimal list

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

function MinimalGroups() {
  return (
    <CometChatGroups
      hideSearch={true}
      hideGroupType={true}
    />
  );
}
```

### Joined groups only

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

function JoinedGroups() {
  return (
    <CometChatGroups
      groupsRequestBuilder={
        new CometChat.GroupsRequestBuilder().joinedOnly(true)
      }
    />
  );
}
```

***

## CSS Architecture

The component uses CSS custom properties (design tokens) defined in `@cometchat/chat-uikit-react/css-variables.css`. The cascade:

1. Global tokens (e.g., `--cometchat-primary-color`, `--cometchat-background-color-01`) are set on the `.cometchat` root wrapper.
2. Component CSS (`.cometchat-groups`) consumes these tokens via `var()` with fallback values.
3. Overrides target `.cometchat-groups` descendant selectors in a global stylesheet.

To scope overrides to a single instance when multiple `CometChatGroups` exist on the same page, wrap the component in a container and scope selectors:

```css lines theme={null}
.sidebar-left .cometchat-groups .cometchat-avatar {
  border-radius: 8px;
}
```

### Key Selectors

| Target              | Selector                                                             |
| ------------------- | -------------------------------------------------------------------- |
| Root                | `.cometchat-groups`                                                  |
| Header title        | `.cometchat-groups .cometchat-list__header-title`                    |
| Search bar input    | `.cometchat-groups .cometchat-search-bar__input`                     |
| List item           | `.cometchat-groups .cometchat-list-item`                             |
| Body title          | `.cometchat-groups .cometchat-list-item__body-title`                 |
| Avatar              | `.cometchat-groups__list-item .cometchat-avatar`                     |
| Subtitle            | `.cometchat-groups__subtitle`                                        |
| Active item         | `.cometchat-groups__list-item-active .cometchat-list-item`           |
| Password group icon | `.cometchat-groups__list-item-password .cometchat-list-item__status` |
| Private group icon  | `.cometchat-groups__list-item-private .cometchat-list-item__status`  |
| Empty state         | `.cometchat-groups__empty-state-view`                                |
| Error state         | `.cometchat-groups__error-state-view`                                |
| Shimmer loading     | `.cometchat-groups__shimmer`                                         |

### Example: Brand-themed groups

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b/oaJbJ0bOxG69pJ1L/images/88288ec7-groups_style-8e467325ba53688633816b7190aa3f95.png?fit=max&auto=format&n=oaJbJ0bOxG69pJ1L&q=85&s=3cc534f45c88079c5276a3b3e2b4921a" width="1280" height="800" data-path="images/88288ec7-groups_style-8e467325ba53688633816b7190aa3f95.png" />
</Frame>

```css lines theme={null}
.cometchat-groups .cometchat-list__header-title {
  background-color: #edeafa;
  color: #6852d6;
  border-width: 0px 1px 1px 0px;
  border-style: solid;
  border-color: #6852d6;
  font-family: "Times New Roman";
  font-size: 24px;
  font-weight: 700;
}

.cometchat-groups__list-item .cometchat-avatar {
  background-color: #aa9ee8;
  border-radius: 6.67px;
}

.cometchat-groups .cometchat-list-item__body-title {
  font-family: "Times New Roman";
  font-size: 16px;
  font-weight: 400;
}

.cometchat-groups .cometchat-groups__subtitle {
  font-family: "Times New Roman";
  font-size: 14px;
  font-weight: 400;
}
```

### Customization Matrix

| What to change                        | Where           | Property/API                     | Example                                                                        |
| ------------------------------------- | --------------- | -------------------------------- | ------------------------------------------------------------------------------ |
| Override behavior on user interaction | Component props | `on<Event>` callbacks            | `onItemClick={(g) => setActive(g)}`                                            |
| Filter which groups appear            | Component props | `groupsRequestBuilder`           | `groupsRequestBuilder={new CometChat.GroupsRequestBuilder().joinedOnly(true)}` |
| Toggle visibility of UI elements      | Component props | `hide<Feature>` boolean props    | `hideGroupType={true}`                                                         |
| Replace a section of the list item    | Component props | `<slot>View` render props        | `itemView={(group) => <div>...</div>}`                                         |
| Change colors, fonts, spacing         | Global CSS      | Target `.cometchat-groups` class | `.cometchat-groups .cometchat-avatar { border-radius: 8px; }`                  |

***

## Props

All props are optional unless noted otherwise.

***

### activeGroup

Highlights the specified group in the list.

|         |                   |
| ------- | ----------------- |
| Type    | `CometChat.Group` |
| Default | `undefined`       |

Must be a reference-equal object from the SDK; a manually constructed object will not match.

***

### emptyView

Custom component displayed when there are no groups.

|         |                      |
| ------- | -------------------- |
| Type    | `JSX.Element`        |
| Default | Built-in empty state |

***

### errorView

Custom component displayed when an error occurs.

|         |                      |
| ------- | -------------------- |
| Type    | `JSX.Element`        |
| Default | Built-in error state |

Hidden when `hideError={true}`.

***

### groupsRequestBuilder

Controls which groups load and in what order.

|         |                                  |
| ------- | -------------------------------- |
| Type    | `CometChat.GroupsRequestBuilder` |
| Default | SDK default (30 per page)        |

Pass the builder instance, not the result of `.build()`.

***

### headerView

Custom component rendered as the entire header bar.

|         |                            |
| ------- | -------------------------- |
| Type    | `JSX.Element`              |
| Default | Built-in header with title |

***

### hideError

Hides the default and custom error views.

|         |           |
| ------- | --------- |
| Type    | `boolean` |
| Default | `false`   |

Also suppresses `errorView` if set.

***

### hideGroupType

Hides the group type icon (public/private/password).

|         |           |
| ------- | --------- |
| Type    | `boolean` |
| Default | `false`   |

***

### hideSearch

Hides the default search bar.

|         |           |
| ------- | --------- |
| Type    | `boolean` |
| Default | `false`   |

***

### itemView

Custom renderer for the entire list item row.

|         |                                           |
| ------- | ----------------------------------------- |
| Type    | `(group: CometChat.Group) => JSX.Element` |
| Default | Built-in list item                        |

***

### leadingView

Custom renderer for the avatar / left section.

|         |                                           |
| ------- | ----------------------------------------- |
| Type    | `(group: CometChat.Group) => JSX.Element` |
| Default | Built-in avatar                           |

***

### loadingView

Custom component displayed during the loading state.

|         |                  |
| ------- | ---------------- |
| Type    | `JSX.Element`    |
| Default | Built-in shimmer |

***

### onError

Callback fired when the component encounters an error.

|         |                                                           |
| ------- | --------------------------------------------------------- |
| Type    | `((error: CometChat.CometChatException) => void) \| null` |
| Default | `undefined`                                               |

***

### onItemClick

Callback fired when a group row is clicked.

|         |                                    |
| ------- | ---------------------------------- |
| Type    | `(group: CometChat.Group) => void` |
| Default | `undefined`                        |

***

### onSelect

Callback fired when a group is selected/deselected. Requires `selectionMode` to be set.

|         |                                                       |
| ------- | ----------------------------------------------------- |
| Type    | `(group: CometChat.Group, selected: boolean) => void` |
| Default | `undefined`                                           |

***

### options

Custom context menu / hover actions for each group item.

|         |                                                 |
| ------- | ----------------------------------------------- |
| Type    | `(group: CometChat.Group) => CometChatOption[]` |
| Default | `undefined`                                     |

```ts lines theme={null}
class CometChatOption {
  id?: string;
  title?: string;
  iconURL?: string;
  onClick?: () => void;
}
```

***

### searchRequestBuilder

Controls filtering when the search bar is active.

|         |                                  |
| ------- | -------------------------------- |
| Type    | `CometChat.GroupsRequestBuilder` |
| Default | `undefined`                      |

***

### selectionMode

Enables single or multi-select checkboxes on list items.

|         |                      |
| ------- | -------------------- |
| Type    | `SelectionMode`      |
| Default | `SelectionMode.none` |

```ts lines theme={null}
enum SelectionMode {
  single,    // 0
  multiple,  // 1
  none,      // 2
}
```

Must pair with `onSelect` to capture selections.

***

### showScrollbar

Shows the scrollbar in the group list.

|         |           |
| ------- | --------- |
| Type    | `boolean` |
| Default | `false`   |

***

### subtitleView

Custom renderer for the member count subtitle text.

|         |                                           |
| ------- | ----------------------------------------- |
| Type    | `(group: CometChat.Group) => JSX.Element` |
| Default | Built-in subtitle                         |

***

### titleView

Custom renderer for the name / title text.

|         |                                           |
| ------- | ----------------------------------------- |
| Type    | `(group: CometChat.Group) => JSX.Element` |
| Default | Built-in title                            |

***

### trailingView

Custom renderer for the right section.

|         |                                           |
| ------- | ----------------------------------------- |
| Type    | `(group: CometChat.Group) => JSX.Element` |
| Default | Built-in trailing view                    |

***

## Events

| Event                                            | Payload                    | Fires when               |
| ------------------------------------------------ | -------------------------- | ------------------------ |
| `CometChatGroupEvents.ccGroupCreated`            | `CometChat.Group`          | New group created        |
| `CometChatGroupEvents.ccGroupDeleted`            | `CometChat.Group`          | Group deleted            |
| `CometChatGroupEvents.ccGroupMemberJoined`       | `IGroupMemberJoined`       | User joins a group       |
| `CometChatGroupEvents.ccGroupLeft`               | `IGroupLeft`               | User leaves a group      |
| `CometChatGroupEvents.ccGroupMemberAdded`        | `IGroupMemberAdded`        | Members added to a group |
| `CometChatGroupEvents.ccGroupMemberScopeChanged` | `IGroupMemberScopeChanged` | Member scope changed     |
| `CometChatGroupEvents.ccGroupMemberKicked`       | `IGroupMemberKickedBanned` | Member kicked            |
| `CometChatGroupEvents.ccGroupMemberBanned`       | `IGroupMemberKickedBanned` | Member banned            |
| `CometChatGroupEvents.ccGroupMemberUnbanned`     | `IGroupMemberUnBanned`     | Member unbanned          |
| `CometChatGroupEvents.ccOwnershipChanged`        | `IOwnershipChanged`        | Ownership transferred    |

All events are RxJS `Subject` instances. Subscribe with `.subscribe()`, unsubscribe with the returned subscription's `.unsubscribe()`.

***

## CSS Selectors

| Target                     | Selector                                                                  |
| -------------------------- | ------------------------------------------------------------------------- |
| Root                       | `.cometchat-groups`                                                       |
| Header title               | `.cometchat-groups .cometchat-list__header-title`                         |
| Search bar input           | `.cometchat-groups .cometchat-search-bar__input`                          |
| List item                  | `.cometchat-groups .cometchat-list-item`                                  |
| Body title                 | `.cometchat-groups .cometchat-list-item__body-title`                      |
| Avatar                     | `.cometchat-groups__list-item .cometchat-avatar`                          |
| Leading view               | `.cometchat-groups__list-item .cometchat-list-item__leading-view`         |
| Subtitle                   | `.cometchat-groups__subtitle`                                             |
| Active item                | `.cometchat-groups__list-item-active .cometchat-list-item`                |
| Password group icon        | `.cometchat-groups__list-item-password .cometchat-list-item__status`      |
| Password group status icon | `.cometchat-groups__list-item-password .cometchat-list-item__status-icon` |
| Private group icon         | `.cometchat-groups__list-item-private .cometchat-list-item__status`       |
| Private group status icon  | `.cometchat-groups__list-item-private .cometchat-list-item__status-icon`  |
| Empty state                | `.cometchat-groups__empty-state-view`                                     |
| Empty state title          | `.cometchat-groups__empty-state-view-body-title`                          |
| Empty state description    | `.cometchat-groups__empty-state-view-body-description`                    |
| Error state                | `.cometchat-groups__error-state-view`                                     |
| Error state title          | `.cometchat-groups__error-state-view-body-title`                          |
| Error state description    | `.cometchat-groups__error-state-view-body-description`                    |
| Shimmer loading            | `.cometchat-groups__shimmer`                                              |
| Shimmer item               | `.cometchat-groups__shimmer-item`                                         |
| Shimmer avatar             | `.cometchat-groups__shimmer-item-avatar`                                  |
| Shimmer title              | `.cometchat-groups__shimmer-item-body-title`                              |
| Shimmer subtitle           | `.cometchat-groups__shimmer-item-body-subtitle`                           |
