RemixRemix

Styler API

Factory constructors, fluent methods, contextual shorthand, and Remix styler conventions

Remix stylers expose matching named factories and fluent methods for canonical style operations. This symmetry lets a state variant use Dart's contextual dot shorthand without constructing another styler explicitly:

Styler and spec names are unprefixed: use ButtonStyler, CardStyler, MenuStyler, and so on. Deprecated RemixXStyler aliases and RemixXSpec typedefs are available for source compatibility. Widgets and data classes use the Remix prefix (RemixButton, RemixMenu, RemixMenuItem).

import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

final style = ButtonStyler()
    .color(Colors.blue)
    .onHovered(.color(Colors.indigo))
    .onPressed(.scale(0.97));

The following expressions are equivalent:

import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

final shorthand = CardStyler.color(Colors.blue);
final fluent = CardStyler().color(Colors.blue);

Factory policy

API shapePolicy
Canonical style operationExpose both a named factory and a matching fluent method.
Direct child styler fieldExpose a field factory such as MenuStyler.trigger(...).
Primary nested containerForward one compatible canonical surface from the nested styler.
Alias of a canonical operationDo not add one. A canonical operation has exactly one spelling.
Slot-forwarding convenience (titleColor, labelFontSize)Keep it fluent-only. It names a child slot rather than duplicating a canonical operation.
Styler lifecycle or composition (animate, variants, wrap, modifier, merge)Keep it fluent-only because it configures or combines an existing parent styler.
Generic variant helperKeep it as an extension method; it operates on an existing styler.
Callable widget helperGenerate it with @MixableSpec(target: RemixWidget.new) so it stays aligned with the widget constructor.
Name conflictGive the component-specific behavior a descriptive name and reserve the canonical name for the generated surface.

Factories are generated from each component spec. Do not add public methods directly to generated *.g.dart files.

Canonical operations and conveniences

Canonical operations include APIs such as color, padding, borderRadius, scale, and direct child fields such as label. Each has exactly one spelling, so contextual shorthand always resolves to the same operation:

import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

final style = CardStyler()
    .padding(.all(12))
    .color(Colors.white)
    .onHovered(.padding(EdgeInsetsGeometryMix.all(16)))
    .onPressed(.color(Colors.grey.shade100));

Here every call names its operation once: color sets the container color and .padding(.all(12)) calls padding directly.

Slot-forwarding conveniences

Each slot-forwarding convenience names a child slot that has no canonical spelling of its own on the parent styler.

ConvenienceExpands to
AccordionStyler.titleColor(value).title(.color(value))
titleFontSize(value) / titleFontWeight(value).title(.fontSize(value)) / .title(.fontWeight(value))
titleStyle(value).title(.style(value))
leadingIconColor(value) / leadingIconSize(value).leadingIcon(.color(value)) / .leadingIcon(.size(value))
trailingIconColor(value) / trailingIconSize(value).trailingIcon(.color(value)) / .trailingIcon(.size(value))
contentColor(value) / contentPadding(value) / contentDecoration(value).content(.color(value)) / .content(.padding(value)) / .content(.decoration(value))
CalloutStyler.iconSize(value).icon(.size(value))
CalloutStyler.textStyle(value).text(.style(value))

Forwarded surfaces

Most visual components forward the canonical surface of their primary Box or FlexBox container. A composite root without one clear visual surface, such as MenuStyler, exposes factories for its child fields instead:

import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

final style = MenuStyler.trigger(
  MenuTriggerStyler.color(Colors.black),
);

SelectStyler stores its popup container as a FlexBox, but intentionally forwards only the compatible Box surface. This exposes operations such as color, padding, and scale without leaking popup layout controls through the root select styler.

The forwarded transform factory accepts Alignment. Use a direct child styler when a directional alignment is required, for example CardStyler.container(BoxStyler(transform: matrix, transformAlignment: AlignmentDirectional.centerStart)).

Variants and selected state

Widget-state and selected-state helpers consume the same styler type, so named factories work contextually for every generated Remix styler:

import 'package:flutter/material.dart';
import 'package:remix/remix.dart';

final checkboxStyle = CheckboxStyler()
    .onHovered(.color(Colors.grey.shade100))
    .onSelected(.color(Colors.green));

Component-specific operations

Component-specific operations use explicit names when a canonical operation already occupies the shorter name:

StylerCanonical generated APIComponent-specific helper
TextFieldStylercolor styles the containertextColor styles editable text
CalloutStylertextStyle(TextStyler) applies the container text stylecontentTextStyle(TextStyleMix) styles callout content

ButtonStyler.rotate transforms the container, while ButtonStyler.wrap(.rotate(...)) rotates the complete widget.

This keeps contextual shorthand predictable while preserving each specialized operation without ambiguous overloads.

Generation boundary

Component stylers are generated from @MixableSpec. Preset wrapper classes are generated from @MixWidget, which is not Remix-internal: any package that depends on remix can annotate a recipe function with it, and the generator emits a widget calling the target Remix constructor. The application-owned fortal preset uses exactly this mechanism to produce its prefixed catalog. The annotations identify the target Remix constructor and which recipe parameters become wrapper fields. Generated files remain deterministic build artifacts and should never be edited directly.

View page source on GitHub

On this page