Skip to main content
Gremorie

Plan

Collapsible plan card with shimmer-marked title while streaming and an expandable body for steps and actions.

Overview

Plan is a collapsible Card that surfaces the assistant's plan before it executes. The title and description run through Shimmer while isStreaming is true, then settle into static text once the plan is final. A toggle in the header expands or collapses the body so users can skim or audit.

Use it for any flow where the model proposes a plan before acting (multi-step agents, deploy bots, codegen). For granular per-step status icons and search citations, layer Chain of Thought or Task inside PlanContent.

Preview

Collapsed

Generate landing page
3 steps - 12s estimated

Expanded

Generate landing page
3 steps - 12s estimated
Hero, features, CTA section composed from rx-display and rx-forms.

Streaming

Composing the layout

Streaming response from the model...

Resolving primitives required for this composition.

Installation

bash npx gremorie@latest add rx-plan
bash pnpm dlx gremorie@latest add rx-plan
bash yarn dlx gremorie@latest add rx-plan
bash bunx --bun gremorie@latest add rx-plan

Usage

import {
  Plan,
  PlanHeader,
  PlanTitle,
  PlanDescription,
  PlanContent,
} from "@gremorie/rx-ai";

export function Example() {
  return (
    <Plan defaultOpen>
      <PlanHeader>
        <PlanTitle>Generate landing page</PlanTitle>
        <PlanDescription>3 steps - 12s estimated</PlanDescription>
      </PlanHeader>
      <PlanContent>
        Hero, features, CTA section composed from rx-display and rx-forms.
      </PlanContent>
    </Plan>
  );
}

Angular edition planned for Phase 5h. Star the repo to track progress.

API

<Plan>

PropTypeDefaultDescription
isStreamingbooleanfalseWhile true, PlanTitle and PlanDescription are rendered through Shimmer.
openboolean-Controlled open state.
defaultOpenboolean-Uncontrolled initial open state.
onOpenChange(open: boolean) => void-Notification when the user toggles.

Extends ComponentProps<typeof Collapsible>. Wraps a Card internally and removes its shadow.

<PlanHeader>

CardHeader with horizontal layout (items-start justify-between). Drop PlanTitle, PlanDescription and (optionally) PlanAction inside.

<PlanTitle>

PropTypeDefaultDescription
childrenstring-Required string (so Shimmer can apply per-character).

Wraps CardTitle.

<PlanDescription>

PropTypeDefaultDescription
childrenstring-Required string for the shimmer effect.

Wraps CardDescription.

<PlanAction>

CardAction slot for a custom action button in the header (e.g. "Regenerate plan").

<PlanTrigger>

Toggle button. Default renders a ghost icon button with ChevronsUpDownIcon and an sr-only "Toggle plan" label.

Forwards CollapsibleTrigger props via asChild.

<PlanContent>

The collapsible body. Wraps CardContent inside CollapsibleContent.

<PlanFooter>

CardFooter. Use for "Approve", "Regenerate", "Cancel" rows.

Composition

  1. <Plan> wraps the whole thing as a card + collapsible.
  2. <PlanHeader> carries title, description and (optionally) action / trigger.
  3. <PlanTitle> + <PlanDescription> are the streaming-aware text fields.
  4. <PlanTrigger> is the optional toggle handle (use PlanAction for other buttons).
  5. <PlanContent> is the expandable body. Compose ChainOfThought, Task, plain markdown or sub-components in here.
  6. <PlanFooter> is the action row at the bottom.

Variations

The standard pattern: title up top, expandable detail, approve / regenerate at the bottom.

<Plan defaultOpen>
  <PlanHeader>
    <PlanTitle>Migrate database to Postgres 16</PlanTitle>
    <PlanDescription>4 steps - 8 min estimated</PlanDescription>
    <PlanTrigger />
  </PlanHeader>
  <PlanContent>
    <ChainOfThought defaultOpen>
      <ChainOfThoughtHeader>Plan</ChainOfThoughtHeader>
      <ChainOfThoughtContent>
        <ChainOfThoughtStep status="complete" label="Snapshot current DB" />
        <ChainOfThoughtStep status="active" label="Run pg_upgrade" />
        <ChainOfThoughtStep status="pending" label="Switch DNS" />
        <ChainOfThoughtStep status="pending" label="Verify replication" />
      </ChainOfThoughtContent>
    </ChainOfThought>
  </PlanContent>
  <PlanFooter>
    <Button variant="outline">Regenerate</Button>
    <Button>Run plan</Button>
  </PlanFooter>
</Plan>

Streaming plan

Use while the plan itself is being generated. Title and description shimmer until isStreaming flips back.

<Plan defaultOpen isStreaming>
  <PlanHeader>
    <PlanTitle>Composing the layout</PlanTitle>
    <PlanDescription>Streaming response from the model...</PlanDescription>
  </PlanHeader>
  <PlanContent>Resolving primitives required for this composition.</PlanContent>
</Plan>

Plan with custom action

Replace the default trigger with a regenerate button via PlanAction.

<Plan defaultOpen>
  <PlanHeader>
    <PlanTitle>Outline the talk</PlanTitle>
    <PlanDescription>5 sections - 30 min</PlanDescription>
    <PlanAction>
      <Button size="sm" variant="ghost" onClick={regenerate}>
        <RefreshIcon className="size-4" />
        Regenerate
      </Button>
    </PlanAction>
  </PlanHeader>
  <PlanContent>...</PlanContent>
</Plan>

Accessibility

  • Keyboard: PlanTrigger is a CollapsibleTrigger, toggling on Enter / Space and participating in Tab order.
  • ARIA: Radix Collapsible wires aria-expanded and aria-controls automatically. The default PlanTrigger ships an sr-only "Toggle plan" label so the icon-only button still announces.
  • Screen readers: title and description live in semantic Card slots, so a plan announces as a single block with heading + supporting text.
  • Reduced motion: collapse / expand uses Tailwind data-state animations and respects prefers-reduced-motion.
  • Chain of Thought - per-step status inside the plan body
  • Task - file-level breakdown for a single step
  • Confirmation - approval prompt before running the plan
  • Shimmer - the streaming text effect used by PlanTitle / PlanDescription

On this page