beUI
Motion components for Flutter — a one-to-one port of beUI v2 (starc007/ui-components).
Spring-physics UI primitives and composed blocks, built on the motor motion engine so the original's exact spring feel carries over — not just its look.
What this is
beUI is a Flutter widget library that ports the beUI React motion library. It covers all 72 catalog entries across the source's three groups — expressive Components (motion primitives with composable APIs), product-ready Blocks (composed patterns like a command palette, wallet card, or availability scheduler), and AI Agents (conversational and agent-reasoning surfaces).
The port's defining goal is motion fidelity. Framer Motion springs are parameterized by stiffness, damping, and mass — the exact same physical parameters as Flutter's SpringDescription — so the source's spring tokens carry over with no fidelity loss. Components don't approximate the feel with Curves.elasticOut; they use the real physics through motor.
- 🎬 Spring-accurate motion — five spring tokens + three easings ported verbatim from the source's
ease.ts. - 🎨 Themeable —
BeuiColorsfor palette,BeuiAgentThemefor AI-agent typography/shape/layout/icons, andThemeData.fontFamilyfor the typeface. - ♿ Reduced-motion aware — one resolver drops movement while keeping opacity/color feedback (not a blanket duration-zeroing).
- 🧩 Native APIs — controlled/uncontrolled
value+onChangedpairs, framework-nativeIconData/Widgeticon props, variants as Dart enums. - 🪟 One overlay foundation — every floating surface (tooltip, drawer, sheet, modal, command palette) builds on a shared
BeuiOverlay.
Status: actively developed. All 72 beui.dev catalog entries are ported. 1.2.0 remediates the chat/agent UX audit — honest failure states, keyboard and screen-reader contracts, AA contrast, composer attachments — and adds
BeuiColors.focusRingplus localizableBeuiAgentStrings.
What's new in 1.2.0
![]() Chat App — composed workspace with a responsive sidebar |
![]() Tool Approval — details open by default, destructive severity tier |
![]() Prompt Input — attachment chips and a keyboarded model picker |
![]() Streaming Response — failed and stopped are no longer silent |
Live gallery
The example/ app is a beui.dev-style component explorer — sidebar, card grid, per-component detail pages with live Preview / Usage / Code tabs, and a Motion Guides page. It's deployed to GitHub Pages on every push to main:
👉 codenameakshay.github.io/beui
![]() Blocks — composed, product-ready motion patterns |
![]() AI Agents — conversational and agent-reasoning surfaces |
![]() Detail page — live Preview / Usage / Code tabs |
![]() Motion Guides — when to move, which token, how to fall back |
![]() Light & dark — every screen renders in both |
![]() Compact — sidebar collapses below 1000px |
Install
dependencies:
beui: ^1.2.0
Or from Git:
dependencies:
beui:
git:
url: https://github.com/codenameakshay/beui.git
Then import the single public entrypoint:
import 'package:beui/beui.dart';
Quick start
1. Register the theme
Components read their colors from a BeuiColors ThemeExtension, so install it on your ThemeData. Color theme and brightness are independent axes — any of the 11 themes works in light or dark.
import 'package:beui/beui.dart';
import 'package:flutter/material.dart';
ThemeData beuiTheme(Brightness brightness) {
final colors = BeuiColors.of(BeuiColorTheme.violet, brightness);
final base = ThemeData(brightness: brightness, useMaterial3: true);
return BeuiTextTheme.trackingNormal(
base.copyWith(
scaffoldBackgroundColor: colors.background,
extensions: [
colors,
const BeuiAgentTheme(), // optional — omit to keep source-fidelity agent styling
],
),
);
}
MaterialApp(
theme: beuiTheme(Brightness.light),
darkTheme: beuiTheme(Brightness.dark),
home: const MyHomePage(),
);
2. Drop in a component
Every stateful component mirrors Flutter's controlled + uncontrolled convention — pass value + onChanged to control it, or omit value to let it hold its own state.
// A spring-thumbed switch
bool wifi = true;
BeuiSwitch(
value: wifi,
label: const Text('Wi-Fi'),
onChanged: (v) => setState(() => wifi = v),
);
// Tabs with a gliding indicator — pill / segment / underline
BeuiTabs<String>(
variant: BeuiTabsVariant.underline,
tabs: const [
BeuiTab(value: 'overview', label: Text('Overview')),
BeuiTab(value: 'activity', label: Text('Activity')),
],
defaultValue: 'overview',
onChanged: (v) => print(v),
);
// A spring-pressed button
BeuiButton(
variant: BeuiButtonVariant.primary,
onPressed: () {},
child: const Text('Continue'),
);
// A hover/focus tooltip with a blur enter/exit
BeuiTooltip(
content: const Text('Copy to clipboard'),
side: BeuiTooltipSide.top,
child: const Icon(LucideIcons.copy),
);
// A GPU shader background (mesh, grain, warp, waves, voronoi…)
BeuiShaderBackground(
variant: BeuiShaderVariant.meshGradient,
speed: 0.6,
);
Component catalog
Mirrors the beui.dev sidebar order. ✨ marks entries added in beUI v2.
Components — motion primitives
| Component | Widget(s) | What it does |
|---|---|---|
| Marquee | BeuiMarquee |
Infinite horizontal/vertical scroll with pause-on-hover |
| Tabs | BeuiTabs |
Pill, segment or underline tabs with a spring layout indicator |
| Switch | BeuiSwitch |
Toggle with a spring-driven thumb and press feedback |
| Input | BeuiInput |
Text field with icons, left-aligned announced errors, error-shake replay and a success check draw |
| Select ✨ | BeuiSelect, BeuiMorphSelect |
Panel that bouncily unfolds from the trigger, plus a Morph variant |
| Checkbox ✨ | BeuiCheckbox |
Draw-on checkmark with spring press feedback and indeterminate |
| Radio Group ✨ | BeuiRadioGroup |
Single-select with a gliding indicator dot and spring feedback |
| Bottom Sheet | BeuiBottomSheet |
Draggable sheet with snap points, inertia and a glass surface |
| Pull to Refresh ✨ | BeuiPullToRefresh |
Pull-to-refresh with drag resistance and async handling |
| Shared Layout Background | BeuiSharedLayoutBg |
A pill that glides between hovered items with a blur enter/exit |
| Bounce Sidebar ✨ | BeuiBounceSidebar |
Vertical rail whose active dot jumps between destinations on a curved path |
| Animated Sidebar ✨ | BeuiAnimatedSidebar |
App sidebar that folds to an icon rail, in sidebar, floating or inset chrome |
| Preview Rail ✨ | BeuiPreviewRail |
Navigation rail of ticks that reveal a destination preview — hover on pointer, tap-to-preview on touch |
| Dock | BeuiDock |
macOS-style dock with separator-grouped actions and a gliding active pill |
| Tooltip | BeuiTooltip |
Hover or focus tooltip with a blur enter/exit and spring spawn |
| Context Menu ✨ | BeuiContextMenu |
Pointer-origin clip morph with checkbox/radio rows, keyboard nav and typeahead |
| Popover ✨ | BeuiPopover, BeuiMorphPopover |
Gooey popover that oozes from the trigger, plus a Morph variant |
| Morphing Modal | BeuiMorphingModal |
A panel that morphs its height between inner views, blur cross-fade |
| Center Morph Modal ✨ | BeuiCenterMorphModal |
A surface that unfolds from its exact center toward every edge |
| Text Animation | BeuiTextReveal, BeuiTextShimmer, BeuiTextCascade, BeuiChromaticTextReveal |
Reveal sequences, shimmer loading states, letter-cascade swaps and a chromatic sweep over cycling words |
| Number Animation | BeuiAnimatedNumber, BeuiNumberTicker |
Count-up values and rolling digit tickers |
| Animated Badge | BeuiAnimatedBadge |
Status badge with animated state icons and pulse feedback |
| Action Swap | BeuiActionSwapButton |
Swap a button's text and icons with blur, roll or cascade motion |
| Animated Toast Stack | BeuiAnimatedToastStack |
Stacked toasts with status morphs, swipe dismissal and actions |
| Theme Toggle | BeuiThemeToggle, BeuiThemeSwitcher |
Theme toggle with a full-page clip-path reveal |
| Bouncy Accordion | BeuiBouncyAccordion |
Single-open accordion with a weighted spring layout |
| Drawer | BeuiDrawer |
Side panel that springs in with a backdrop blur and esc-to-close |
| Scroll Animation | BeuiSmoothScroll, BeuiScrollProgress, BeuiScrollReveal, BeuiScrollTo, BeuiParallax |
Smooth-scroll provider (vertical or horizontal), reading-progress indicator, reveal, scroll-to and parallax |
| Range Slider ✨ | BeuiRangeSlider, BeuiFluidSlider, BeuiWaveSlider, BeuiBubbleSlider, BeuiRulerSlider |
Five sliders: ticked bar thumb, thumbless liquid fill, equalizer wave, velocity-leaning bubble, and a scale that scrolls under a fixed needle |
| Wheel Picker ✨ | BeuiWheelPicker |
iOS-style 3D picker drum with momentum snap |
| Table ✨ | BeuiTable |
Virtualized table smooth at 10k+ rows: sort, select, resize, reorder |
| Shader Background ✨ | BeuiShaderBackground |
21 GPU shader backgrounds (mesh, grain, warp, waves, voronoi…) |
| Cylinder Carousel ✨ | BeuiCylinderCarousel |
Items line the inside of a cylinder; drag or scroll with springy snap |
| Loader ✨ | BeuiLoader |
Loading indicator with seventeen variants from one size prop |
| Tilt Card | BeuiTiltCard |
3D perspective tilt on hover with a cursor-tracked glare |
| Button | BeuiButton, BeuiStatefulButton, BeuiMagneticButton |
Spring-pressed Button, StatefulButton and MagneticButton |
| Animated CTA Buttons ✨ | BeuiExpandingArrowButton, BeuiHoldActionButton, BeuiSlideActionButton |
CTA buttons with expanding, hold-to-confirm and slide-to-confirm interactions |
Blocks — composed patterns
| Block | Widget | What it does |
|---|---|---|
| Availability Scheduler ✨ | BeuiAvailabilityScheduler |
Weekly availability grid with per-day time ranges |
| Multi-chain Swap | BeuiMultiChainSwap |
Token swap card with chain switching and an animated quote |
| Dynamic Island | BeuiDynamicIsland |
iOS-style island that morphs between compact and expanded views |
| Command Palette | BeuiCommandPalette |
⌘K palette with fuzzy search and spring-animated results |
| Expandable Action Bar | BeuiExpandableActionBar |
Icon rail whose segments expand to reveal a label on hover |
| Overflow Actions | BeuiOverflowActions |
Primary actions with an overflow that fans out from a ⋯ toggle |
| Expandable Tabs | BeuiExpandableTabs |
Icon tabs where the active tab expands to show its label |
| Swipeable List | BeuiSwipeableList |
List rows with spring-backed swipe-to-reveal actions |
| File Upload | BeuiFileUpload |
Drop zone with real progress, cancel-in-flight, size limits and inline rejection |
| Attachment Upload | BeuiAttachmentUpload |
Mixed attachment workspace — image previews, seekable audio, retry and cancel |
| Prediction Market | BeuiPredictionMarket |
Market card with a gliding outcome pill and animated odds |
| Wallet Card ✨ | BeuiWalletCard |
Wallet card with an account switcher and morphing search |
| OTP Input | BeuiOtpInput |
One-time-code field with per-cell focus and a success check |
| Bloom Menu ✨ | BeuiBloomMenu |
Radial action menu that blooms open from a floating trigger |
| Feedback Widget ✨ | BeuiFeedbackWidget |
Feedback popover that keeps drafts, validates inline and morphs to a success state |
| 404 / Not Found | BeuiNotFoundGlitch, …Magnetic, …Spotlight, …Stacked, …Terminal |
Five expressive 404 treatments |
| Infinite Masonry ✨ | BeuiInfiniteMasonry |
Masonry grid that lazily appends tiles as you scroll |
| Notification Stack ✨ | BeuiNotificationStack |
Collapsed notification stack that expands with layout-aware motion |
| Knockout Bracket ✨ | BeuiKnockoutBracket, BeuiKnockoutWheel |
Tournament fixtures in two styles: a paging bracket with a third-place playoff, and a wheel wrapping the same tree around the champion |
AI Agents — conversational and agent-reasoning interfaces
| Component | Widget(s) | What it does |
|---|---|---|
| Message Bubble | BeuiMessageBubble |
Conversational surface with tones, alignment, grouping and expandable content |
| Message | BeuiMessage |
Primitives for rows, avatars, metadata, live markers and a mount-only pop-up |
| Message Scroller | BeuiMessageScroller |
Viewport that follows streamed output, releases when the reader scrolls away, and offers a jump-to-latest pill |
| Prompt Input | BeuiPromptInput |
Auto-growing composer with attachment chips, a keyboarded model picker and animated send/stop |
| Todo List | BeuiTodoList |
Collapsible task plan with morphing status marks and a completion count |
| Code Block | BeuiCodeBlock |
Highlighted code that stays stable while streaming, with copy feedback |
| Approval Card | BeuiApprovalCard |
Human-in-the-loop surface for approvals, questions, and compact-to-expanded proposals |
| File Diff | BeuiFileDiff |
Change disclosure with wrap or horizontal scroll, hunk-gap markers and live counts |
| Tool Result | BeuiToolResult |
Execution disclosure for terminal or request output that collapses when done |
| Streaming Response | BeuiStreamingResponse |
Response surface with completion actions, a visible failed state and a stopped/continue path |
| Image Generation | BeuiImageGeneration |
Queued → refining → complete image surface with determinate progress and cancel |
| Tool Approval | BeuiToolApproval |
Permission card: allow once, remember access, or deny — with a destructive severity tier |
| Citations | BeuiCitations |
Inline markers plus a collapsible, progressively rendered reference list |
| Agent Activity | BeuiAgentActivity |
One adaptive stream for reasoning, searches, tool calls and traces — including failed and cancelled runs |
| Agent Loading States | BeuiThinkingShimmer, BeuiAgentProgress, BeuiReasoningText |
Shimmering status text, live progress and cycling reasoning phrases |
| AI Sidebar | BeuiAiSidebar |
Workspace sidebar for folders, projects, files and bookmarks with inline rename |
| Chat App | BeuiChatApp |
A complete conversation workspace composing the widgets above, with a responsive sidebar |
| Agent Theme | — | Gallery route that installs a custom BeuiAgentTheme on the real widgets |
Also exported as standalone primitives: BeuiMagnetic (cursor-follow pull) and the BeuiOverlay foundation.
Theming
Three layers, installed once on ThemeData. Ordinary widgets then pick the values up — no per-component style wrappers.
| Layer | Owns | Install |
|---|---|---|
ThemeData.fontFamily / BeuiTextTheme |
Global sans/mono family names and Material letter-spacing normalisation. The package ships no font files. | ThemeData(fontFamily: 'General Sans') plus BeuiTextTheme.trackingNormal(...) |
BeuiColors |
Palette: core tokens, brand themes, BeuiGlass, and focusRing (WCAG 2.2 3:1 non-text contrast). Not typography, radii, or spacing. |
extensions: [BeuiColors.of(theme, brightness)] |
BeuiAgentTheme |
AI-agent semantics: type roles, bubble/card radii, conversation spacing, density, borders, optional glass cards, default icons, status palettes, and localizable BeuiAgentStrings. |
extensions: [BeuiAgentTheme(...)] — omit it and widgets use source-fidelity defaults identical to 1.0.0 |
ThemeData(
fontFamily: 'General Sans',
extensions: [
BeuiColors.of(BeuiColorTheme.green, Brightness.light).copyWith(
primary: Color(0xFF3D6B2F),
),
BeuiAgentTheme(
shapes: BeuiAgentShapes(
userBubble: BorderRadius.circular(20),
assistantBubble: BorderRadius.circular(12),
card: BorderRadius.circular(18),
),
layout: BeuiAgentLayout(
density: BeuiAgentDensity.compact,
turnSpacing: 12,
bubblePadding: EdgeInsets.fromLTRB(12, 8, 12, 8),
),
icons: BeuiAgentIcons(edit: Icons.edit_outlined),
),
],
);
BeuiMessageBubble(...);
BeuiApprovalCard(
expandedChild: ..., // compact-to-expanded; omit to keep the 1.0.0 API
);
BeuiToolResult(...);
BeuiColors is a ThemeExtension ported from the source's design tokens. Read colors in your own widgets the same way components do:
final colors = Theme.of(context).extension<BeuiColors>()!;
Container(color: colors.card /* colors.foreground, .primary, .border, .muted, … */);
11 color themes, each valid in light and dark — resolve with BeuiColors.of(theme, brightness):
Mono (neutral base) · Violet · Blue · Green · Amber · Blood Orange · Rose · Red · Teal · Indigo · Lime
Each BeuiColorTheme value carries picker metadata (name, slug, swatch) for building a theme switcher. Overlay surfaces use a dedicated frosted-glass tier (BeuiGlass) with the source's 12–20px backdrop blur.
Agent widgets that previously hard-coded text-sm / rounded-2xl / Lucide defaults now resolve those from BeuiAgentTheme.of(context), which falls back to the same numbers and glyphs when the extension is missing. See the Agent Theme gallery route for a live custom palette, radii, density, icons, and an expandable approval card:

