Skip to content

feat: add @bind-able Pane Size to FluentMultiSplitterPane#5160

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".

Metadata

Metadata

Assignees

No one assigned

    Labels

    improvementA non-feature-adding improvement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions