features/rewrite/dropdown #14
							
								
								
									
										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