remix 1.0.0-beta.10
remix: ^1.0.0-beta.10 copied to clipboard
Remix is a modern, expressive design system built on top of Naked and Mix.
A Flutter component library combining Naked UI interaction and accessibility with Mix styling.
Styling a button #
final style = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.animate(AnimationConfig.spring(300.ms))
.onHovered(.color(Colors.blue.shade700));
RemixButton(
onPressed: () {},
label: 'Click me',
style: style,
);
Or using callable styles:
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.onHovered(.color(Colors.blue.shade700))
.animate(AnimationConfig.spring(300.ms));
button(
label: 'Click me',
onPressed: () {},
); // return RemixButton Widget.
Quick Start #
Installation #
Add Remix to your project:
flutter pub add remix:^1.0.0-beta.9
Or add it to your pubspec.yaml:
dependencies:
remix: ^1.0.0-beta.9
Your First Component #
A button with hover styling and animation:
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';
class MyApp extends StatelessWidget {
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.label(TextStyler().color(Colors.white));
@override
Widget build(BuildContext context) {
return WidgetsApp(
color: Colors.blue,
builder: (_, _) => Center(
child: button(
label: 'Click Me',
onPressed: () => debugPrint('Button pressed!'),
),
),
);
}
}
Adding Interaction States #
Easily define how components should look in different interaction states.
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.label(TextStyler().color(Colors.white))
.onHovered(.color(Colors.blue.shade700))
.onPressed(.scale(0.95));
Adding Animation #
Make your button style smoothly animate when its state changes by chaining .animate() with your state-specific styles. You can use AnimationConfig.spring to get natural, spring-based motion.
final style = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.animate(AnimationConfig.spring(300.ms))
.onHovered(.color(Colors.blue.shade700))
.onPressed(.scale(0.95));
This example animates both the color on hover and the scale on press, creating a smooth interactive experience for your users.
See the Mix repository for keyframe and phase animation APIs.
Style Composition and Reuse #
Create base styles and extend them to build variants:
final baseButtonStyle = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.borderRadius(.all(const Radius.circular(8)));
final primaryButton = baseButtonStyle
.color(Colors.blue)
.label(TextStyler().color(Colors.white));
final destructiveButton = baseButtonStyle
.color(Colors.red)
.label(TextStyler().color(Colors.white));
Theming with Fortal #
Remix ships no theme of its own. If you want a polished, Radix Themes-inspired starting point instead of authoring every style yourself, initialize the application-owned Fortal preset:
flutter pub add dev:remix_cli
dart run remix_cli:remix init --prefix Fortal --preset fortal
dart run remix_cli:remix add button
It copies FortalScope, the token system, fortal*Style() recipes, and the
components you add into your application.
See the Fortal documentation to get started.
Host Capabilities #
Remix composes inside your existing Flutter host. It does not require a
MaterialApp, Scaffold, or Remix-owned application wrapper.
| UI | Caller provides | Compatible hosts |
|---|---|---|
Ordinary Remix* widgets |
The inherited Flutter services used by the widget subtree | Material, Cupertino, Widgets, and router-based hosts |
| Widgets styled by the Fortal preset | The preset's token scope, in addition to the widget's normal Flutter services | Any Flutter host |
| Menu, select, popover, and tooltip | An Overlay |
Any host exposing an overlay; use Overlay.wrap when no Navigator is needed |
showRemixDialog and showRemixAlertDialog |
A Navigator |
Any host with a caller-owned navigator |
For a portal-based interface without routing, provide only an overlay:
import 'package:flutter/widgets.dart';
import 'package:remix/remix.dart';
Widget buildPortalHost() {
return WidgetsApp(
color: const Color(0xFFFFFFFF),
builder: (_, _) => Overlay.wrap(
child: Center(
child: RemixMenu<String>(
trigger: const RemixMenuTrigger(label: 'Actions'),
items: const [
RemixMenuItem(value: 'share', label: 'Share'),
],
),
),
),
);
}
A MaterialApp, CupertinoApp, WidgetsApp, or router with routing configured
commonly provides a Navigator and its overlay already. Dialog helpers push
routes, so their calling context must be below that caller-owned Navigator.
Components #
Available components:
Interactive Elements #
- Button - Clickable actions with full styling control
- IconButton - Icon-based actions
- Switch - Toggle controls
- Toggle - Two-state on/off buttons
- Checkbox - Multiple selection
- CheckboxGroup - Coordinated multiple selection with composable checkbox visuals
- Radio - Single selection from a group
- Slider - Continuous value selection
Input Components #
- TextField - Text input with validation support
- TextArea - Multiline text input with safe auto-growing defaults
- Select - Dropdown selection with keyboard navigation
Display Components #
- Avatar - User avatars and images
- Badge - Status indicators and labels
- Card - Content containers
- DataList - Label/value metadata lists with a shared label column
- DataTable - Controlled tables with shared column headers, sorting, selection, and pagination
- Divider - Visual separators
- Progress - Progress indicators
- Skeleton - Loading placeholders that mirror their content
- Spinner - Loading states
Layout & Navigation #
- Tabs - Tabbed navigation
- Accordion - Collapsible content sections
- Disclosure - A standalone trigger and inline expandable panel
- Link - Styled text that navigates, with the Link role and Enter activation
- Menu - Context menus and dropdowns
- SegmentedControl - Equal-segment controlled single selection
Overlays #
- Dialog - Modal dialogs
- Tooltip - Contextual help
- Callout - Highlighted information blocks
Who is Remix for? #
Remix is ideal for:
- Teams building custom design systems who need full control over component appearance
- Developers requiring complex state management with multiple variants and interaction states
- Applications needing consistent styling across dozens of components
Examples #
Check out apps/dashboard, apps/demo, and the per-package examples in
packages/remix/example and registry_source/example for complete working examples demonstrating:
- Component usage patterns
- Style composition techniques
- Design system implementation
- Advanced customization