1.2.0 adds two theme roles the audit needed: BeuiColors.focusRing (a 3:1 focus halo that paints outside layout, separate from the ring hairline) and BeuiAgentTheme.strings / statusLight / statusDark so agent copy and status color can be rethemed or localized without forking a widget.
Motion system
The whole library speaks one motion language, defined once in lib/src/tokens/motion.dart and exported through the barrel:
| Token | Physics | Used for |
|---|---|---|
beuiSpringPress |
stiffness 500 · damping 30 · mass 0.6 | Button / tap press feedback |
beuiSpringSwap |
stiffness 460 · damping 30 · mass 0.55 | Content swaps (label/icon slots) |
beuiSpringPanel |
stiffness 420 · damping 40 · mass 0.5 | Overlay panel entrances (modals, sheets) |
beuiSpringLayout |
stiffness 360 · damping 32 · mass 0.6 | Shared-layout glides (pills, indicators) |
beuiSpringMouse |
stiffness 200 · damping 15 · mass 0.3 | Cursor-follow physics (magnetic, tilt) |
Plus three easings — beuiEaseOut, beuiEaseInOut, beuiEaseDrawer — and helpers beuiBlurSigma(px) (CSS-blur → Flutter sigma) and motionFor(context, token, isMovement:) (the reduced-motion resolver).
Reduced motion is respected everywhere: with the OS setting on, movement-bearing tokens collapse to movement-free motion while opacity/color transitions are preserved — motion that explains rather than distracts. See the Motion Guides page in the live gallery.
Icons
beUI re-exports the flutter_lucide icon set (the Flutter equivalent of the source's lucide-react glyphs), so defaults in badges, toasts, and the command palette work out of the box — LucideIcons.* is available from the barrel.
Transitive dependency: adding
beuipulls in the Lucide icon font whether or not you use a defaulted icon. Icon props accept the framework-nativeIconData(any glyph) orWidget(custom content), so you can override every default without depending on Lucide directly.
Develop
Uses FVM (pinned to Flutter stable in .fvmrc).
fvm flutter pub get
fvm flutter analyze # static analysis + lints
fvm flutter test # widget + golden tests
fvm flutter test --update-goldens # regenerate goldens after intentional visual changes
cd example && fvm flutter run # the component explorer
Run fvm flutter analyze && fvm flutter test before considering work done. See CLAUDE.md for architecture and conventions, and docs/PORTING_SPEC.md for the full catalog and the motion-token mapping.
Credits
A Flutter port of beUI by Saurabh Chauhan — beui.dev (starc007/ui-components). All component designs and the original motion work are his; this package brings them to Flutter.
License
MIT — see LICENSE. Both the upstream copyright (Saurabh Chauhan) and the port's copyright are preserved, as the MIT license requires for derivative works.
Libraries
- beui
- beUI — a one-to-one Flutter port of beUI v2 motion components.









