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