Skip to content
Notra logoNotra UI
Esc
↑↓navigate↵open⌘Jpreview
On this page

Message

Gemini's user pill and bubble-less assistant turn.

import { Card } from "@/components/ui/card";

import { GeminiMessage } from "../components/gemini-message";
import { GeminiStoryText } from "../components/gemini-story-text";
import { GEMINI_STORY_THREAD } from "../constants/gemini-story";

export default function GeminiMessageExample() {
  return (
    <Card className="border-gemini-border bg-gemini-bg flex w-full min-w-0 flex-col gap-8 overflow-hidden rounded-2xl border px-4 py-8 text-base ring-0">
      {GEMINI_STORY_THREAD.map((message) => (
        <GeminiMessage from={message.from} key={message.id}>
          {message.from === "user" ? (
            message.text
          ) : (
            <GeminiStoryText sources={message.sources} text={message.text} />
          )}
        </GeminiMessage>
      ))}
    </Card>
  );
}
$ bunx --bun shadcn@latest add @notra/gemini-message

GeminiMessage renders a user turn as a gray pill capped at 70% width and aligned to the end. Assistant turns have no bubble. They stack thoughts, status, the reply and actions, and the actions fade in on hover or focus. On touch screens they stay visible.

Prop Default Description
from "user" or "assistant".
thoughts Renders first in an assistant turn, usually GeminiThoughts.
status Renders above an assistant reply, like GeminiThinking.
actions Renders under an assistant reply, like GeminiActions.

Everything else goes to the root div.

Used in

Gemini

A full recreation of the Gemini chat with the animated sparkle, streamed replies and a model picker.