Skip to content

fix(ui): draw the split button's divider on every surface - #173

Open
renefloor wants to merge 7 commits into
mainfrom
fix/disabled-split-button
Open

fix(ui): draw the split button's divider on every surface#173
renefloor wants to merge 7 commits into
mainfrom
fix/disabled-split-button

Conversation

@renefloor

Copy link
Copy Markdown
Collaborator

Submit a pull request

Linear: FLU-754

Github Issue: #

CLA

  • I have signed the Stream CLA (required).
  • The code changes follow best practices
  • Code changes are tested (add some information if not applicable)

Description of the pull request

The divider took borderDisabled while disabled, close enough to the disabled surface to vanish, so a disabled split button read as one wide pill with two icons in it. Checking the other states turned up more of the same: the divider is drawn on the button's own surface, so what it should be is a question about that surface rather than about the button's style.

Screenshots / Videos

renefloor and others added 2 commits September 1, 2026 14:52
The divider took borderDisabled while disabled, close enough to the disabled
surface to vanish, so a disabled split button read as one wide pill with two
icons in it. Checking the other states turned up more of the same: the divider
is drawn on the button's own surface, so what it should be is a question about
that surface rather than about the button's style.

  solid, accent fill   border/core/on-accent, per the design
  solid, secondary     border/core/default
  outline              the button's own border, so the divider continues it
  ghost                the button's icon colour, the only colour it has
  disabled             border/core/default, whatever the style

Only the first two are in the design; there is none for outline and ghost, and
the previous grey hairline cut across a blue or red outline rather than
continuing it. These are unreleased and unused, so the choice is cheap to
revisit.

The style defaults now take the resolved button style, since the divider's
colour is a property of what it is drawn on.

Adds a disabled matrix golden in both brightnesses. The state assertions read
what is painted — the surface's outline, the glyph's own text style — rather
than restating the tokens the implementation uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@renefloor
renefloor requested a review from a team as a code owner September 1, 2026 12:57
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 7b9ed3d5-ccc3-45c3-98d3-c51528e557f2


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment on lines -437 to +459
if (states.contains(WidgetState.disabled)) return _colorScheme.borderDisabled;
return _colorScheme.borderDefault;
// A disabled button drops its fill, its outline and its icon colour for
// the shared disabled treatment, so the divider goes back to the hairline
// that reads on it rather than disappearing into it as borderDisabled did.
if (states.contains(WidgetState.disabled)) return _colorScheme.borderDefault;

return switch (_type) {
// Drawn against the fill, unless the fill is already a light one.
StreamButtonType.solid =>
_style == StreamButtonStyle.secondary ? _colorScheme.borderDefault : _colorScheme.borderOnAccent,
// Continues the outline it sits inside.
StreamButtonType.outline => _buttonStyle.borderColor?.resolve(states) ?? _colorScheme.borderDefault,
// No fill and no outline, so the icons either side of it are the only
// colour the button has to match.
StreamButtonType.ghost => _buttonStyle.foregroundColor?.resolve(states) ?? _colorScheme.borderDefault,
};

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe in the next major release for chat, but I think we should have something like StreamMessageLayoutData for buttons, so you can pass all relevant fields to the theme resolver instead of the nested button styles we have now.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 67.82%. Comparing base (31c96f6) to head (32a1d98).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...rc/theme/components/stream_split_button_theme.dart 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #173      +/-   ##
==========================================
+ Coverage   65.93%   67.82%   +1.89%     
==========================================
  Files         203      208       +5     
  Lines        8198     8528     +330     
==========================================
+ Hits         5405     5784     +379     
+ Misses       2793     2744      -49     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants