Skip to content

Repository files navigation

Remix banner

A Flutter component library combining Naked UI interaction and accessibility with Mix styling.

Agent skills

skills.sh

This repository publishes two skills from its skills/ catalog:

List the available skills without installing them:

npx skills add conceptadev/remix --list

Install both skills, or select one:

npx skills add conceptadev/remix
npx skills add conceptadev/remix --skill using-remix -y

Project installs create a local agent-skills directory such as .agents/. Contributors who do not want that directory in their checkout can install globally or use a skill ephemerally:

npx skills add conceptadev/remix --skill using-remix -g -y
npx skills use conceptadev/remix@using-remix

List installed skills and update them later:

npx skills ls
npx skills update

Vendored Mix skill

This repository commits the project-scoped Mix skill and its lockfile so Codex and Claude Code use the same reviewed instructions. Install or refresh the canonical copy and Claude symlink with:

npx skills add conceptadev/mix --skill mix --agent codex --agent claude-code -y

Update the committed installation from its locked project source with:

npx skills update mix --project -y

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

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
  • 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

Live examples:

  • Fortal dashboard — a polished product dashboard with responsive layouts, charts, data, and live theme controls.
  • Component catalog — the Widgetbook catalog for reviewing Remix and Fortal components, variants, and states.

Check out apps/dashboard, apps/demo, and the per-package examples in packages/remix/example and packages/remix_fortal/example for complete working examples demonstrating:

  • Component usage patterns
  • Style composition techniques
  • Design system implementation
  • Advanced customization

Built with ❤️ using Mix and Naked UI

About

A Flutter component library that combines headless UI behavior with Mix's powerful styling system, giving you complete freedom to build and customize components that match your design system perfectly.

Resources

Stars

18 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages