Copy for LLM
NotificationCard
An incoming notification: avatar, sender, time, a message preview, and optional quick actions. The glanceable comms surface (richer than a Toast).
Installation
npx @glasskit-ui/cli add notification-cardInstall 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/notification-card.tsximport type { ReactNode } from "react";import { cn } from "../lib/utils";/** * <NotificationCard> — an incoming notification (message, mention, alert): a * leading avatar/glyph, sender + time, a message preview, and optional quick * actions. A popping surface, below the sightline like the real Display. Richer * than a toast (which is a transient one-liner): a NotificationCard waits for * the wearer and participates in focus. RTL-safe (logical layout). */export function NotificationCard({ avatar, title, time, children, actions, className,}: { /** Leading <Avatar> or app <Icon>. */ avatar?: ReactNode; /** Sender / app name. */ title: ReactNode; /** Optional timestamp. */ time?: ReactNode; /** The message preview. */ children: ReactNode; /** Optional action row (e.g. <QuickReplyChips> or <Button>s). */ actions?: ReactNode; className?: string;}) { return ( <div className={cn( "surface flex w-full flex-col gap-[13px] rounded-[22px] p-5 text-start", className, )} role="status" > <div className="flex items-center gap-[13px]"> {avatar != null ? ( <span className="inline-flex flex-none">{avatar}</span> ) : null} <span className="t-body min-w-0 flex-1 font-bold">{title}</span> {time != null ? ( <span className="t-caption flex-none text-foreground-faint"> {time} </span> ) : null} </div> <div className="t-body text-muted-foreground">{children}</div> {actions != null ? ( <div className="mt-[3px] flex justify-end gap-2.5">{actions}</div> ) : null} </div> );}Usage
<NotificationCard avatar={<Avatar name="Mara Lin" tone="violet" size="sm" />} title="Mara Lin" time="now"> On my way, be there in 5</NotificationCard>Props
| Prop | Type | Default | Description |
|---|---|---|---|
avatar | ReactNode | — | Leading <Avatar> or app glyph. |
title | ReactNode | — | Sender / app name. |
time | ReactNode | — | Optional timestamp. |
children | ReactNode | — | The message preview. |
actions | ReactNode | — | Optional action row. |
When to use
NotificationCard is for an actionable item that waits for the wearer and participates in focus. For a transient confirmation that just narrates what happened, fire a toast via the app-wide Toaster queue.
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.
MediaThumb
A photo / reel tile (Photos, Instagram): a rounded media tile with optional duration pill and caption overlay. Compose in a grid for a gallery.