> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Building A Messaging UI With Tabs, Sidebar, And Message View

This guide walks you through creating a **tab-based messaging UI** using **React** and **CometChat UIKit**. The UI will include different sections for **Chats, Calls, Users, and Groups**, allowing seamless navigation.

[<img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/R-mrzo_AxVZMXils/images/30d34521-play-codesandbox.svg?fit=max&auto=format&n=R-mrzo_AxVZMXils&q=85&s=719f2f667589e0991584e435e7936741" width="165" height="32" data-path="images/30d34521-play-codesandbox.svg" />](https://link.cometchat.com/react-tabs-sidebar-message)

> **Tip:** You can **fork** the sandbox, insert your **CometChat credentials** (App ID, Region, Auth Key.) in the code, and immediately preview how the UI and messages respond in real time.

***

## **User Interface Preview**

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-feature-react-native-sdk-quotedmessage-a/FOPcIvXNMzgmVa9j/images/010808a2-multi_tab_ui_web_screens-4c6055da929b73c11d7d45b0112fd5fc.png?fit=max&auto=format&n=FOPcIvXNMzgmVa9j&q=85&s=25e2a8b035f8f0d92dc72339ade2c54c" width="1282" height="802" data-path="images/010808a2-multi_tab_ui_web_screens-4c6055da929b73c11d7d45b0112fd5fc.png" />
</Frame>

This layout consists of:

1. **Sidebar (Conversation List)** – Displays recent conversations with active users and groups.
2. **Message View** – Shows the selected chat with real-time messages.
3. **Message Input Box** – Allows users to send messages seamlessly.

***

## **Step-by-Step Guide**

### **Step 1: Create a Tab Component**

To manage navigation, let's build a **`CometChatTabs`** component. This component will render different tabs and allow switching between sections dynamically.

#### **Folder Structure**

Create a `CometChatTabs` folder inside your `src` directory and add the following files:

```python theme={null}
src/
│── CometChatTabs/
│   ├── assets # These are the images you need to save
│   │   ├── chats.svg 
│   │   ├── calls.svg 
│   │   ├── users.svg 
│   │   ├── groups.svg
│   ├── CometChatTabs.tsx
│   ├── CometChatTabs.css 
```

#### **Download the Icons**

These icons are available in the **CometChat UI Kit assets folder**. You can find them at:\
🔗 [GitHub Assets Folder](https://github.com/cometchat/cometchat-uikit-react/tree/v6/sample-app/src/assets)

***

#### **Implementation**

<Tabs>
  <Tab title="TypeScript">
    ```tsx CometChatTabs.tsx theme={null}
    import { useState } from "react";
    import chatsIcon from "./assets/chats.svg";
    import callsIcon from "./assets/calls.svg";
    import usersIcon from "./assets/users.svg";
    import groupsIcon from "./assets/groups.svg";
    import "./CometChatTabs.css";

    export const CometChatTabs = (props: {
        onTabClicked?: (tabItem: { name: string; icon?: string; }) => void;
        activeTab?: string;
    }) => {

        const {
            onTabClicked = () => { },
            activeTab
        } = props;

        const [hoverTab, setHoverTab] = useState("");

        const tabItems = [
            {
                "name": "CHATS",
                "icon": chatsIcon
            },
            {
                "name": "CALLS",
                "icon": callsIcon
            },
            {
                "name": "USERS",
                "icon": usersIcon
            },
            {
                "name": "GROUPS",
                "icon": groupsIcon
            }
        ]

        return (
            <div className="cometchat-tab-component">
                {
                    tabItems.map((tabItem) => (
                        <div
                            key={tabItem.name}
                            className="cometchat-tab-component__tab"
                            onClick={() => onTabClicked(tabItem)}
                        >
                            <div
                                className={(activeTab === tabItem.name.toLowerCase() || hoverTab === tabItem.name.toLowerCase()) ? "cometchat-tab-component__tab-icon cometchat-tab-component__tab-icon-active" : "cometchat-tab-component__tab-icon"}
                                style={tabItem.icon ? {
                                    WebkitMaskImage: `url("${tabItem.icon}")`,
                                    maskImage: `url("${tabItem.icon}")`,
                                } : undefined}
                                onMouseEnter={() => setHoverTab(tabItem.name.toLowerCase())}
                                onMouseLeave={() => setHoverTab("")}
                            />
                            <div
                                className={(activeTab === tabItem.name.toLowerCase() || hoverTab === tabItem.name.toLowerCase()) ? "cometchat-tab-component__tab-text cometchat-tab-component__tab-text-active" : "cometchat-tab-component__tab-text"}
                                onMouseEnter={() => setHoverTab(tabItem.name.toLowerCase())}
                                onMouseLeave={() => setHoverTab("")}
                            >
                                {tabItem.name}
                            </div>
                        </div>
                    ))
                }
            </div>
        )

    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css CometChatTabs.css theme={null}
    .cometchat-tab-component {
        display: flex;
        width: 100%;
        padding: 0px 8px;
        align-items: flex-start;
        gap: 8px;
        border-top: 1px solid var(--cometchat-border-color-light, #F5F5F5);
        border-right: 1px solid var(--cometchat-border-color-light, #F5F5F5);
        background: var(--cometchat-background-color-01, #FFF);
    }

    .cometchat-tab-component__tab {
        display: flex;
        padding: 12px 0px 10px 0px;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 4px;
        flex: 1 0 0;
        min-height: 48px;
    }

    .cometchat-tab-component__tab-icon {
        display: flex;
        width: 32px;
        height: 32px;
        justify-content: center;
        align-items: center;
        background: var(--cometchat-icon-color-secondary, #A1A1A1);
        -webkit-mask-size: contain;
        -webkit-mask-position: center;
        -webkit-mask-repeat: no-repeat;
        mask-size: contain;
        mask-position: center;
        mask-repeat: no-repeat;
        cursor: pointer;
    }

    .cometchat-tab-component__tab-text {
        color: var(--cometchat-text-color-secondary, #727272);
        text-align: center;
        font: var(--cometchat-font-caption1-medium, 500 12px Roboto);
        cursor: pointer;
    }

    .cometchat-tab-component__tab-icon-active {
        background: var(--cometchat-icon-color-highlight);
    }

    .cometchat-tab-component__tab-text-active {
        color: var(--cometchat-text-color-highlight);
    }
    ```
  </Tab>
</Tabs>

***

### **Step 2: Create Sidebar**

Let's create the `Sidebar` component which will render different conversations.

#### **Folder Structure**

Create a `CometChatSelector` folder inside your `src` directory and add the following files:

```
src/
│── CometChatSelector/ 
│   ├── CometChatSelector.tsx
│   ├── CometChatSelector.css
```

<Tabs>
  <Tab title="TypeScript">
    ```tsx CometChatSelector.tsx theme={null}
    import { useEffect, useState } from "react";
    import { Call, Conversation, Group, User, CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatCallLogs, CometChatConversations, CometChatGroups, CometChatUIKitLoginListener, CometChatUsers } from "@cometchat/chat-uikit-react";
    import { CometChatTabs } from "../CometChatTabs/CometChatTabs";
    import "./CometChatSelector.css";

    interface SelectorProps {
        onSelectorItemClicked?: (input: User | Group | Conversation | Call, type: string) => void;
        onHide?: () => void;
        onNewChatClicked?: () => void;
    }

    export const CometChatSelector = (props: SelectorProps) => {
        const {
            onSelectorItemClicked = () => { },
        } = props;

        const [loggedInUser, setLoggedInUser] = useState<CometChat.User | null>();
        const [activeItem, setActiveItem] = useState<CometChat.Conversation | CometChat.User | CometChat.Group | CometChat.Call | undefined>();
        const [activeTab, setActiveTab] = useState<string>("chats");

        useEffect(() => {
            const loggedInUsers = CometChatUIKitLoginListener.getLoggedInUser();
            setLoggedInUser(loggedInUsers)
        }, [])

        return (
            <>
                {loggedInUser && <>
                    {activeTab == "chats" ? (
                        <CometChatConversations
                            activeConversation={activeItem instanceof CometChat.Conversation ? activeItem : undefined}
                            onItemClick={(e) => {
                                setActiveItem(e);
                                onSelectorItemClicked(e, "updateSelectedItem");
                            }}
                        />
                    ) : activeTab == "calls" ? (
                        <CometChatCallLogs
                            activeCall={activeItem instanceof CometChat.Call ? activeItem : undefined}
                            onItemClick={(e: Call) => {
                                setActiveItem(e);
                                onSelectorItemClicked(e, "updateSelectedItemCall");
                            }}
                        />
                    ) : activeTab == "users" ? (
                        <CometChatUsers
                            activeUser={activeItem instanceof CometChat.User ? activeItem : undefined}
                            onItemClick={(e) => {
                                setActiveItem(e);
                                onSelectorItemClicked(e, "updateSelectedItemUser");
                            }}
                        />
                    ) : activeTab == "groups" ? (
                        <CometChatGroups
                            activeGroup={activeItem instanceof CometChat.Group ? activeItem : undefined}
                            onItemClick={(e) => {
                                setActiveItem(e);
                                onSelectorItemClicked(e, "updateSelectedItemGroup");
                            }}
                        />
                    ) : null}
                </>}
                <CometChatTabs activeTab={activeTab} onTabClicked={(item: { name: string; icon?: string; }) => {
                    setActiveTab(item.name.toLowerCase())
                }} />
            </>
        );
    }
    ```
  </Tab>

  <Tab title="CSS">
    ```css CometChatSelector.css theme={null}
    .selector-wrapper .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon {
        background: var(--cometchat-icon-color-primary);
    }

    .cometchat-conversations .cometchat-list__header-menu .cometchat-button__icon:hover {
        background: var(--cometchat-icon-color-highlight);
    }

    .cometchat-list__header-search-bar {
        border-right: none;
    }

    .cometchat .cometchat-menu-list__sub-menu-list-item {
        text-align: left;
    }

    .cometchat .cometchat-conversations .cometchat-menu-list__sub-menu-list {
        width: 212px;
        top: 40px !important;
        left: 172px !important;
    }

    #logged-in-user {
        border-bottom: 2px solid var(--cometchat-border-color-default, #E8E8E8);
    }

    #logged-in-user .cometchat-menu-list__sub-menu-item-title,
    #logged-in-user .cometchat-menu-list__sub-menu-list-item {
        cursor: default;
    }

    .cometchat-menu-list__sub-menu-list-item-icon-log-out {
        background-color: var(--cometchat-error-color, #F44649);
    }

    .cometchat-menu-list__sub-menu-item-title-log-out {
        color: var(--cometchat-error-color, #F44649)
    }

    .chat-menu .cometchat .cometchat-menu-list__sub-menu-item-title {
        cursor: pointer;
    }

    .chat-menu .cometchat .cometchat-menu-list__sub-menu {
        box-shadow: none;
    }

    .chat-menu .cometchat .cometchat-menu-list__sub-menu-icon {
        background-color: var(--cometchat-icon-color-primary, #141414);
        width: 24px;
        height: 24px;
    }
    ```
  </Tab>
</Tabs>

### **Step 3: Update App**

Now we will update the `App.tsx` & `App.css` files to import these new components as below,

<Tabs>
  <Tab title="TypeScript">
    ```tsx App.tsx theme={null}
    import { useState } from "react";
    import { CometChatMessageComposer, CometChatMessageHeader, CometChatMessageList } from "@cometchat/chat-uikit-react";
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatSelector } from "./CometChatSelector/CometChatSelector";
    import "./App.css";
    import '@cometchat/chat-uikit-react/css-variables.css';

    function App() {
      const [selectedUser, setSelectedUser] = useState<CometChat.User | undefined>(undefined);
      const [selectedGroup, setSelectedGroup] = useState<CometChat.Group | undefined>(undefined);
      const [selectedCall, setSelectedCall] = useState<CometChat.Call | undefined>(undefined);

      return (
        <div className="conversations-with-messages">
          <div className="conversations-wrapper">
            <CometChatSelector onSelectorItemClicked={(activeItem) => {
              let item = activeItem;
              if (activeItem instanceof CometChat.Conversation) {
                item = activeItem.getConversationWith();
              }
              if (item instanceof CometChat.User) {
                setSelectedUser(item as CometChat.User);
                setSelectedCall(undefined);
                setSelectedGroup(undefined);
              } else if (item instanceof CometChat.Group) {
                setSelectedUser(undefined);
                setSelectedGroup(item as CometChat.Group);
                setSelectedCall(undefined);
              }
              else if (item instanceof CometChat.Call) {
                //custom logic to open call details
                setSelectedUser(undefined);
                setSelectedGroup(undefined);
                setSelectedCall(item as CometChat.Call);
              }
            }} />
          </div>
          {selectedUser || selectedGroup || selectedCall ? (
            <div className="messages-wrapper">
              <CometChatMessageHeader user={selectedUser} group={selectedGroup} />
              <CometChatMessageList user={selectedUser} group={selectedGroup} />
              <CometChatMessageComposer user={selectedUser} group={selectedGroup} />
            </div>
          ) : (
            <div className="empty-conversation">Select Conversation to start</div>
          )}
        </div>
      );
    };

    export default App;
    ```
  </Tab>

  <Tab title="CSS">
    ```css App.css theme={null}
    #root {
      text-align: center;
      width: 100vw;
      height: 100vh;
      background-color: #282c34;
    }

    .conversations-with-messages {
      display: flex;
      height: 100%;
      width: 100%;
      flex-direction: row;
    }

    .conversations-wrapper {
      height: 100vh;
      width: 480px;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }

    .conversations-wrapper>.cometchat {
      overflow: hidden;
    }

    .messages-wrapper {
      width: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }

    .empty-conversation {
      height: 100vh;
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      background: var(--cometchat-background-color-03, #F5F5F5);
      color: var(--cometchat-text-color-secondary, #727272);
      font: var(--cometchat-font-body-regular, 400 14px Roboto);
    }

    .cometchat .cometchat-message-composer {
      border-radius: 0px;
    }
    ```
  </Tab>
</Tabs>

### **Step 4: Run the project**

```powershell theme={null}
npm start
```

***

## **Next Steps**

### **Enhance the User Experience**

* **[Advanced Customizations](/ui-kit/react/theme)** – Personalize the chat UI to align with your brand.

***
