feat: component styles on every widget with app-wide FlowTheme defaults - #21
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 88b289a. Configure here.
| ), | ||
| style: typography.labelMediumEmphasised | ||
| .copyWith(color: labelForeground) | ||
| .merge(style?.labelStyle), |
There was a problem hiding this comment.
Label style skips disabled ink
Low Severity
labelStyle is merged after the enabled/disabled foreground is applied, so a labelStyle that sets color keeps full-strength ink on disabled FlowPill and FlowSuggestion rows. iconColor / removeColor / foregroundColor correctly run through flowDisabledColor, so disabled pills and suggestions can show a muted icon beside an unmuted label.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 88b289a. Configure here.


Summary
Adds Material's component-theme tier on top of flow_ui's tokens. Every major widget now takes an optional style object of color and text overrides, and
FlowThemecarries an app-wide default for each.lib/src/styles/, joiningFlowMenuStyle(moved there too):FlowComposerStyle,FlowMessageStyle,FlowMarkdownStyle,FlowCodeBlockStyle,FlowErrorStateStyle,FlowMessageActionsStyle,FlowPillStyle,FlowSuggestionStyle. Each is an immutable data bag of optional fields withmerge(other wins),lerp(theme transitions, following the nullablesyntaxconvention), and value equality. Text fields merge over their role's base.FlowThemegains one optional field per style (markdownStyle,menuStyle,composerStyle, ...) with fullcopyWith/lerp. Resolution is field by field everywhere: the widget's style wins over the theme's, tokens beneath both.FlowMarkdownStyleopens the markdown surface per element: heading cuts for all six levels, link color, inline-code face and painted chip fill, quote bar and ink, table header/cell styles and hairlines, rule color. The settled-span cache keys on the resolved style, so restyling invalidates while streaming deltas keep reusing it.outlineColorflattens the gradient hairline in every state (the menu border precedent); the code block'sborderColorholds through hover unlesshoverBorderColorsays otherwise; failed turns keep their error treatment regardless ofbubbleColor.lib/src/styles/folder so the dependency direction matches the taxonomy:widgets -> stylesandtheme -> styles, withflow_theme.dartno longer importing fromwidgets/. Everything re-exports through the barrel, so the public API surface is purely additive.Docs: every component page gains a
Restylingsection, theming.mdx a "Component styles" section with the resolution story, and the changelog a0.3.0 (unreleased)entry. The pubspec stays at 0.2.0 so the pending release is unaffected.Screenshots
How this was verified
flutter analyzeclean in the package root,example/, andplayground/;dart formatapplied; docs site builds;flutter pub publish --dry-runvalidates. A scratch widget-test harness proves the resolution chain behaviorally: a themeFlowMarkdownStylereaches link spans and chip fills, a widget-level field beats the theme's,FlowMessageStyle/FlowCodeBlockStyleland on the bubble and block grounds, and with nothing installed every token default holds. The existing streaming-reveal tests pass unchanged.Checklist
flutter analyze libandflutter analyzeinexample/andplayground/are cleandart format .applieddependencies:inpubspec.yaml(Flutter SDK and flutter.dev packages only)lib/flow_ui.dartand documented indocs/and the README tableCHANGELOG.mdupdated for user-facing changes, with breaking changes called outfeat:,fix:,refactor:,docs:,chore:)Note
Low Risk
Additive theming API with field-by-field merge over existing tokens; no auth, data, or behavior changes unless hosts opt in.
Overview
Adds Material-style component themes on top of flow_ui tokens. Major widgets now take an optional
FlowXStylebag of color/text overrides, andFlowThemecan carry an app-wide default for each.Resolution is field by field: widget style wins over theme style, tokens underneath. Text fields merge onto their role’s base.
FlowMenuStylemoves tolib/src/styles/with the new classes (FlowComposerStyle,FlowMessageStyle,FlowMarkdownStyle,FlowCodeBlockStyle,FlowErrorStateStyle,FlowMessageActionsStyle,FlowPillStyle,FlowSuggestionStyle). Public API is additive.FlowMarkdownStylecovers headings, links, inline-code chips, quotes, tables, and rules; the settled-span cache keys on the resolved style. A few look details stay faithful: composeroutlineColorflattens the gradient hairline; code-blockborderColorholds through hover unlesshoverBorderColoris set; failed user turns keep error treatment regardless of bubble style.Docs add a Restyling section per component plus a theming overview; changelog notes 0.3.0 (unreleased).
Reviewed by Cursor Bugbot for commit 88b289a. Bugbot is set up for automated code reviews on this repo. Configure here.