Optimization Sequencer
A stepped sequencer for applying optimization passes in a user-chosen order. Renders an ordered applied list (numbered, removable), an available pool of the rest, and a progress bar with a cumulative-savings readout. Controlled or uncontrolled — drop in { id, label, savings? } passes and use it anywhere "pick a series of changes and watch the running tally" helps.
Preview
Apply optimizations
Apply passes in any order — the cumulative savings sum on the right.
Applied0/4·0 KB
Applied
Pick an optimization below to start the sequence.
Available
Customize
Per-step savings (KB)
48KB
68KB
52KB
24KB
Options
Installation
npx shadcn@latest add https://craftbits.dev/r/optimization-sequencer.jsonUsage
import { OptimizationSequencer } from "@craft-bits/core";
<OptimizationSequencer
title="Apply optimizations"
steps={[
{ id: "route-split", label: "Route split", savings: 48 },
{ id: "tree-shake", label: "Tree shake", savings: 68 },
{ id: "dynamic-import", label: "Dynamic import", savings: 52 },
{ id: "vendor-chunk", label: "Vendor chunk", savings: 24 },
]}
savingsUnit="KB"
/>Controlled mode — drive appliedSteps from outside so the sequence can feed an external simulator:
const [applied, setApplied] = useState<string[]>([]);
<OptimizationSequencer
steps={STEPS}
appliedSteps={applied}
onAppliedStepsChange={setApplied}
/>Anatomy
- Header. Optional
title(renders with thecb-labelstyle) and adescriptionsub-line. Omit both for a chromeless panel. - Progress. A counter ("3 of 4") plus a cumulative-savings readout, with a thin progress bar showing the proportion of passes applied. The bar fills with the
SPRINGS.snaptoken. - Applied region. An ordered list of applied steps with a 1-based numbered accent pill, label, optional savings, and a remove button. A reset button in the region header clears the whole sequence.
- Available region. The rest of the steps as click-to-apply buttons. Hidden once every step is applied.
Understanding the component
- Apply order matters. The applied list preserves the order steps were picked — the sequencer is intended for lessons where order changes the outcome. Removing a step closes the gap; re-applying appends to the end.
- Controlled + uncontrolled. Provide
appliedStepswithonAppliedStepsChangeto drive from outside, ordefaultAppliedStepsfor the uncontrolled case. Omit both and the sequence starts empty. - Cumulative savings. Each step can declare an optional
savingsnumber. The readout sums savings across applied steps and renders with thesavingsUnitsuffix. Steps withoutsavingscontribute zero. - Motion. Applied items use Motion's
layoutso removing a step animates the rest into place; the progress bar fills with a spring. Every animation short-circuits underprefers-reduced-motion.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
steps | OptimizationSequencerStep[] | required | All passes a consumer can apply. |
appliedSteps | string[] | — | Controlled applied-step ids, in apply order. |
defaultAppliedSteps | string[] | [] | Initial applied steps in uncontrolled mode. |
onAppliedStepsChange | (next) => void | — | Fires on apply / remove / reset. |
title | ReactNode | — | Optional heading above the panel. |
description | ReactNode | — | Optional sub-headline under the title. |
headingAs | 'h2' | 'h3' | 'h4' | 'h3' | Tag for the title element. |
savingsUnit | string | 'KB' | Suffix on the savings readout. |
hideSavings | boolean | false | Hide the cumulative-savings readout. |
hideProgress | boolean | false | Hide the progress bar. |
appliedLabel | ReactNode | 'Applied' | Header for the applied region. |
availableLabel | ReactNode | 'Available' | Header for the pool region. |
resetLabel | ReactNode | 'reset' | Label on the reset button. |
hideReset | boolean | false | Hide the reset button. |
emptyMessage | ReactNode | sensible default | Shown when no steps are applied. |
formatSavings | (value, unit) => string | sensible default | Custom formatter for the readout. |
className | string | — | Merged onto the root via cn(). |
OptimizationSequencerStep
| Field | Type | Description |
|---|---|---|
id | string | Stable identifier. |
label | ReactNode | Visible name on both rails. |
description | ReactNode | Optional one-line sub-label. |
savings | number | Optional savings contribution summed into the cumulative readout. |
Accessibility
- The wrapper is a
<section>withdata-cb-edu="optimization-sequencer"anddata-cb-empty="true | false". - The progress bar is
role="progressbar"witharia-valuenow/aria-valuemin/aria-valuemax. - The applied list is an
<ol role="list">witharia-live="polite"; each entry exposesdata-cb-applied-id. - Apply / remove buttons carry verbose
aria-labels likeApply Tree shakeandRemove Tree shakeso the action is conveyed without depending on icons or position. - The reset button is disabled when nothing is applied and labels itself
Reset applied steps. - Animations are limited to opacity, transform, and width and short-circuit under
prefers-reduced-motion.
Credits
- Extracted from:
terminal-dreams(src/components/frontend-design/perf-bundle/ui/OptimizationSequencer.tsx). The original was bound to a fixed four-keyOptimizationKeyunion, a globalOPT_STEPSregistry from a bundle simulator, and Framer Motion'sReordergroup for drag-to-reorder. This rewrite drops the global registry and the reorder gesture (apply order is the order steps are picked), generalises the data shape, adds controlled / uncontrolled support, surfaces a progress bar plus cumulative savings readout, and replaces the project's CSS module with token-driven Tailwind.