---
title: Styler API
description: 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`).

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

The following expressions are equivalent:

```dart
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 shape | Policy |
| --- | --- |
| Canonical style operation | Expose both a named factory and a matching fluent method. |
| Direct child styler field | Expose a field factory such as `MenuStyler.trigger(...)`. |
| Primary nested container | Forward one compatible canonical surface from the nested styler. |
| Alias of a canonical operation | Do 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 helper | Keep it as an extension method; it operates on an existing styler. |
| Callable widget helper | Generate it with `@MixableSpec(target: RemixWidget.new)` so it stays aligned with the widget constructor. |
| Name conflict | Give 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:

```dart
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.

| Convenience | Expands 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:

```dart
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:

```dart
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:

| Styler | Canonical generated API | Component-specific helper |
| --- | --- | --- |
| `TextFieldStyler` | `color` styles the container | `textColor` styles editable text |
| `CalloutStyler` | `textStyle(TextStyler)` applies the container text style | `contentTextStyle(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
[`remix_fortal`](/fortal) package does exactly this to produce its `Fortal*`
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.
