microsoft / microsoft/fluentui-blazor
feat: add `@bind`-able Pane Size to `FluentMultiSplitterPane`
Nobody has claimed this yet.
- 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
Sizeshould allow the pane to resize from code. - Size should be
@bind-able, so a drag can then give you the newSize.
<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
@keyon 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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