Plan

A collapsible proposed plan with streaming title treatment, actions, and supporting context.

Review planProposed

Check the supplied brief before proposing changes.

  1. Read the current scope and responsibilities.
  2. Flag decisions without an owner.
  3. Prepare a draft for review.

Approve a proposed review

Review planProposed

Check the supplied brief before proposing changes.

  1. Read the current scope and responsibilities.
  2. Flag decisions without an owner.
  3. Prepare a draft for review.

Use it for

  • Supply plan content and application-owned actions. The title and description shimmer only while streaming.
  • The native disclosure starts open; open/defaultOpen/onOpenChange preserve controlled and uncontrolled usage.

Avoid

  • Treating a displayed plan as executed work.

React package

npm install @noorddev/vlak-react

Load the stylesheet once at your app root, then import the components you use.

import "@noorddev/vlak-react/css";
import { Plan, Button } from "@noorddev/vlak-react";

Per-component imports are available at @noorddev/vlak-react/components/plan.

Copy the source

npx @noorddev/vlak-cli add plan

Adds the component and its dependencies to components/vlak/. Follow the StyleX setup to compile the source in your application.

shadcn registry

npx shadcn add https://vlak.dev/r/plan.json

Installs the same source through the shadcn CLI.

import { Plan, Button } from "@noorddev/vlak-react";

export function ReviewPlan({ streaming, onApprove }: { streaming: boolean; onApprove: () => void }) {
  return <Plan title="Review plan" description="Two steps" streaming={streaming} actions={<Button variant="subtle" disabled={streaming} onClick={onApprove}>Approve plan</Button>}>
    <ol><li>Read the brief</li><li>Check owners</li></ol>
  </Plan>;
}

See the integration example to compose these components with your application's model and data.

Plan

A proposed plan with supplied steps and actions. Execution remains application-owned.

PropTypeDefaultDescription
titlerequiredstring
descriptionstring
streamingbooleanfalse
actionsReactNode
footerReactNode
statusLabelstring
defaultOpenboolean
onOpenChange(open: boolean) => void
variant"inline" | "panel"An inline disclosure for message activity, or a framed panel.
durationMsnumberOptional elapsed time supplied by the application, in milliseconds.
measureDurationbooleanMeasure this component's streaming interval. Off by default.
autoExpandbooleanOpen when a new streaming interval begins. Manual disclosure remains the default.
autoCollapseDelaynumber | falseClose once after completion unless the reader manually changed the disclosure.

Also accepts Omit<DetailsHTMLAttributes<HTMLDetailsElement>, "title">.

The ref reaches HTMLDetailsElement.

KeysDoes
TabMoves through the supplied native controls in reading order
Enter, SpaceActivates focused buttons and disclosure summaries
  • Native attributes, className, style, and the forwarded ref reach the outer element.
  • Interactive content requires accessible names; progress text is not announced for every streamed token.

The same styles are available as CSS. Native HTML provides the static presentation; React or application code supplies state updates and actions.

npm install @noorddev/vlak
import "@noorddev/vlak/css";
<details class="rs-plan" open><summary>Review plan</summary><ol><li>Read the brief</li><li>Check owners</li></ol></details>

Classes

.rs-plan.rs-plan-description.rs-plan-actions.rs-plan-footer