Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: FluentOverflow does not fit to container when ChildContent is modified #2225

Closed
S-Syrichko opened this issue Jun 20, 2024 · 2 comments
Closed
Labels
status:in-progress Work is in progress

Comments

@S-Syrichko
Copy link

馃悰 Bug Report

When using FluentOverflow with FluentBadge and modifying badge values, the FluentOverflow component does not update it's width.

馃捇 Repro or Code Sample

<button id="myPopoverButton" style="width: 200px; height: 30px; overflow-x: visible; border-width: 1px; border-radius: 4px; box-sizing: content-box; padding: 4px;" @onclick="() => _showPopover = !_showPopover">
    <FluentOverflow Style="width: 100%;">
        <ChildContent>
            @foreach(var item in categoryItems)
            {
                <FluentOverflowItem Style="background-color: #ffd800; border-radius: 4px;">
                    <FluentBadge Appearance="Appearance.Lightweight">@item.Name</FluentBadge>
                </FluentOverflowItem>
            }
        </ChildContent>
        <MoreButtonTemplate >
            <FluentBadge Appearance="Appearance.Lightweight" Style="width: 32px; border-radius: 4px; background-color: #ffd800;">
                @($"+{context.ItemsOverflow.Count()}")
            </FluentBadge>
        </MoreButtonTemplate>
    </FluentOverflow>
</button>

<FluentPopover AnchorId="myPopoverButton" Style="width: 300px" @bind-Open="_showPopover">
        <Body>
            <FluentGrid Justify="JustifyContent.FlexStart" Spacing="3">
                <FluentGridItem xs="11">
                    <FluentSortableList Items="categoryItems" OnUpdate="@SortList" Style="width: 100%;">
                        <ItemTemplate>
                            <FluentTextField @bind-value="@context.Name" Minlength="4" Style="width: 80%; margin-right: 15px;"></FluentTextField>
                            <FluentIcon Value="@(new Icons.Regular.Size16.ChevronUpDown())" />
                        </ItemTemplate>
                    </FluentSortableList>
                </FluentGridItem>
                <FluentGridItem xs="11">
                    <FluentButton Appearance="Appearance.Stealth" OnClick="@Save">
                        <FluentIcon Value="@(new Icons.Regular.Size28.Save())" />
                    </FluentButton>
                </FluentGridItem>
            </FluentGrid>
        </Body>
    </FluentPopover>
    
@code 
{
    protected string ClassValue => "customOverflow";
    protected string CategoryButton => "categoryButton";

    bool _showPopover;
    
    [Parameter]
    public ObservableCollection<string> InitialItems { get; set; }

    [Parameter]
    public EventCallback<ObservableCollection<string>> ItemsUpdated { get; set; }

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; } = "";

    }

    public ObservableCollection<Item> categoryItems = new ObservableCollection<Item>();

    protected override void OnInitialized()
    {
        if (InitialItems != null)
        {
            categoryItems = new ObservableCollection<Item>(InitialItems.Select((name, index) => new Item { Id = index, Name = name }));
        }
    }

    private void SortList(FluentSortableListEventArgs args)
    {
        if (args is null || args.OldIndex == args.NewIndex)
        {
            return;
        }

        var oldIndex = args.OldIndex;
        var newIndex = args.NewIndex;

        var items = this.categoryItems;
        var itemToMove = items[oldIndex];
        items.RemoveAt(oldIndex);

        if (newIndex < items.Count)
        {
            items.Insert(newIndex, itemToMove);
        }
        else
        {
            items.Add(itemToMove);
        }
        itemToMove.Id = newIndex;
        InvokeAsync(() =>
        {

            StateHasChanged();
        });
    }
    private async Task Save()
    {
        var updatedItems = categoryItems.OrderBy(i => i.Id).Select(i => i.Name).ToList();
        this.StateHasChanged();
        await ItemsUpdated.InvokeAsync(new ObservableCollection<string>(updatedItems));
    }

    

}
    

馃 Expected Behavior

FluentOverflow fits the button width when badge content is updated.

馃槸 Current Behavior

image
image
image

@microsoft-github-policy-service microsoft-github-policy-service bot added the triage New issue. Needs to be looked at label Jun 20, 2024
@vnbaaij vnbaaij added status:needs-investigation Needs additional investigation needs: author feedback The author of this issue needs to respond in order for us to continue investigating this issue. and removed triage New issue. Needs to be looked at labels Jun 20, 2024
@vnbaaij
Copy link
Collaborator

vnbaaij commented Jun 20, 2024

Currently, the FluentOverflow is setup in such a way that the underlying script only responds to changes to its 'childlist' (OverflowItems being added/removed) so the behavior you are seeing is expected.

The script does already have an exported resize/refresh function . What we could do is add a public method RefreshAsync to the FluentOverflow component that would call the exported function in the script when invoked.

Your code would then change to this:

@using System.Collections.ObjectModel

