microsoft / microsoft/fluentui-blazor

feat: add `@bind`-able Pane Size to `FluentMultiSplitterPane`

Open
#5,160 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

improvement v5
Dominant language
C#
Stars
4.8k
Forks
483
Avg merge
14h 41m
Merged PRs (30d)
68

Description

🙋 Feature Request

FluentMultiSplitterPane.Size should be two-way bindable (@bind-Size) so that pane sizes can be set programmatically and by user dragging, in either order.

  • Size is init-only, after first drag it's ignored
  • There is no public API to set a pane's size from code.

Affects both v4 and v5

🤔 Expected Behavior

  • Setting Size should allow the pane to resize from code.
  • Size should be @bind-able, so a drag can then give you the new Size.
<FluentMultiSplitter OnResize="@OnResizeHandler">
    <FluentMultiSplitterPane @bind-Size="_leftSize" Min="50px">Left</FluentMultiSplitterPane>
    <FluentMultiSplitterPane @bind-Size="_rightSize">Right</FluentMultiSplitterPane>
</FluentMultiSplitter>

<FluentButton OnClick="@(() => _leftSize = "25%")">Reset left pane</FluentButton>

@code {
    private string? _leftSize = "20%";
    private string? _rightSize = "80%";
}

Clicking Reset left pane should set the pane to 25% whether or not it has already been dragged.

😯 Current Behavior

Each pane has a SizeRuntime which is where resizes are written to, and once this is set the passed-in size is completely ignored:

V4

public string Size
{
    get => string.IsNullOrWhiteSpace(SizeRuntime) ? _size : SizeRuntime;
    set => _size = value; 
}

dev-v5

protected string? StyleValue => DefaultStyleBuilder
    .AddStyle("flex-basis", string.IsNullOrWhiteSpace(SizeRuntime) ? Size : SizeRuntime)

Currently I have two options which I don't really like either of:

  • Reflect the SizeRuntime setter and then call Refresh.
  • Change a @key on the FluentMultiSplitter to nuke the whole thing - but that resets the child component as well.

Also, something that claude found at the same time, but I'm not 100% sure if this is intentional or not:

There is also a sharp edge that makes the reflection workaround hazardous with pixel values. StartResize's mouseup handler is guarded by:

if (splitteDataElement &&
pane?.style.flexBasis.includes('%') &&
paneNext?.style.flexBasis.includes('%')) {

If a pane has been set to e.g. 200px and the user presses and releases the splitter bar without moving, the guard fails, document's mousemove/mouseup listeners are never removed, and the pane subsequently tracks the cursor with no button held. (src/Core.Scripts/src/Components/Splitter/FluentMultiSplitter.ts on dev-v5; FluentMultiSplitter.razor.js on dev.)

💁 Possible Solution

Size becomes the actual current size - maybe with a separate SizeRuntime that is explicitly the size for things like mid-drag if that is necessary.

🔦 Context

Building a dashboard with resizable panes - but the UI also needs to derive from some dynamic state:

  • Restoring a saved layout on page load (user persisted sizing).
  • "Reset layout" etc buttons "50/50", "focus editor", "hide properties".

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with FluentMultiSplitterPane in the v4 and dev-v5 implementations, then trace resize handling in src/Core.Scripts/src/Components/Splitter/FluentMultiSplitter.ts and FluentMultiSplitter.razor.js. Verify that programmatic Size changes and user dragging stay synchronized through @bind-Size, including the pixel-value mouseup case. Done means the documented reset and persisted-layout scenarios work in both v4 and v5.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, javascript, typescript
Domain
frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.