Add dropdown component
This commit is contained in:
		
							parent
							
								
									455119f467
								
							
						
					
					
						commit
						b250353ad8
					
				
							
								
								
									
										48
									
								
								src/Connected.Components/Components/Dropdown.razor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/Connected.Components/Components/Dropdown.razor
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| @typeparam T; | ||||
| @inherits Connected.Models.InputBase; | ||||
| 
 | ||||
| <div class="@InputFieldClassList"> | ||||
|    <select type="textarea" @onfocus="(()=> Open())" @onblur="(()=> Close())"> | ||||
|       @if (SelectedItems.Any()) | ||||
|       { | ||||
|          <option selected> | ||||
|             @foreach (var item in SelectedItems) | ||||
|             { | ||||
|                @SelectedValueTemplate?.Invoke(item) | ||||
|             } | ||||
|          </option> | ||||
|       } | ||||
|    </select> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|    <span class="highlight"></span><span class="bar"></span> | ||||
|    <label class="label-animated">@Label</label> | ||||
|    <div class="input-helper-text">@HelperText</div> | ||||
|    <div class="input-error-text">@ErrorText</div> | ||||
|    <span class="input-glyph-wraper"> | ||||
|       <span class="input-glyph button"> | ||||
|          <Glyph SVG="@Icons.Material.Outlined.Cancel" class="icon-root svg-icon" Click="_ => { SelectedItems.Clear(); Close(); }" /> | ||||
|       </span> | ||||
|       <span class="input-glyph"> | ||||
|          <Glyph SVG="@Icons.Material.Filled.ArrowDropDown" class="icon-root svg-icon icon-size-md" Click="()=> Toggle()" /> | ||||
|       </span> | ||||
|       <span class="input-glyph error"> | ||||
|          <Glyph SVG="@Icons.Material.Outlined.ErrorOutline" class="icon-root svg-icon" /> | ||||
|       </span> | ||||
|    </span> | ||||
| 
 | ||||
|    <TransitionAnimator TransitionDuration="5000" TransitionInClass="drop-down fade-in" TransitionOutClass="drop-down fade-out" Visible=@DropdownOpen> | ||||
|       <div class="backdrop d-sm-none"> | ||||
|       </div> | ||||
|       <div class="dropdown-menu"> | ||||
|          @foreach (var item in Items) | ||||
|          { | ||||
|             <div class="dropdown-item @(IsItemSelected(item)?"active":"")" | ||||
|               @onclick="(async () => await OptionSelected(item))"> | ||||
|                @OptionTemplate?.Invoke(item) | ||||
|             </div> | ||||
|          } | ||||
|       </div> | ||||
|    </TransitionAnimator> | ||||
| </div> | ||||
							
								
								
									
										112
									
								
								src/Connected.Components/Components/Dropdown.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/Connected.Components/Components/Dropdown.razor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| using Microsoft.AspNetCore.Components; | ||||
| using System.Collections.ObjectModel; | ||||
| using Connected.Models; | ||||
| using System.Collections.Immutable; | ||||
| 
 | ||||
| namespace Connected.Components; | ||||
| 
 | ||||
| public partial class Dropdown<T> : InputBase, IAsyncDisposable | ||||
| { | ||||
| 	[Parameter, EditorRequired] | ||||
| 	public ObservableCollection<T> Items { get; set; } = new ObservableCollection<T>(); | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public RenderFragment<T>? OptionTemplate { get; set; } | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public RenderFragment<T>? SelectedValueTemplate { get; set; } | ||||
| 
 | ||||
| 	[Parameter, EditorRequired] | ||||
| 	public Func<T, string> ItemToKey { get; set; } = default!; | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public ObservableCollection<T> SelectedItems { get; set; } = new(); | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public EventCallback<ObservableCollection<T>> SelectedItemsChanged { get; set; } | ||||
| 
 | ||||
| 	[Parameter] | ||||
| 	public bool AllowMultiple { get; set; } | ||||
| 
 | ||||
| 	private bool DropdownOpen { get; set; } | ||||
| 
 | ||||
| 	private bool IsItemSelected(T item) | ||||
| 	{ | ||||
| 		return SelectedItems.Contains(item); | ||||
| 	} | ||||
| 
 | ||||
| 	public void Open() | ||||
| 	{ | ||||
| 		DropdownOpen = true; | ||||
| 	} | ||||
| 
 | ||||
| 	public void Close() | ||||
| 	{ | ||||
| 		DropdownOpen = false; | ||||
| 	} | ||||
| 
 | ||||
| 	public void Toggle() | ||||
| 	{ | ||||
| 		DropdownOpen = !DropdownOpen; | ||||
| 	} | ||||
| 
 | ||||
| 	protected override void OnInitialized() | ||||
| 	{ | ||||
| 		base.OnInitialized(); | ||||
| 		 | ||||
| 		OptionTemplate ??= (T item) => (builder) => | ||||
| 		{ | ||||
| 			builder.OpenElement(0, "div"); | ||||
| 			builder.SetKey(item); | ||||
| 			builder.AddContent(1, item?.ToString()); | ||||
| 			builder.CloseElement(); | ||||
| 		}; | ||||
| 
 | ||||
| 		SelectedValueTemplate ??= (T item) => (builder) => | ||||
| 		{ | ||||
| 			builder.OpenElement(0, "span"); | ||||
| 			builder.SetKey(item); | ||||
| 			builder.AddContent(1, item?.ToString()); | ||||
| 			builder.CloseElement(); | ||||
| 		}; | ||||
| 	} | ||||
| 	protected override void OnParametersSet() | ||||
| 	{ | ||||
| 		base.OnParametersSet(); | ||||
| 
 | ||||
| 		Items.CollectionChanged += CollectionChanged; | ||||
| 		SelectedItems.CollectionChanged += CollectionChanged; | ||||
| 	} | ||||
| 
 | ||||
| 	private void CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) | ||||
| 	{ | ||||
| 		if (sender == SelectedItems) | ||||
| 			SelectedItemsChanged.InvokeAsync(SelectedItems); | ||||
| 
 | ||||
| 		StateHasChanged(); | ||||
| 	} | ||||
| 
 | ||||
| 	private async Task OptionSelected(T item) | ||||
| 	{ | ||||
| 		if (AllowMultiple) | ||||
| 		{ | ||||
| 			if (SelectedItems.Contains(item)) | ||||
| 			{ | ||||
| 				SelectedItems.Remove(item); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			SelectedItems.Clear(); | ||||
| 		} | ||||
| 
 | ||||
| 		SelectedItems.Add(item); | ||||
| 	} | ||||
| 
 | ||||
| 	public async ValueTask DisposeAsync() | ||||
| 	{ | ||||
| 		Items.CollectionChanged -= CollectionChanged; | ||||
| 		SelectedItems.CollectionChanged -= CollectionChanged; | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Matija Koželj
						Matija Koželj