152 lines
4.3 KiB
Plaintext
152 lines
4.3 KiB
Plaintext
@inject IJSRuntime JS
|
|
|
|
@*
|
|
* dbMango
|
|
*
|
|
* Copyright 2025 Deutsche Bank AG
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*@
|
|
|
|
<style>
|
|
.split-panel {
|
|
display: flex;
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.split-panel.horizontal {
|
|
flex-direction: row;
|
|
}
|
|
|
|
.split-panel.vertical {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.split-panel-pane {
|
|
overflow: auto;
|
|
}
|
|
|
|
.split-panel-splitter {
|
|
border-left: 1px solid @Night.Border;
|
|
border-right: 1px solid @Night.Border;
|
|
z-index: 1;
|
|
}
|
|
|
|
.split-panel.horizontal .split-panel-splitter {
|
|
width: @SplitterWidthPx px;
|
|
cursor: ew-resize;
|
|
}
|
|
|
|
.split-panel.vertical .split-panel-splitter {
|
|
height: @SplitterWidthPx px;
|
|
cursor: ns-resize;
|
|
}
|
|
</style>
|
|
|
|
<div class="split-panel @Orientation"
|
|
id="@_id"
|
|
@onmousemove="OnMouseMove"
|
|
@onmouseup="OnMouseUp"
|
|
@onmouseleave="OnMouseUp">
|
|
<div class="split-panel-pane first" style="@FirstPaneStyle">
|
|
@First
|
|
</div>
|
|
<div class="split-panel-splitter"
|
|
@onmousedown="OnMouseDown"
|
|
style="@SplitterStyle"></div>
|
|
<div class="split-panel-pane second" style="@SecondPaneStyle">
|
|
@Second
|
|
</div>
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public RenderFragment? First { get; set; }
|
|
[Parameter] public RenderFragment? Second { get; set; }
|
|
[Parameter] public string Orientation { get; set; } = "horizontal"; // "horizontal" or "vertical"
|
|
[Parameter] public double InitialSplit { get; set; } = 0.5; // 0.0 - 1.0
|
|
[Parameter] public int SplitterWidthPx { get; set; } = 3;
|
|
|
|
private string _id = $"S{Random.Shared.Next():08X}";
|
|
|
|
private double _split = 0.5;
|
|
private bool _isDragging = false;
|
|
private double _panelSize = 0;
|
|
private double _startPos = 0;
|
|
private double _startSplit = 0;
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
_split = InitialSplit;
|
|
}
|
|
|
|
private string FirstPaneStyle =>
|
|
Orientation == "vertical"
|
|
? $"height: {_split * 100}%;"
|
|
: $"width: {_split * 100}%;";
|
|
private string SecondPaneStyle =>
|
|
Orientation == "vertical"
|
|
? $"height: {(1 - _split) * 100}%;"
|
|
: $"width: {(1 - _split) * 100}%;";
|
|
private string SplitterStyle =>
|
|
Orientation == "vertical"
|
|
? $"height: {SplitterWidthPx}px; cursor: ns-resize;"
|
|
: $"width: {SplitterWidthPx}px; cursor: ew-resize;";
|
|
|
|
private async void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
_isDragging = true;
|
|
_startSplit = _split;
|
|
if (Orientation == "vertical")
|
|
{
|
|
_panelSize = await GetPanelSizeAsync("clientHeight");
|
|
_startPos = e.ClientY;
|
|
}
|
|
else
|
|
{
|
|
_panelSize = await GetPanelSizeAsync("clientWidth");
|
|
_startPos = e.ClientX;
|
|
}
|
|
}
|
|
|
|
private void OnMouseMove(MouseEventArgs e)
|
|
{
|
|
if (!_isDragging) return;
|
|
double delta = 0;
|
|
if (Orientation == "vertical")
|
|
delta = (e.ClientY - _startPos) / (_panelSize == 0 ? 1 : _panelSize);
|
|
else
|
|
delta = (e.ClientX - _startPos) / (_panelSize == 0 ? 1 : _panelSize);
|
|
|
|
_split = Math.Clamp(_startSplit + delta, 0.01, 0.99);
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void OnMouseUp(MouseEventArgs e)
|
|
{
|
|
_isDragging = false;
|
|
}
|
|
|
|
private async Task<double> GetPanelSizeAsync(string property)
|
|
{
|
|
// Inline JS: get the property directly from the element
|
|
return await JS.InvokeAsync<double>(
|
|
"eval",
|
|
$"(function(element){{return element.{property} || 0;}})(document.getElementById('{_id}'))"
|
|
);
|
|
}
|
|
}
|