buildFluentToolbar function
- FluentToolbarBaseState state,
- FluentToolbarStyle style,
- Set<
WidgetState> states
Renders a toolbar from a resolved state and style.
The third of the three-function recomposition contract. Takes FluentToolbarBaseState rather than FluentToolbarState on purpose: it never reads the size or the type, so a consumer can supply their own style and still use Fluent's layout.
Motion: none, and that is the spec
useToolbarStyles.styles.ts and useToolbarDividerStyles.styles.ts on
microsoft/fluentui@master declare no transition, no animation and no
motionTokens reference at all. A change of size or type therefore lands
on the next frame, exactly like FluentDivider and FluentCheckbox. There
is no AnimationController here and nothing for
MediaQuery.disableAnimationsOf to shorten — a toolbar is already correct
under reduced motion because it never moves. The buttons inside it animate
their own surfaces through FluentAnimatedStyle, which handles reduced
motion itself.
states exists for symmetry with the interactive components and is normally
empty — a toolbar is a container and reports no interaction state of its own.
It is still honoured, so a caller passing a state-dependent style gets what
they asked for.
Implementation
Widget buildFluentToolbar(
FluentToolbarBaseState state,
FluentToolbarStyle style,
Set<WidgetState> states,
) {
final radius = style.borderRadius?.resolve(states) ?? FluentRadius.allMedium;
final borderWidth = style.borderWidth?.resolve(states) ?? FluentStroke.none;
final borderColor = style.borderColor?.resolve(states);
final padding = style.padding?.resolve(states) ?? EdgeInsets.zero;
final gap = style.gap?.resolve(states) ?? FluentSpacing.none;
return DecoratedBox(
decoration: BoxDecoration(
color: style.backgroundColor?.resolve(states),
borderRadius: radius,
border: borderWidth > 0 && borderColor != null
? Border.all(color: borderColor, width: borderWidth)
: null,
boxShadow: style.shadow?.resolve(states),
),
child: Padding(
padding: padding,
// ponytail: IntrinsicHeight is what lets a divider span exactly the item
// row rather than a hard-coded 32 — it is the only way a Row can tell a
// child "be as tall as your tallest sibling". A toolbar holds a handful of
// shallow items so the extra layout pass is not worth optimising; if a
// toolbar ever holds a deep subtree, pin `dividerPadding` and give the
// divider a fixed height instead.
child: IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: gap,
children: state.items,
),
),
),
);
}