add multiple select list

This commit is contained in:
2025-03-11 00:14:09 +01:00
parent fbcd40834e
commit 3ba79fdf03
11 changed files with 124 additions and 20 deletions

View File

@@ -1,7 +1,7 @@
using FluentValidation;
using GameIdeas.Shared.Dto;
namespace GameIdeas.BlazorApp.Shared.Layouts.Header;
namespace GameIdeas.BlazorApp.Shared.Components.Account;
public class LoginValidator : AbstractValidator<LoginDto>
{

View File

@@ -3,14 +3,25 @@
<InputText class="search-field"
@bind-Value=Text />
@if (!string.IsNullOrEmpty(Text))
{
<div class="clear-icon" @onclick=HandleClearClicked>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
</svg>
</div>
}
<div type="submit" class="search-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
@if (Icon == SearchInputIcon.Search)
{
<path d="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
}
else if (Icon == SearchInputIcon.Dropdown)
{
<path style="fill: var(--violet)" d="M1 3H23L12 22" />
}
</svg>
</div>
</div>

View File

@@ -8,6 +8,7 @@ public partial class SearchInput
{
[Parameter] public string? Text { get; set; }
[Parameter] public EventCallback<string> TextChanged { get; set; }
[Parameter] public SearchInputIcon Icon { get; set; }
private EditContext? EditContext;

View File

@@ -0,0 +1,7 @@
namespace GameIdeas.BlazorApp.Shared.Components.Search;
public enum SearchInputIcon
{
Search,
Dropdown
}

View File

@@ -11,7 +11,6 @@ public partial class SelectListElement<TItem>
{
if (Value != null)
{
Value.IsSelected = true;
await ValueChanged.InvokeAsync(Value);
}
}

View File

@@ -1,19 +1,32 @@
.select-element {
display: flex;
flex-direction: row;
width: fit-content;
width: 100%;
gap: 6px;
height: 20px;
align-items: center;
}
.select-element:hover {
cursor: pointer;
}
.selected {
width: 12px;
min-width: 12px;
height: 12px;
min-height: 12px;
}
.selected svg {
display: block;
fill: var(--white)
}
/***** Navigation Theme *****/
.navigation {
padding: 4px 8px;
width: 100%;
}
.navigation .selected {
@@ -26,10 +39,6 @@
/***** Sort Theme *****/
.sort {
gap: 6px;
display: flex;
flex-direction: row;
width: 100%;
padding: 2px 6px;
}
@@ -37,11 +46,6 @@
background: var(--low-white);
}
.sort .selected {
width: 20px;
height: 20px;
}
.sort .select-label {
text-wrap: nowrap;
margin-right: 6px;

View File

@@ -0,0 +1,29 @@
@using GameIdeas.BlazorApp.Shared.Components.Search
@using GameIdeas.BlazorApp.Shared.Components.Select.Components
@typeparam TItem
<div class="select-list" @onclick=HandleButtonClicked>
<div class="select-button">
<SearchInput Icon="SearchInputIcon.Dropdown"
Text="Text"
TextChanged="HandleTextChanged"/>
</div>
<div @ref=Container @onfocusout=HandleFocusOut
class="select-container @(AlignRight ? "align-right" : "")"
tabindex="1000">
@if (ContentVisile)
{
<div class="select-content @(Enum.GetName(Theme)?.ToLower())">
@foreach (var item in Items)
{
<SelectListElement TItem="TItem"
Value="item"
ValueChanged="HandleItemClicked"
Theme="Theme" />
}
</div>
}
</div>
</div>

View File

@@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Components;
namespace GameIdeas.BlazorApp.Shared.Components.Select;
public partial class MultipleSelectList<TItem>
{
[Parameter] public IEnumerable<TItem>? Values { get; set; }
[Parameter] public EventCallback<IEnumerable<TItem>?> ValuesChanged { get; set; }
[Parameter] public IEnumerable<SelectElement<TItem>> Items { get; set; } = [];
[Parameter] public SelectListTheme Theme { get; set; }
[Parameter] public bool AlignRight { get; set; }
private bool ContentVisile = false;
private DateTime ContentLastFocusOut = DateTime.Now;
private ElementReference Container;
private string? Text;
public async Task OpenAsync()
{
if (DateTime.Now - ContentLastFocusOut >= TimeSpan.FromSeconds(0.2))
{
await Container.FocusAsync();
ContentVisile = true;
}
}
public void Close() => ContentVisile = false;
private async Task HandleButtonClicked() => await OpenAsync();
private void HandleFocusOut()
{
ContentLastFocusOut = DateTime.Now;
ContentVisile = true;
}
private async Task HandleItemClicked(SelectElement<TItem> selectedValue)
{
selectedValue.IsSelected = !selectedValue.IsSelected;
Values = Items.Where(x => x.IsSelected && x.Item != null).Select(x => x.Item!);
Text = string.Join(", ", Values);
await ValuesChanged.InvokeAsync(Values);
}
private void HandleTextChanged(string args)
{
foreach (var item in Items)
{
item.IsSelected = false;
}
}
}

View File

@@ -0,0 +1 @@
@import "SelectList.razor.css";

View File

@@ -5,4 +5,5 @@ public class SelectElement<TItem>
public TItem? Item { get; set; }
public string? Label { get; set; }
public bool IsSelected { get; set; } = false;
public bool IsNew { get; set; } = false;
}

View File

@@ -34,7 +34,7 @@ public partial class SelectList<TItem>
private void HandleFocusOut()
{
ContentLastFocusOut = DateTime.Now;
ContentVisile = false;
ContentVisile = true;
}
private async Task HandleItemClicked(SelectElement<TItem> selectedValue)