Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.26k stars 529 forks source link

Feature: interactively resizable side bar #2423

Open nightroman opened 3 years ago

nightroman commented 3 years ago

Feature: interactively resizable side bar

ref:

Is your feature request related to a problem? Please describe.

Kind of a usability problem and poor user experience in some cases.

We use TreeView in the side bar (left panel) and render selected item pages in the main area (right panel). It's a popular UI layout pattern used in apps like "file explorers", "hierarchical content browsers", etc.

Depending on the tree item text lengths and the depth of expanded items the fixed width of the side bar (either default or custom but still fixed) may be insufficient for comfortable viewing and navigating through the tree items.

And I can imagine use cases without TreeView but with dynamic content of the side bar. The comfortable width may be difficult to predict and set beforehand.

Describe the solution you'd like

The natural solution would be ability to resize the side bar by dragging the right edge of the bar horizontally, some sort of optional vertical splitter dividing the application side bar and main areas.

nightroman commented 3 years ago

Here is a poor man solution mentioned in the discussion. It uses the slider component shown (optionally) at the top.

Part 1. Markup.

@inject IJSRuntime JS

@if (_showSlider)
{
    <Slider TValue="int" Value="@_width1" Max="@_width2" ValueChanged="@SliderValueChanged" />
}

<Layout Sider="true">
    <LayoutSider>
        <LayoutSiderContent>
            ...

Part 2. Code behind.

Code for toggling _showSlider is omitted for simplicity (and implementation is rather opinionated).

    bool _showSlider;
    int _width1, _width2;
    [CascadingParameter] protected Theme Theme { get; set; }

    protected override async Task OnInitializedAsync()
    {
        _width2 = await JS.InvokeAsync<int>("getWindowWidth");
        _width1 = int.Parse(Theme.BarOptions.VerticalWidth.Replace("px", ""));
    }

    async Task SliderValueChanged(int value)
    {
        var coeff = (double)value / _width2;
        _width2 = await JS.InvokeAsync<int>("getWindowWidth");
        _width1 = Math.Max(300, (int)(_width2 * coeff));
        Theme.BarOptions.VerticalWidth = $"{_width1}px";
        Theme.ThemeHasChanged();
    }

Part 3. JavaScript, e.g. in index.html

    <script>
        function getWindowWidth() {
            return window.innerWidth;
        }
    </script>
njannink commented 2 years ago

Our UX designer has also requested this feature. To have a resizable sidebar and to also have it resize automatically when resizing the window. Like having a percentage size + explicit max-size instead of having 1 fixed values / breakpoints

stsrki commented 2 years ago

I can schedule it for 1.2 and we'll see how it goes.

nightroman commented 2 years ago

@stsrki Fantastic news, looking forward to it!

njannink commented 2 years ago

good news @stsrki

for now I will use a css formula to calculate the width --b-vertical-bar-width: min(350px, max(200px, calc(20vw)));