Ousi UI for Flutter
35+ beautiful, production-ready Flutter components with smooth micro-interactions.
Built with OKLCH colors, full dark mode, and a native feel.
Features
- 35+ components — buttons, forms, overlays, charts, data display, navigation, and feedback
- OKLCH-inspired color system — perceptually uniform colors that look great in light and dark mode
- Dual radius system — separate
radius(general) andfieldRadius(form inputs) for fine-tuned design control - Full dark mode — every component adapts automatically via
ThemeExtension - Micro-interactions — haptic feedback, smooth transitions, and polished animations throughout
- Chart engine — line, multi-series, and candlestick charts with spline interpolation and time windows
- Toast system — stacking toasts with swipe dismiss, promise API, and rich content support
- Zero dependencies beyond Flutter SDK,
flutter_hooks, andequatable
Installation
dependencies:
ousi_ui: ^0.1.0
import 'package:ousi_ui/ousi_ui.dart';
Quick Start
Wrap your MaterialApp with the Ousi theme extension:
MaterialApp(
theme: ThemeData(
extensions: [OusiThemeData.light()],
fontFamily: OusiTypography.fontSans,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
extensions: [OusiThemeData.dark()],
fontFamily: OusiTypography.fontSans,
),
);
Custom accent color and radius
OusiThemeData.light(
accentColor: Color(0xFF8B5CF6), // Purple accent
radius: OusiRadii.lg, // Larger corners
)
Using ColorScheme with Ousi
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
extensions: [OusiThemeData.light(accentColor: Colors.blue)],
fontFamily: OusiTypography.fontSans,
),
Toast overlay
Add OToastOverlay to your widget tree (typically in your app's builder):
MaterialApp(
builder: (context, child) => Stack(
children: [
child!,
const OToastOverlay(),
],
),
);
Components
Buttons
| Component | Description |
|---|---|
OButton |
Primary button with solid, bordered, light, flat, ghost, and gradient variants. Supports sizes, loading state, icon-only mode. |
OLinkButton |
Inline text link with optional underline and icon. |
Forms
| Component | Description |
|---|---|
OTextField |
Text input with primary/secondary variants, label, description, error state, prefix/suffix icons. |
OSearchField |
Collapsible search with mitosis animation, thinking glow, debounce, and roll text placeholders. |
OSelect |
Dropdown with 3 presentations: popover, bottom sheet, and searchable dialog. |
OSwitch |
Toggle switch with smooth thumb animation and icon support. |
OCheckbox |
Checkbox with check/indeterminate states, rounded corners. |
ORadio |
Radio button group with label support. |
OSlider |
Range slider with step marks, value labels, and custom formatting. |
OInputOTP |
One-time password input with per-digit cells and flip animation. |
OTagGroup |
Tag/chip group with add/remove, single/multi select. |
OColorPicker |
HSL color picker with hue/saturation/lightness sliders, hex input, and presets. |
ODatePicker |
Calendar date picker presented in a bottom sheet. |
OTimePicker |
Scroll-wheel time picker with hour/minute/AM-PM and scroll shadows. |
Data Display
| Component | Description |
|---|---|
OAvatar |
Circular avatar with image, initials fallback, and size variants. |
OBadge |
Small status indicator with color variants and positioning. |
OSeparator |
Horizontal/vertical divider with optional label. |
OSpinner |
Loading spinner with multiple styles and sizes. |
OAccordion |
Expandable/collapsible content panels with smooth animation. |
OAnimatedNumber |
Animated number display with roll (odometer), count, slide, fade, and flip modes. |
OCalendar |
Full calendar view with day/week navigation, event dots, and range selection. |
Navigation
| Component | Description |
|---|---|
OTabs |
Tabbed navigation with animated indicator, scrollable overflow, and badge support. |
OBottomNav |
Floating bottom navigation bar with expandable sub-tabs panel that slides up behind the main bar. |
OAdaptiveSidebar |
Adaptive navigation that renders as a sidebar on wide screens and morphs into a floating top bar (pill) on narrow screens. Includes toggle button and customizable item display modes. |
Overlays
| Component | Description |
|---|---|
OBottomSheet |
Bottom sheet with snap points, detached mode, blur/opaque overlays, and keyboard avoidance. |
OModal |
Modal dialog with customizable content and overlay styles. |
OPopover |
Floating popover anchored to a trigger with auto-placement. |
OTooltip |
Tooltip with plain, arrow, and bubble (thought bubble) styles. |
OToast |
Stacking toast notifications with swipe dismiss and promise API. |
OMenu |
Context menu with sections, icons, destructive items, and nested submenus. |
Feedback
| Component | Description |
|---|---|
OAlert |
Alert banner with info, success, warning, and danger variants. |
OProgressBar |
Determinate/indeterminate progress bar with label and striped animation. |
OSkeleton |
Content placeholder with shimmer animation. |
Primitives
| Component | Description |
|---|---|
OCard |
Surface container with shadow, border, and padding options. |
OScrollShadow |
Adds fade shadows to scrollable content edges. |
Charts
| Component | Description |
|---|---|
OChart |
Full-featured chart with line, multi-series, and candlestick modes. Supports spline interpolation, time windows, value overlays, empty states, and theming. |
Chart Usage
OChart(
controller: OChartController(
data: [
OChartPoint(label: 'Jan', value: 120),
OChartPoint(label: 'Feb', value: 340),
OChartPoint(label: 'Mar', value: 220),
],
),
)
Multi-series
OChart(
controller: OChartController(
series: [
OChartSeries(name: 'Revenue', color: Colors.blue, data: [...]),
OChartSeries(name: 'Expenses', color: Colors.red, data: [...]),
],
),
)
Candlestick
OChart(
controller: OChartController(
candleData: [
OCandlePoint(label: 'Mon', open: 100, high: 120, low: 95, close: 115),
],
),
)
Toast API
// Simple toast
OToastManager.show('File saved');
// With variant
OToastManager.show('Error occurred', variant: OToastVariant.danger);
// Promise-based (loading → success/error)
OToastManager.promise(
fetchData(),
loading: 'Loading...',
success: (data) => 'Loaded ${data.length} items',
error: (e) => 'Failed: $e',
);
Bottom Navigation
OBottomNav(
items: [
OBottomNavItem(
icon: Icons.explore_outlined,
label: 'Explore',
selectedIcon: Icons.explore_rounded,
subTabs: ['Rooms', 'Inspiration', 'Profiles'],
),
OBottomNavItem(
icon: Icons.settings_outlined,
label: 'Settings',
selectedIcon: Icons.settings_rounded,
),
],
selectedIndex: _tabIndex,
onItemSelected: (i) => setState(() => _tabIndex = i),
selectedSubIndex: _subIndex,
onSubTabSelected: (i) => setState(() => _subIndex = i),
)
Adaptive Sidebar
OAdaptiveSidebar(
items: [
OAdaptiveSidebarItem(icon: Icons.home_rounded, label: 'Home'),
OAdaptiveSidebarItem(icon: Icons.inbox_outlined, label: 'Inbox'),
OAdaptiveSidebarItem(
icon: Icons.auto_awesome_outlined,
label: 'AI',
topBarDisplay: OTopBarDisplay.icon, // Icon-only in top bar mode
),
],
selectedIndex: _selected,
onItemSelected: (i) => setState(() => _selected = i),
breakpoint: 800, // Auto-switch at this width
sidebarHeader: Text('My App'),
topBarActions: [IconButton(icon: Icon(Icons.add), onPressed: () {})],
body: YourContentWidget(),
)
Design Tokens
Colors
Access the OKLCH-inspired palette via OusiColors:
OusiColors.blue[500] // Primary blue
OusiColors.zinc[100] // Light gray
OusiColors.rose[600] // Danger red
Typography
Font sizes follow the Tailwind scale:
OusiTypography.xs // 12
OusiTypography.sm // 14
OusiTypography.md // 16
OusiTypography.lg // 18
OusiTypography.xl // 20
Radii
OusiRadii.sm // 8
OusiRadii.md // 12 (default)
OusiRadii.lg // 16
OusiRadii.xl // 20
OusiRadii.full // 9999
Accessing theme in widgets
final theme = context.ousiTheme;
Container(
color: theme.accentColor,
child: Text('Hello', style: TextStyle(color: theme.foregroundColor)),
)
Example App
The example/ directory contains a full showcase app with demos for every component.
cd example
flutter run
Contributing
Contributions are welcome! Please open an issue or pull request on GitHub.
License
MIT © Carlos Aroca