<button id="myPopoverButton" style="width: 200px; height: 30px; overflow-x: visible; border-width: 1px; border-radius: 4px; box-sizing: content-box; padding: 4px;" @onclick="() => _showPopover = !_showPopover">
    <FluentOverflow Style="width: 100%;" @ref="@_overflow">
        <ChildContent>
            @foreach (var item in categoryItems)
            {
                <FluentOverflowItem Style="background-color: #ffd800; border-radius: 4px;">
                    <FluentBadge Appearance="Appearance.Lightweight">@item.Name</FluentBadge>
                </FluentOverflowItem>
            }
        </ChildContent>
        <MoreButtonTemplate>
            <FluentBadge Appearance="Appearance.Lightweight" Style="width: 32px; border-radius: 4px; background-color: #ffd800;">
                @($"+{context.ItemsOverflow.Count()}")
            </FluentBadge>
        </MoreButtonTemplate>
    </FluentOverflow>
</button>

<FluentPopover AnchorId="myPopoverButton" Style="width: 300px" @bind-Open="_showPopover">
    <Body>
        <FluentGrid Justify="JustifyContent.FlexStart" Spacing="3">
            <FluentGridItem xs="11">
                <FluentSortableList Items="categoryItems" OnUpdate="@SortListAsync" Style="width: 100%;">
                    <ItemTemplate>
                        <FluentTextField @bind-value="@context.Name" Minlength="4" Style="width: 80%; margin-right: 15px;"></FluentTextField>
                        <FluentIcon Value="@(new Icons.Regular.Size16.ChevronUpDown())" />
                    </ItemTemplate>
                </FluentSortableList>
            </FluentGridItem>
            <FluentGridItem xs="11">
                <FluentButton Appearance="Appearance.Stealth" OnClick="@Save">
                    <FluentIcon Value="@(new Icons.Regular.Size28.Save())" />
                </FluentButton>
            </FluentGridItem>
        </FluentGrid>
    </Body>
</FluentPopover>

@code
{
    protected FluentOverflow? _overflow;
    protected string ClassValue => "customOverflow";
    protected string CategoryButton => "categoryButton";

    bool _showPopover;

    [Parameter]
    public ObservableCollection<string> InitialItems { get; set; } = ["aaaaa", "bbbbb", "ccccc"];

    [Parameter]
    public EventCallback<ObservableCollection<string>> ItemsUpdated { get; set; }

    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; } = "";

    }

    public ObservableCollection<Item> categoryItems = new ObservableCollection<Item>();

    protected override void OnInitialized()
    {
        if (InitialItems != null)
        {
            categoryItems = new ObservableCollection<Item>(InitialItems.Select((name, index) => new Item { Id = index, Name = name }));
        }
    }

    private async Task SortListAsync(FluentSortableListEventArgs args)
    {
        if (args is null || args.OldIndex == args.NewIndex)
        {
            return;
        }

        var oldIndex = args.OldIndex;
        var newIndex = args.NewIndex;

        var items = this.categoryItems;
        var itemToMove = items[oldIndex];
        items.RemoveAt(oldIndex);

        if (newIndex < items.Count)
        {
            items.Insert(newIndex, itemToMove);
        }
        else
        {
            items.Add(itemToMove);
        }
        itemToMove.Id = newIndex;

        if (_overflow is not null)
        {
           await _overflow.RefreshAsync();
        }
    }
    private async Task Save()
    {
        var updatedItems = categoryItems.OrderBy(i => i.Id).Select(i => i.Name).ToList();
        if (_overflow is not null)
        {
            await _overflow.RefreshAsync();
        }
        await ItemsUpdated.InvokeAsync(new ObservableCollection<string>(updatedItems));
    }
}
  1. add @ref="@_overflow" to the FluentOverflow (and declare it of course)
  2. call await _overflow.RefreshAsync(); on SortListAsync and Save

Thoughts?

vnbaaij added a commit that referenced this issue Jun 20, 2024
-Add public RefreshAsync method to call refresf function in script (#2225)
-Prep work for adding new VisibleOnLoad parameter (#2221)
@vnbaaij vnbaaij added status:in-progress Work is in progress and removed needs: author feedback The author of this issue needs to respond in order for us to continue investigating this issue. status:needs-investigation Needs additional investigation labels Jun 22, 2024
vnbaaij added a commit that referenced this issue Jun 24, 2024
* - Rename functions in js to be in line with rest of scripts
-Add public RefreshAsync method to call refresf function in script (#2225)
-Prep work for adding new VisibleOnLoad parameter (#2221)

* - Clear out IssueTester
- Add VisiblieOnLoad parameter
- Add compensation for overflow badge itself in js
@vnbaaij
Copy link
Collaborator

vnbaaij commented Jun 24, 2024

Fixed with #2236

@vnbaaij vnbaaij closed this as completed Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:in-progress Work is in progress
Projects
None yet
Development

No branches or pull requests

2 participants