Plan

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

Review plan
  1. Read the brief
  2. Check owners

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