Chat Sidebar

Bir sohbet uygulaması için kenar çubuğu. Üstte logo, arama ve Yeni sohbet, altında kendi bağlantılarınız, sabitlenmiş sohbetler, sohbetlerini göstermek için genişleyen projeler, güne göre gruplanmış son sohbetler ve hover ile sağ tık menüleri, satır içi yeniden adlandırma, geri alınabilir silme ve canlı yanıt durumları olan satırlar.

ChatGPT, Claude, Perplexity ve Grok'un hepsi aynı kenar çubuğunda anlaştı: üstten sohbet başlat ya da ara, birkaç sohbeti sabitle, işleri projelerde grupla ve geri kalan her şeyi güne göre geriye doğru kaydır. Chat Sidebar, HextaUI Sidebar'ın inset varyantı üzerine kurulu bu kenar çubuğudur; böylece konuşma çerçevenin içinde kendi yuvarlak panelinde durur. Masaüstünde simge çubuğuna daralır; telefonlarda ekranı dolduracak şekilde kayarak gelir ve bir sohbet seçer seçmez kayarak gider.

Başlıkta logonuz, bir arama düğmesi ve daralt düğmesi bulunur. Altında kısayolu her zaman görünür New chat, ardından ilettiğiniz Images, Library veya Plugins gibi bağlantılar gelir. Projeler, her biri kendi simgesine sahip daraltılabilir klasörlerdir ve sohbetleri geçmişte değil içlerinde girintili durur. Son sohbetler Today, Yesterday, Previous 7 days, Previous 30 days ve ardından aya göre gruplanır, kaydırdıkça sayfa sayfa render edilir; böylece binlerce sohbet anında açılır.

Her satırın hover'da bir menüsü ve sağ tıklamada aynı menüsü vardır: sabitle, yeniden adlandır, projeye taşı ve sil. Yeniden adlandırma çift tıklama veya F2 ile yerinde yapılır. Delete sohbeti hemen gizler ve onDelete çağrılmadan önce beş saniye Undo sunar. Yanıt veren bir sohbet spinner, başka yerde biten bir sohbet nokta gösterir; ikisi de hover'da menü düğmesine yer açar. Hesap menüsü, ilettiğiniz öğelerin üstünde adınız ve e-postanızla yukarı doğru açılır.

  1. Pro registry'yi components.json dosyasına ekleyin

    components.json
    {
      "registries": {
        "@hextaui-pro": {
          "url": "https://hextaui.com/r/pro/{name}.json",
          "headers": {
            "Authorization": "Bearer ${HEXTAUI_PRO_TOKEN}"
          }
        }
      }
    }
  2. Token'ınızı ekleyin

    Hesap sayfanızda bir token oluşturun ve .env.local dosyasına HEXTAUI_PRO_TOKEN olarak ekleyin.

  3. Bloğu ekleyin

    pnpm dlx shadcn@latest add @hextaui-pro/chat-sidebar

State'inize bağlayın

Sohbetleri ve desteklediğiniz işleyicileri iletin. Her menü öğesi yalnızca işleyicisi ayarlıysa görünür; bu yüzden salt okunur bir geçmiş yalnızca onSelect ve onNewChat gerektirir.

"use client"

import * as React from "react"

import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"

import { ChatSidebar } from "@/components/blocks/chat-sidebar/chat-sidebar"
import type { SidebarChat } from "@/components/blocks/chat-sidebar/chats"

export function App({ initialChats }: { initialChats: SidebarChat[] }) {
  const [chats, setChats] = React.useState(initialChats)
  const [activeId, setActiveId] = React.useState<string | null>(null)

  const update = (id: string, change: Partial<SidebarChat>) =>
    setChats((current) => current.map((chat) => (chat.id === id ? { ...chat, ...change } : chat)))

  return (
    <SidebarProvider>
      <ChatSidebar
        chats={chats}
        activeId={activeId}
        onSelect={setActiveId}
        onNewChat={() => setActiveId(null)}
        onRename={(id, title) => update(id, { title })}
        onPinnedChange={(id, pinned) => update(id, { pinned })}
        onDelete={(id) => setChats((current) => current.filter((chat) => chat.id !== id))}
        user={{ name: "Mia Chen", plan: "Pro plan" }}
      />
      <SidebarInset />
    </SidebarProvider>
  )
}

Projeler ve yönlendirme

Her proje, kendi simgesi olan daraltılabilir bir klasördür. Sohbetleri tarihli geçmişte değil, içinde girintili durur. onMove her satıra Move to project ekler.

"use client"

import { useRouter } from "next/navigation"

import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"

import { ChatSidebar } from "@/components/blocks/chat-sidebar/chat-sidebar"
import type { SidebarChat, SidebarProject } from "@/components/blocks/chat-sidebar/chats"

export function Workspace({
  chats,
  projects,
  activeId,
  moveChat,
  children,
}: {
  chats: SidebarChat[]
  projects: SidebarProject[]
  activeId: string | null
  moveChat: (id: string, projectId: string | null) => void
  children: React.ReactNode
}) {
  const router = useRouter()

  return (
    <SidebarProvider>
      <ChatSidebar
        chats={chats}
        projects={projects}
        activeId={activeId}
        onSelect={(id) => router.push(`/c/${id}`)}
        onNewChat={() => router.push("/")}
        defaultOpenProjects={projects.slice(0, 1).map((project) => project.id)}
        onMove={moveChat}
      />
      <SidebarInset>{children}</SidebarInset>
    </SidebarProvider>
  )
}

