Component levee-brand-strategy not found in registry.
Demos (UI only, no backend)
The following demo shows different ways to use Levee: full workflow (form then chat), form-only stage, chat-only stage, and rail with lock checklist. All run in the browser with no API calls.
Overview
Levee is a set of React components for staged, goal-directed workflows. You provide a list of stages (each with id, title, lock items, and mode). The root Levee wraps everything in a provider; the rail shows progress and stage status; the stage view shows the active stage (form, chat, or synthesis). The agent (or completion logic) marks lock items satisfied; the stage does not advance until those criteria are met. Use Levee for strategy flows, onboarding, or any process with a defined "done."
Installation
Levee is part of AI Elements. It is not a CLI-installable UI block. Install the AI SDK and import from the ai-elements package:
pnpm add ai @ai-sdk/openai
import {
Levee,
LeveeRail,
LeveeStageCollectedData,
LeveeStageHeader,
LeveeStageLockChecklist,
LeveeStageView,
useLevee,
} from "@/components/ai-elements/levee"For the progress ring used inside the rail and lock checklist, the component uses LeveeProgressRing from @/components/ai-elements/levee-progress internally; you only need to import from levee for the public API above.
Core components
| Export | Purpose |
|---|---|
Levee | Root layout and provider; takes config, allowRevisit, onComplete, etc. |
useLevee | Hook to read and update stage state (stages, activeStageIndex, updateLockItems, advanceStage, etc.). |
LeveeRail | Sidebar listing all stages with status and progress. |
LeveeRailItem | Single stage row (used inside LeveeRail). |
LeveeStageView | Main area for the active stage; renders children and the interstitial overlay. |
LeveeStageHeader | Stage title, description, and sidebar toggle. |
LeveeStageSplit | Optional resizable split (chat + context panel). |
LeveeStageChat | Flex column container for chat content. |
LeveeConversation | Scrollable conversation area with scroll-to-bottom button. |
LeveeStageForm | Renders initial input fields (from config) in the context panel. |
LeveeStageFormView | Full form-stage layout (fields plus confirm message). |
LeveeStageLockChecklist | Lock items list and progress ring. |
LeveeStageCollectedData | Key-value display of collected data for a stage. |
LeveeStageContextPanel | Wrapper for context content (checklist, data, form). |
LeveeInterstitial | "Stage complete" overlay shown between stage transitions. |
Types
- LeveeStageConfig:
id,title,description,objective,mode?(one of"form","chat","synthesis"),lockItems,initialInputs,agentInstructions,tools,maxSteps?. - LeveeStageState:
id,status,phase,formData,collectedData,lockItems,lockPercentage,summary?. - LeveeLockItem:
id,label,satisfied. - LeveeInputField:
id,label,type(e.g.text,textarea,select,multiselect,number),placeholder?,description?,required?,options?.
Full TypeScript definitions live in @/components/ai-elements/levee.
Usage
Minimal structure: wrap with Levee, put LeveeRail and the active stage content in LeveeStageView. Use useLevee() inside children to drive chat, forms, and lock updates.
import type { LeveeStageConfig } from "@/components/ai-elements/levee"
const stages: LeveeStageConfig[] = [
{
id: "intro",
title: "Intro",
description: "Get started",
objective: "Collect basic info",
mode: "form",
lockItems: [{ id: "done", label: "Info collected", satisfied: false }],
initialInputs: [{ id: "name", label: "Name", type: "text" }],
agentInstructions: "Confirm the user's input and mark the stage complete.",
tools: {},
},
{
id: "chat",
title: "Discussion",
description: "Chat stage",
objective: "Discuss goals",
mode: "chat",
lockItems: [{ id: "goals", label: "Goals captured", satisfied: false }],
initialInputs: [],
agentInstructions: "Ask about goals and mark the lock when satisfied.",
tools: { askTextInput: true, askMultipleChoice: true },
},
]
export function MyLeveeFlow() {
return (
<Levee
config={stages}
allowRevisit
onComplete={(s) => console.log("Done", s)}
>
<LeveeRail>
<LeveeSidebarContent />
</LeveeRail>
<LeveeStageView>
<LeveeStageHeader />
<LeveeStageChat>
<LeveeConversation>{/* messages */}</LeveeConversation>
{/* PromptInput or custom input */}
</LeveeStageChat>
</LeveeStageView>
</Levee>
)
}
function LeveeSidebarContent() {
const { stages, activeStageIndex } = useLevee()
const active = stages[activeStageIndex]
if (!active) return null
return (
<>
<LeveeStageLockChecklist
items={active.lockItems}
percentage={active.lockPercentage}
/>
<LeveeStageCollectedData data={active.collectedData} />
</>
)
}For a full implementation (API route, tool views, form and synthesis stages), see the Levee brand strategy pro block.
Props
Levee
| Prop | Type | Default | Description |
|---|---|---|---|
config | LeveeStageConfig[] | required | Stage definitions. |
allowRevisit | boolean | false | Whether completed stages can be revisited. |
activeStageIndex | number | — | Controlled current stage index. |
defaultActiveStageIndex | number | 0 | Initial stage when uncontrolled. |
onActiveStageIndexChange | (index: number) => void | — | Called when the active stage changes. |
onComplete | (stages: LeveeStageState[]) => void | — | Called when all stages are locked. |
Also accepts div props (e.g. className).
LeveeRail
| Prop | Type | Default | Description |
|---|---|---|---|
compact | boolean | false | When true, narrow rail (icons only). |
Also accepts aside props. Children (e.g. lock checklist, collected data) render below the stage list when not compact.
LeveeStageLockChecklist
| Prop | Type | Description |
|---|---|---|
items | LeveeLockItem[] | Lock items and their satisfied state. |
percentage | number | 0–100 lock progress. |
LeveeStageCollectedData
| Prop | Type | Description |
|---|---|---|
data | Record<string, unknown> | Key-value data collected in the stage. |
Related
- AI Elements — Chat, message, and prompt components used with Levee.
- On the Design of Levee — Design context and why staged workflows.
- Levee brand strategy pro block — Full example with API, tool views, and multiple stage modes.
ai sdk patterns.