UI/SpawnMenu/Props/SpawnPageLocal.razor
@using Sandbox;
@using Sandbox.UI;

@inherits Panel
@namespace Sandbox

<SpawnMenuContent>

    <Header>
        <SpawnMenuToolbar>
            <Left>
                <TextEntry Placeholder="#spawnmenu.common.search" class="filter menu-input" Value:bind=@Filter />
            </Left>
        </SpawnMenuToolbar>
    </Header>

    <Body>
        @if ( Entries.Count == 0 )
        {
            <SpawnMenuEmptyState Icon="search_off" Subtitle="#spawnmenu.empty.try_another_category" />
        }
        else
        {
            <VirtualGrid Items=@Entries ItemSize=@(new Vector2( 160, 120 ))>
                <Item Context="item">
                    @if ( item is LocalProps.Entry entry )
                    {
                        <SpawnMenuIcon Ident=@($"prop:{entry.Path}") [email protected] />
                    }
                </Item>
            </VirtualGrid>
        }
    </Body>

</SpawnMenuContent>

@code
{
    public string Category { get; set; } = "";

    private string Filter
    {
        get;
        set { field = value; Rebuild(); }
    }

    private List<LocalProps.Entry> Entries = new();

    protected override void OnParametersSet()
    {
        Rebuild();
    }

    void Rebuild()
    {
        var source = string.IsNullOrEmpty( Category )
            ? LocalProps.All
            : LocalProps.All.Where( x => x.Category == Category ).ToList();

        if ( !string.IsNullOrWhiteSpace( Filter ) )
            source = source.Where( x => x.DisplayName.Contains( Filter, StringComparison.OrdinalIgnoreCase )
                                     || x.Path.Contains( Filter, StringComparison.OrdinalIgnoreCase ) ).ToList();

        Entries = source;
        StateHasChanged();
    }
}