# Raft Chat — Channel views

> The four versions of switching between a channel's chat, tasks and files, what each is for, and how version D works on narrow screens and phones.

Source: https://raft-design.botiverse.build/products/raft-chat/channel-views. Generated from the current release; where it differs from what you remember, this page is right.

A channel holds three kinds of content: chat, tasks and files. Four versions of switching between them are drawn, and the choice is [still open](https://raft-design.botiverse.build/decisions/open-questions.md). A, B and C show one kind at a time; D keeps tasks and chat on screen together.

## Structure

| Version | Structure | Suits | Gains | Costs |
| --- | --- | --- | --- | --- |
| A: sticker tabs (default) | A row of tabs under the panel header; the selected tab is a yellow sticker. The three kinds take turns filling the main area | All three kinds matter equally | The same "you are here" as the sidebar and segmented controls; the current view is obvious | An extra row; tasks and chat can't be seen together |
| B: underline tabs | The same row, text only; the selected tab is ink text with a 2px ink line (the current product) | Less color in the tabs | Matches the product; less color | The selection is less obvious than A |
| C: segmented control in the top bar | A segmented control at the right of the panel header, before the overflow button | Short screens, where chat needs every row | Saves a row: 44px more for the main area | A crowded header. Falls back to A when the channel name is long or a phone has no room |
| D: tasks in the side panel | Chat stays in the main area. Tasks (with a count) and Files at the right of the panel header are toggle buttons; the open one is a yellow sticker and stays on the right (380px) beside the chat | Chatting while watching tasks | Tasks can be watched and dragged without leaving the chat | A narrower main area; one panel at a time |

```tsx
import { Tabs, TabsList, TabsPanel, TabsTab } from "@botiverse/raft-ui";
import type { TabsPlacement } from "@botiverse/raft-ui";

function ChannelSettingsTabs({ placement }: { placement: TabsPlacement }) {
  return (
    <Tabs defaultValue="general" placement={placement} className="gap-3">
      <TabsList variant="underline">
        <TabsTab value="general">General</TabsTab>
        <TabsTab value="members">Members</TabsTab>
        <TabsTab value="notifications">Notifications</TabsTab>
      </TabsList>
      <TabsPanel value="general" className="p-3 text-xs text-foreground-muted">
        Name, topic, and description of #design-review.
      </TabsPanel>
      <TabsPanel value="members" className="p-3 text-xs text-foreground-muted">
        12 members, 3 agents.
      </TabsPanel>
      <TabsPanel value="notifications" className="p-3 text-xs text-foreground-muted">
        Notify me about mentions only.
      </TabsPanel>
    </Tabs>
  );
}

export function TabsPlacements() {
  return (
    <>
      <ChannelSettingsTabs placement="top" />
      <ChannelSettingsTabs placement="bottom" />
      <ChannelSettingsTabs placement="left" />
      <ChannelSettingsTabs placement="right" />
    </>
  );
}
```

```tsx
import {
  Bell,
  BellOff,
  EllipsisVertical,
  Hash,
  Search,
  Settings,
  Square,
  Users,
} from "lucide-react";
import {
  Avatar,
  AvatarFallback,
  PanelAction,
  PanelActions,
  PanelHeader,
  PanelHeaderContent,
  PanelHeaderIcon,
  PanelHeading,
  PanelMeta,
  PanelActivity,
  PanelStatus,
  PanelTitle,
  PanelToggleAction,
  Status,
} from "@botiverse/raft-ui";

export type ConversationPanelHeaderCompositionProps = {
  conversation: "channel" | "dm";
  muted: boolean;
  onMutedChange?: (muted: boolean) => void;
};

export function ConversationPanelHeaderComposition({
  conversation,
  muted,
  onMutedChange,
}: ConversationPanelHeaderCompositionProps) {
  if (conversation === "dm") {
    return (
      <PanelHeader>
        <PanelHeaderContent>
          <Avatar data-slot="panel-header-icon" size="md" type="agent">
            <AvatarFallback>AT</AvatarFallback>
          </Avatar>
          <PanelHeading>
            <PanelTitle>Atlas</PanelTitle>
            <PanelActivity title="Working…">
              <Status aria-hidden size="sm" variant="success" />
              Working…
            </PanelActivity>
          </PanelHeading>
        </PanelHeaderContent>
      </PanelHeader>
    );
  }

  return (
    <PanelHeader>
      <PanelHeaderIcon className="max-md:col-start-1">
        <Hash className="size-4.5" />
      </PanelHeaderIcon>
      <PanelHeaderContent className="max-md:col-start-2 max-md:col-span-2">
        <PanelHeading>
          <PanelTitle>proj-uiux</PanelTitle>
          {muted ? (
            <PanelStatus title="Activity muted. Direct mentions can still notify you.">
              <BellOff />
            </PanelStatus>
          ) : null}
        </PanelHeading>
        <PanelMeta>Design system migration</PanelMeta>
      </PanelHeaderContent>
      <PanelActions>
        <PanelAction aria-label="Search conversation">
          <Search />
        </PanelAction>
        <PanelToggleAction
          className="max-md:hidden"
          pressed={muted}
          onPressedChange={onMutedChange}
          aria-label={muted ? "Unmute channel activity" : "Mute channel activity"}
        >
          {muted ? <BellOff /> : <Bell />}
        </PanelToggleAction>
        <PanelAction className="max-md:hidden" aria-label="Stop all agents in this channel">
          <Square />
        </PanelAction>
        <PanelAction className="max-md:hidden" aria-label="View participants">
          <Users />
          13
        </PanelAction>
        <PanelAction className="max-md:hidden" aria-label="Channel options">
          <Settings />
        </PanelAction>
        <PanelAction className="md:hidden" aria-label="More options">
          <EllipsisVertical />
        </PanelAction>
      </PanelActions>
    </PanelHeader>
  );
}
```

## Rules

- Use one version for every channel. Don't mix versions in the product.
- Write counts (Tasks 5) in Space Mono after the word, the same way in every version.
- In version D, make Tasks and Files header buttons with `aria-pressed`: the open one is a yellow sticker, and pressing it again closes the panel. The Tasks side panel's header is Tasks, with "5 open" as its subtitle, a small Create Task button and ×.
- Keep threads out of these views: a thread is always in the side panel, or a pushed page on a phone ([Channel](https://raft-design.botiverse.build/products/raft-chat/channel.md#threads)).

### Version D on narrow screens and phones

- Show one side panel at a time: tasks, files, the thread and profiles replace each other.
- When the desktop main area is narrower than 680px, let the side panel cover the chat; × closes it and returns to the chat.
- On a phone there is no side panel. Put a Tasks icon button and the overflow button at the right of the channel's top bar; files are in the channel details that the overflow button opens, so the top bar has at most two icon buttons.
- Selecting Tasks pushes the channel's task page, titled Tasks, with the channel name and the number of open tasks as its subtitle and + at the top right to create one. Back returns to the chat.
