Blocks
Copy for LLM
ChatBubble
A conversation view. <MessageThread> stacks <ChatBubble>s, where from="them" is a surface bubble at the start and from="me" is the accent-gradient bubble at the end. RTL-safe.
Installation
npx @glasskit-ui/cli add chat-bubbleInstall the SDK (it provides GlassViewport, useDpad and the stylesheet), then copy these files into your project:
npm install @glasskit-ui/react// components/lib/utils.tsimport { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";export type { ClassValue };/** * Merge class names the shadcn way: clsx joins conditionals, tailwind-merge * de-dupes conflicting Tailwind utilities so a consumer's `className` override * wins (e.g. passing `px-2` beats the component's `px-6`). Lens components are * Tailwind utilities + `--gk-*` tokens, so this de-dupe matters. */export function cn(...inputs: ClassValue[]): string { return twMerge(clsx(inputs));}/** * Accessible name from a free-form `label` prop: the label itself when it's a * plain string, otherwise undefined (a ReactNode can't become an aria-label). */export function stringLabel(label: unknown): string | undefined { return typeof label === "string" ? label : undefined;}// components/glasskit/chat-bubble.tsximport type { ReactNode } from "react";import { cn } from "../lib/utils";/** * <MessageThread> — a vertical stack of <ChatBubble>s (a conversation view). * Newest at the bottom; scrolls like <List>. RTL-safe (logical alignment). */export function MessageThread({ children, className,}: { children: ReactNode; className?: string;}) { return ( <div className={cn( "flex h-full w-full flex-col justify-end gap-2.5 overflow-y-auto", className, )} > {children} </div> );}/** * <ChatBubble> — one message. `from="me"` is the accent-gradient bubble aligned * to the inline-end; `from="them"` is a surface bubble at the inline-start. */export function ChatBubble({ from = "them", children, className,}: { from?: "me" | "them"; children: ReactNode; className?: string;}) { return ( <div className={cn( "t-body max-w-[82%] rounded-[22px] px-[18px] py-3.5", from === "me" ? "self-end rounded-ee-[7px] border border-white/20 text-white [background:var(--accent-surface)] [box-shadow:inset_0_1px_0_rgba(255,255,255,0.35),0_10px_22px_-12px_var(--accent-glow)]" : "surface self-start rounded-es-[7px]", className, )} > {children} </div> );}Usage
<MessageThread> <ChatBubble from="them">Where are you?</ChatBubble> <ChatBubble from="me">Two blocks away</ChatBubble></MessageThread>Props
| Prop | Type | Default | Description |
|---|---|---|---|
MessageThread · children | ReactNode | — | ChatBubble elements. |
ChatBubble · from | "me" | "them" | "them" | Alignment + style. |
ChatBubble · children | ReactNode | — | The message. |
CallCard
An incoming / active call: a big avatar, caller name, a status line, and round accept / decline actions (the one place a semantic green/red reads clearer than the single accent).
NotificationCard
An incoming notification: avatar, sender, time, a message preview, and optional quick actions. The glanceable comms surface (richer than a Toast).