Yapı

Dıştan içe doğru birleştirdiğiniz parçalar.

ParçaAçıklama
ChatSidebarTüm kenar çubuğu: başlık, New chat ve bağlantılar, sabitlenmiş sohbetler, projeler, tarihli geçmiş ve hesap menüsü.
groupChatsSohbetleri en yeniden başlayarak sıralar ve kenar çubuğunun gösterdiği tarihli gruplara böler.
searchChatsArama iletişim kutusunun kullandığı kelime tabanlı başlık araması. Boş sorgu için en son 8 sohbeti döndürür.
PropTürVarsayılan
chatsHer sohbet, herhangi bir sırada. Her birinde id, title, updatedAt (ms) ve isteğe bağlı projectId, pinned ve status ("streaming" veya "unread") vardır.
SidebarChat[]–
projectsid, name ve isteğe bağlı icon içeren projeler. Her biri sohbetlerini tutan daraltılabilir bir klasör olarak render edilir. Boşken bölüm gizlenir.
SidebarProject[][]
activeIdGeçerli sayfa olarak işaretlenmiş açık sohbet.
string | null–
onSelectListeden, aramadan ya da simge çubuğundaki son sohbetler kartından bir sohbet seçildiğinde çağrılır.
(id: string) => void–
onNewChatNew chat düğmesinden ve ⌘⇧O ile çağrılır.
() => void–
linksNew chat altında Images, Library veya Plugins gibi ek satırlar. Simge çubuğunda tooltip'li simge olarak kalırlar.
{ label, icon, href?, active?, onSelect? }[][]
defaultOpenProjectsGenişletilmiş başlayan projeler.
string[][]
onProjectOpenChangeBir proje genişletildiğinde veya daraltıldığında çağrılır; böylece hatırlayabilirsiniz.
(id: string, open: boolean) => void–
onRenameRename'i, çift tıklamayı ve F2'yi etkinleştirir. Yalnızca başlık gerçekten değiştiyse çağrılır.
(id: string, title: string) => void–
onPinnedChangePin ve Unpin'i etkinleştirir.
(id: string, pinned: boolean) => void–
onMoveMove to project'i etkinleştirir. null sohbeti projesinden çıkarır.
(id: string, projectId: string | null) => void–
onDeleteDelete'i etkinleştirir. Beş saniyelik Undo süresi dolduktan sonra çağrılır.
(id: string) => void–
brandArama ve daralt düğmelerinin yanında, en üstteki logonuz.
ReactNode–
userAlt bilgide hesap düğmesini gösterir.
{ name, email?, image?, plan? }–
accountMenuAd ve e-postanın altındaki DropdownMenu öğeleri; Settings, bir Help alt menüsü ve Log out gibi.
ReactNode–
pageSizeAynı anda kaç geçmiş satırı render edileceği. Listenin sonuna yaklaştıkça daha fazlası yüklenir.
number60
classNameSidebar kökü için sınıflar.
string–
TuşAction
⌘KSohbet aramasını açar veya kapatır. Başlıktaki arama düğmesi aynısını yapar.
⌘⇧OYeni bir sohbet başlatır.
⌘BSimge çubuğuna daraltır ya da genişletir. Telefonlarda tam ekran kenar çubuğunu açar veya kapatır.
F2Odaktaki sohbeti yeniden adlandırır. Çift tıklama aynısını yapar.
EnterOdaktaki projeyi genişletir veya daraltır. Yeniden adlandırırken yeni başlığı kaydeder; alandan ayrılmak da kaydeder.
EscYeniden adlandırmayı iptal eder ya da bir menüyü veya aramayı kapatır.
  • Açık sohbet aria-current="page" ile işaretlenir ve her satırın menü düğmesi sohbetinin adını taşır, örneğin “Options for Pricing page copy”. Yanıt durumları yalnızca spinner veya nokta olarak gösterilmek yerine “Replying” ve “Unread reply” olarak duyurulur.
  • Menü düğmeleri fare kullanıcıları için hover'da görünür ama Tab ile erişilebilir kalır ve her satır eylemi o menüdedir; böylece hiçbir şey sağ tık ya da çift tıklamaya bağlı değildir. Projeler aria-expanded bildirir ve bir proje açıldıktan sonra sohbetleri tarayıcının bul özelliğiyle bulunabilir kalır.
  • Yazılan başlık ve telefonlardaki tam ekran kayma, azaltılmış hareketi dikkate alır. Undo zaman aşımına kadar toast'ta kalır ve bir sohbet silindiğinde odak olduğu yerde kalır.

Şunlarla geliştirildi

Chat Sidebar bloğunun yapıldığı ücretsiz HextaUI bileşenleri. Her biri tek başına yüklenir.

Kod

3 dosya, components/blocks/chat-sidebar konumuna eklendi.