conceptadev / conceptadev/mix

Add a subtree blend-mode widget modifier

Open
#994 0 comments 0 reactions 0 assignees View on GitHub
enhancement mix
Dominant language
Dart
Stars
800
Forks
49
Avg merge
3h 39m
Merged PRs (30d)
22

Description

## Use case

Mix supports `BoxDecorationMix.backgroundBlendMode`, which blends a decoration's own background layers, and `ShaderMaskModifier`, which blends a shader with its child. It does not currently have the widget-level equivalent of CSS `mix-blend-mode`: compositing a complete rendered child subtree as one source against content already painted behind it.

This is needed when mapping design systems that use element-level blending. For example, Radix Themes applies `mix-blend-mode: multiply` to disabled Slider roots in light themes and `screen` in dark themes. Applying a blend mode independently to the track, range, thumbs, and shadows produces different output because those elements are not grouped before compositing.

Remix currently needs a bespoke render-object wrapper to preserve this behavior.

## Visual comparison

The same disabled Fortal Slider is rendered against the same backdrop. Only subtree compositing changes.

![Disabled Fortal Slider before and after subtree multiply blending](https://gist.githubusercontent.com/leoafarias/ae1fa64af6cf4af78a8fc0f7ccbb938d/raw/216422386c3b7abde6b4ff5517dbc1e913318d89/fortal_slider_before_after_flutter.png)

- **Before:** `BlendMode.srcOver` — standard painting, with no subtree layer.
- **After:** `BlendMode.multiply` — the complete Slider subtree is composited as one layer against the backdrop.

This comparison was rendered by Flutter with the theme, recipe, disabled state, value, dimensions, and backdrop held constant.

## Proposal

Add a Mix widget modifier for subtree blending, tentatively `BlendModeModifier` / `BlendModeModifierMix`, exposed through `WidgetModifierConfig`.

Proposed usage:

```dart
BoxStyler().wrap(.blendMode(BlendMode.multiply))
```

Desired behavior:

- Composite the complete painted child subtree against its backdrop using the selected `BlendMode`.
- Treat `BlendMode.srcOver` as a no-op fast path.
- Preserve layout, hit testing, and semantics.
- Participate in normal Mix property resolution and modifier merging.
- Account for child paint overflow and explicit clips when determining the blend layer bounds.
- Explicitly support or document the behavior for composited descendants such as `RepaintBoundary`.

A canvas implementation can group child painting with `saveLayer`, but retained/composited descendants cannot simply be enclosed by that canvas operation. The API should therefore either support them through a layer-based design or expose the limitation clearly.

This is distinct from both decoration `backgroundBlendMode` and `ShaderMaskModifier` because the source and destination operands are different.

## References

- [Radix Themes Slider uses element-level blend modes](https://github.com/radix-ui/themes/blob/1faff10ac26ae17f09944d418c6949b93fc6b566/packages/radix-ui-themes/src/components/slider.css#L249-L263)
- [Mix `BoxDecorationMix.backgroundBlendMode`](https://github.com/conceptadev/mix/blob/2daca01db3b146ec5bd0a466019b6a7d8dbdb02b/packages/mix/lib/src/properties/painting/decoration_mix.dart#L115-L161)
- [Mix `ShaderMaskModifier`](https://github.com/conceptadev/mix/blob/2daca01db3b146ec5bd0a466019b6a7d8dbdb02b/packages/mix/lib/src/modifiers/shader_mask_modifier.dart#L9-L69)
- [Current Remix subtree compositor](https://github.com/conceptadev/remix/blob/1d9c7ee97268c5e7708ca69a35d5cd09326832ac/packages/remix/lib/src/rendering/remix_blend_mode.dart)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the existing ShaderMaskModifier and BoxDecorationMix references, then inspect Remix's packages/remix/lib/src/rendering/remix_blend_mode.dart. Determine how a widget modifier could composite a complete subtree while preserving layout, hit testing, semantics, overflow, clips, and composited descendants. Done means the proposed modifier is exposed through WidgetModifierConfig and its supported behavior and limitations are documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
frontend, mobile-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.