Progress
This commit is contained in:
		
							parent
							
								
									c3b267dfc4
								
							
						
					
					
						commit
						b178bbb9b0
					
				@ -10,176 +10,127 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public partial class Dialog : UIComponent
 | 
					public partial class Dialog : UIComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   protected string ContentClass => new CssBuilder("dialog-content")
 | 
						#region Variables
 | 
				
			||||||
     .AddClass($"dialog-no-side-padding", DisableSidePadding)
 | 
						[CascadingParameter] private DialogInstance DialogInstance { get; set; }
 | 
				
			||||||
     .AddClass(ClassContent)
 | 
						[Inject] public IDialogService DialogService { get; set; }
 | 
				
			||||||
   .Build();
 | 
						private IDialogReference _reference;
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   protected string ActionClass => new CssBuilder("dialog-actions")
 | 
						#region Events
 | 
				
			||||||
     .AddClass(ClassActions)
 | 
						[Parameter]
 | 
				
			||||||
   .Build();
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
 | 
						public Action OnBackdropClick { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   [CascadingParameter] private DialogInstance DialogInstance { get; set; }
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// Raised when the inline dialog's display status changes.
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						[Parameter] public EventCallback<bool> IsVisibleChanged { get; set; }
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   [Inject] public IDialogService DialogService { get; set; }
 | 
						#region Content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// Define the dialog title as a renderfragment (overrides GlyphTitle)
 | 
						/// Define the dialog title as a renderfragment (overrides GlyphTitle)
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
   public RenderFragment TitleContent { get; set; }
 | 
						public DefaultFocus DefaultFocus { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// Define the dialog body here
 | 
						/// Define the dialog title as a renderfragment (overrides GlyphTitle)
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
   public RenderFragment DialogContent { get; set; }
 | 
						public RenderFragment TitleContent { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// Define the action buttons here
 | 
						/// Define the dialog body here
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
   public RenderFragment DialogActions { get; set; }
 | 
						public RenderFragment DialogContent { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// Default options to pass to Show(), if none are explicitly provided.
 | 
						/// Define the action buttons here
 | 
				
			||||||
   /// Typically useful on inline dialogs.
 | 
						/// </summary>
 | 
				
			||||||
   /// </summary>
 | 
						[Parameter]
 | 
				
			||||||
   [Parameter]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Misc)]  // Behavior and Appearance
 | 
						public RenderFragment DialogActions { get; set; }
 | 
				
			||||||
   public DialogOptions Options { get; set; }
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   [Parameter]
 | 
						#region Styling
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
						/// <summary>
 | 
				
			||||||
   public Action OnBackdropClick { get; set; }
 | 
						/// No padding at the sides
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						[Parameter]
 | 
				
			||||||
 | 
						[Category(CategoryTypes.Dialog.Appearance)]
 | 
				
			||||||
 | 
						public bool DisableSidePadding { get; set; }
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// CSS class that will be applied to the dialog content
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						[Parameter]
 | 
				
			||||||
 | 
						[Category(CategoryTypes.Dialog.Appearance)]
 | 
				
			||||||
 | 
						public string ClassContent { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// No padding at the sides
 | 
						/// CSS class that will be applied to the action buttons container
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Appearance)]
 | 
						[Category(CategoryTypes.Dialog.Appearance)]
 | 
				
			||||||
   public bool DisableSidePadding { get; set; }
 | 
						public string ClassActions { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// CSS class that will be applied to the dialog content
 | 
						/// CSS styles to be applied to the dialog content
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Appearance)]
 | 
						[Category(CategoryTypes.Dialog.Appearance)]
 | 
				
			||||||
   public string ClassContent { get; set; }
 | 
						public string ContentStyle { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// CSS class that will be applied to the action buttons container
 | 
						/// Bind this two-way to show and close an inlined dialog. Has no effect on opened dialogs
 | 
				
			||||||
   /// </summary>
 | 
						/// </summary>
 | 
				
			||||||
   [Parameter]
 | 
						[Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Appearance)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
   public string ClassActions { get; set; }
 | 
						public bool IsVisible
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							get => _isVisible;
 | 
				
			||||||
 | 
							set
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (_isVisible == value)
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								_isVisible = value;
 | 
				
			||||||
 | 
								IsVisibleChanged.InvokeAsync(value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						private bool _isVisible;
 | 
				
			||||||
 | 
						protected string ContentClass => new CssBuilder("dialog-content")
 | 
				
			||||||
 | 
						  .AddClass($"dialog-no-side-padding", DisableSidePadding)
 | 
				
			||||||
 | 
						  .AddClass(ClassContent)
 | 
				
			||||||
 | 
						.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						protected string ActionClass => new CssBuilder("dialog-actions")
 | 
				
			||||||
   /// CSS styles to be applied to the dialog content
 | 
						  .AddClass(ClassActions)
 | 
				
			||||||
   /// </summary>
 | 
						.Build();
 | 
				
			||||||
   [Parameter]
 | 
						#endregion
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Appearance)]
 | 
					 | 
				
			||||||
   public string ContentStyle { get; set; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						#region Behavior
 | 
				
			||||||
   /// Bind this two-way to show and close an inlined dialog. Has no effect on opened dialogs
 | 
						/// <summary>
 | 
				
			||||||
   /// </summary>
 | 
						/// Used for forwarding state changes from inlined dialog to its instance
 | 
				
			||||||
   [Parameter]
 | 
						/// </summary>
 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
						internal void ForceUpdate()
 | 
				
			||||||
   public bool IsVisible
 | 
						{
 | 
				
			||||||
   {
 | 
							StateHasChanged();
 | 
				
			||||||
      get => _isVisible;
 | 
						}
 | 
				
			||||||
      set
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         if (_isVisible == value)
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
         _isVisible = value;
 | 
					 | 
				
			||||||
         IsVisibleChanged.InvokeAsync(value);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
   private bool _isVisible;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /// <summary>
 | 
						/// <summary>
 | 
				
			||||||
   /// Raised when the inline dialog's display status changes.
 | 
						/// Default options to pass to Show(), if none are explicitly provided.
 | 
				
			||||||
   /// </summary>
 | 
						/// Typically useful on inline dialogs.
 | 
				
			||||||
   [Parameter] public EventCallback<bool> IsVisibleChanged { get; set; }
 | 
						/// </summary>
 | 
				
			||||||
 | 
						[Parameter]
 | 
				
			||||||
 | 
						[Category(CategoryTypes.Dialog.Misc)]  // Behavior and Appearance
 | 
				
			||||||
 | 
						public DialogOptions Options { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
   /// <summary>
 | 
					 | 
				
			||||||
   /// Define the dialog title as a renderfragment (overrides GlyphTitle)
 | 
					 | 
				
			||||||
   /// </summary>
 | 
					 | 
				
			||||||
   [Parameter]
 | 
					 | 
				
			||||||
   [Category(CategoryTypes.Dialog.Behavior)]
 | 
					 | 
				
			||||||
   public DefaultFocus DefaultFocus { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   private bool IsInline => DialogInstance == null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   private IDialogReference _reference;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   /// <summary>
 | 
					 | 
				
			||||||
   /// Show this inlined dialog
 | 
					 | 
				
			||||||
   /// </summary>
 | 
					 | 
				
			||||||
   /// <param name="title"></param>
 | 
					 | 
				
			||||||
   /// <param name="options"></param>
 | 
					 | 
				
			||||||
   /// <returns></returns>
 | 
					 | 
				
			||||||
   public IDialogReference Show(string title = null, DialogOptions options = null)
 | 
					 | 
				
			||||||
   {
 | 
					 | 
				
			||||||
      if (!IsInline)
 | 
					 | 
				
			||||||
         throw new InvalidOperationException("You can only show an inlined dialog.");
 | 
					 | 
				
			||||||
      if (_reference != null)
 | 
					 | 
				
			||||||
         Close();
 | 
					 | 
				
			||||||
      var parameters = new DialogParameters()
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         [nameof(AdditionalClassList)] = AdditionalClassList,
 | 
					 | 
				
			||||||
         [nameof(Tag)] = Tag,
 | 
					 | 
				
			||||||
         [nameof(TitleContent)] = TitleContent,
 | 
					 | 
				
			||||||
         [nameof(DialogContent)] = DialogContent,
 | 
					 | 
				
			||||||
         [nameof(DialogActions)] = DialogActions,
 | 
					 | 
				
			||||||
         [nameof(DisableSidePadding)] = DisableSidePadding,
 | 
					 | 
				
			||||||
         [nameof(ClassContent)] = ClassContent,
 | 
					 | 
				
			||||||
         [nameof(ClassActions)] = ClassActions,
 | 
					 | 
				
			||||||
         [nameof(ContentStyle)] = ContentStyle,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      _reference = DialogService.Show<Dialog>(title, parameters, options ?? Options);
 | 
					 | 
				
			||||||
      _reference.Result.ContinueWith(t =>
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         _isVisible = false;
 | 
					 | 
				
			||||||
         InvokeAsync(() => IsVisibleChanged.InvokeAsync(false));
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      return _reference;
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   protected override void OnAfterRender(bool firstRender)
 | 
					 | 
				
			||||||
   {
 | 
					 | 
				
			||||||
      if (IsInline)
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         if (_isVisible && _reference == null)
 | 
					 | 
				
			||||||
         {
 | 
					 | 
				
			||||||
            Show(); // if isVisible and we don't have any reference we need to call Show
 | 
					 | 
				
			||||||
         }
 | 
					 | 
				
			||||||
         else if (_reference != null)
 | 
					 | 
				
			||||||
         {
 | 
					 | 
				
			||||||
            if (IsVisible)
 | 
					 | 
				
			||||||
               (_reference.Dialog as Dialog)?.ForceUpdate(); // forward render update to instance
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
               Close(); // if we still have reference but it's not visible call Close
 | 
					 | 
				
			||||||
         }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      base.OnAfterRender(firstRender);
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   /// <summary>
 | 
					 | 
				
			||||||
   /// Used for forwarding state changes from inlined dialog to its instance
 | 
					 | 
				
			||||||
   /// </summary>
 | 
					 | 
				
			||||||
   internal void ForceUpdate()
 | 
					 | 
				
			||||||
   {
 | 
					 | 
				
			||||||
      StateHasChanged();
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   /// <summary>
 | 
					 | 
				
			||||||
   /// Close the currently open inlined dialog
 | 
					   /// Close the currently open inlined dialog
 | 
				
			||||||
   /// </summary>
 | 
					   /// </summary>
 | 
				
			||||||
   /// <param name="result"></param>
 | 
					   /// <param name="result"></param>
 | 
				
			||||||
@ -191,9 +142,69 @@ public partial class Dialog : UIComponent
 | 
				
			|||||||
      _reference = null;
 | 
					      _reference = null;
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   protected override void OnInitialized()
 | 
						private bool IsInline => DialogInstance == null;
 | 
				
			||||||
   {
 | 
					
 | 
				
			||||||
      base.OnInitialized();
 | 
						#endregion
 | 
				
			||||||
      DialogInstance?.Register(this);
 | 
					
 | 
				
			||||||
   }
 | 
						#region Lifecycle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected override void OnInitialized()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							base.OnInitialized();
 | 
				
			||||||
 | 
							DialogInstance?.Register(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// Show this inlined dialog
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <param name="title"></param>
 | 
				
			||||||
 | 
						/// <param name="options"></param>
 | 
				
			||||||
 | 
						/// <returns></returns>
 | 
				
			||||||
 | 
						public IDialogReference Show(string title = null, DialogOptions options = null)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!IsInline)
 | 
				
			||||||
 | 
								throw new InvalidOperationException("You can only show an inlined dialog.");
 | 
				
			||||||
 | 
							if (_reference != null)
 | 
				
			||||||
 | 
								Close();
 | 
				
			||||||
 | 
							var parameters = new DialogParameters()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								[nameof(AdditionalClassList)] = AdditionalClassList,
 | 
				
			||||||
 | 
								[nameof(Tag)] = Tag,
 | 
				
			||||||
 | 
								[nameof(TitleContent)] = TitleContent,
 | 
				
			||||||
 | 
								[nameof(DialogContent)] = DialogContent,
 | 
				
			||||||
 | 
								[nameof(DialogActions)] = DialogActions,
 | 
				
			||||||
 | 
								[nameof(DisableSidePadding)] = DisableSidePadding,
 | 
				
			||||||
 | 
								[nameof(ClassContent)] = ClassContent,
 | 
				
			||||||
 | 
								[nameof(ClassActions)] = ClassActions,
 | 
				
			||||||
 | 
								[nameof(ContentStyle)] = ContentStyle,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							_reference = DialogService.Show<Dialog>(title, parameters, options ?? Options);
 | 
				
			||||||
 | 
							_reference.Result.ContinueWith(t =>
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								_isVisible = false;
 | 
				
			||||||
 | 
								InvokeAsync(() => IsVisibleChanged.InvokeAsync(false));
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							return _reference;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected override void OnAfterRender(bool firstRender)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (IsInline)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (_isVisible && _reference == null)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Show(); // if isVisible and we don't have any reference we need to call Show
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (_reference != null)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (IsVisible)
 | 
				
			||||||
 | 
										(_reference.Dialog as Dialog)?.ForceUpdate(); // forward render update to instance
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										Close(); // if we still have reference but it's not visible call Close
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							base.OnAfterRender(firstRender);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,29 +12,52 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public partial class DialogInstance : UIComponent, IDisposable
 | 
					public partial class DialogInstance : UIComponent, IDisposable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						#region Variables
 | 
				
			||||||
	private DialogOptions _options = new();
 | 
						private DialogOptions _options = new();
 | 
				
			||||||
	private string _elementId = "dialog_" + Guid.NewGuid().ToString().Substring(0, 8);
 | 
						private string _elementId = "dialog_" + Guid.NewGuid().ToString().Substring(0, 8);
 | 
				
			||||||
	private IKeyInterceptor _keyInterceptor;
 | 
						private IKeyInterceptor _keyInterceptor;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	[Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; }
 | 
						[Inject] private IKeyInterceptorFactory _keyInterceptorFactory { get; set; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	[CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; }
 | 
					 | 
				
			||||||
	[CascadingParameter] private DialogProvider Parent { get; set; }
 | 
						[CascadingParameter] private DialogProvider Parent { get; set; }
 | 
				
			||||||
	[CascadingParameter] private DialogOptions GlobalDialogOptions { get; set; } = new DialogOptions();
 | 
						[CascadingParameter] private DialogOptions GlobalDialogOptions { get; set; } = new DialogOptions();
 | 
				
			||||||
 | 
						private Dialog _dialog;
 | 
				
			||||||
 | 
						private bool _disposedValue;
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[Parameter]
 | 
						#region Events
 | 
				
			||||||
	[Category(CategoryTypes.Dialog.Misc)]  // Behavior and Appearance
 | 
						private void HandleBackgroundClick()
 | 
				
			||||||
	public DialogOptions Options
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		get
 | 
							if (DisableBackdropClick)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (_dialog?.OnBackdropClick == null)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (_options == null)
 | 
								Cancel();
 | 
				
			||||||
				_options = new DialogOptions();
 | 
								return;
 | 
				
			||||||
			return _options;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		set => _options = value;
 | 
					
 | 
				
			||||||
 | 
							_dialog?.OnBackdropClick.Invoke();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// Cancels all dialogs in dialog provider collection.
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public void CancelAll()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Parent?.DismissAll();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void Register(Dialog dialog)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (dialog == null)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							_dialog = dialog;
 | 
				
			||||||
 | 
							//AdditionalClassList = dialog.AdditionalClassList;
 | 
				
			||||||
 | 
							TitleContent = dialog.TitleContent;
 | 
				
			||||||
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Content
 | 
				
			||||||
	[Parameter]
 | 
						[Parameter]
 | 
				
			||||||
	[Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
	public string Title { get; set; }
 | 
						public string Title { get; set; }
 | 
				
			||||||
@ -46,10 +69,129 @@ public partial class DialogInstance : UIComponent, IDisposable
 | 
				
			|||||||
	[Parameter]
 | 
						[Parameter]
 | 
				
			||||||
	[Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
	public RenderFragment Content { get; set; }
 | 
						public RenderFragment Content { get; set; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	[Parameter]
 | 
						[Parameter]
 | 
				
			||||||
	[Category(CategoryTypes.Dialog.Behavior)]
 | 
						[Category(CategoryTypes.Dialog.Behavior)]
 | 
				
			||||||
	public Guid Id { get; set; }
 | 
						public Guid Id { get; set; }
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Styling
 | 
				
			||||||
 | 
						public void ForceRender()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						private string SetPosition()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DialogPosition position;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (Options.Position.HasValue)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								position = Options.Position.Value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (GlobalDialogOptions.Position.HasValue)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								position = GlobalDialogOptions.Position.Value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								position = DialogPosition.Center;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return $"dialog-{position.ToDescription()}";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetHideHeader()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.NoHeader.HasValue)
 | 
				
			||||||
 | 
								return Options.NoHeader.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.NoHeader.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.NoHeader.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetCloseButton()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.CloseButton.HasValue)
 | 
				
			||||||
 | 
								return Options.CloseButton.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.CloseButton.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.CloseButton.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetDisableBackdropClick()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.DisableBackdropClick.HasValue)
 | 
				
			||||||
 | 
								return Options.DisableBackdropClick.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.DisableBackdropClick.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.DisableBackdropClick.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetCloseOnEscapeKey()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.CloseOnEscapeKey.HasValue)
 | 
				
			||||||
 | 
								return Options.CloseOnEscapeKey.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.CloseOnEscapeKey.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.CloseOnEscapeKey.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						private string SetMaxWidth()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							MaxWidth maxWidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (Options.MaxWidth.HasValue)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								maxWidth = Options.MaxWidth.Value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (GlobalDialogOptions.MaxWidth.HasValue)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								maxWidth = GlobalDialogOptions.MaxWidth.Value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								maxWidth = MaxWidth.Small;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return $"dialog-width-{maxWidth.ToDescription()}";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetFullWidth()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.FullWidth.HasValue)
 | 
				
			||||||
 | 
								return Options.FullWidth.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.FullWidth.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.FullWidth.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private bool SetFulScreen()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Options.FullScreen.HasValue)
 | 
				
			||||||
 | 
								return Options.FullScreen.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GlobalDialogOptions.FullScreen.HasValue)
 | 
				
			||||||
 | 
								return GlobalDialogOptions.FullScreen.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected string Classname =>
 | 
				
			||||||
 | 
							new CssBuilder("dialog")
 | 
				
			||||||
 | 
								.AddClass(DialogMaxWidth, !FullScreen)
 | 
				
			||||||
 | 
								.AddClass("dialog-width-full", FullWidth && !FullScreen)
 | 
				
			||||||
 | 
								.AddClass("dialog-fullscreen", FullScreen)
 | 
				
			||||||
 | 
								.AddClass("dialog-rtl", RightToLeft)
 | 
				
			||||||
 | 
								.AddClass(_dialog?.AdditionalClassList)
 | 
				
			||||||
 | 
							.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Custom close icon.
 | 
						/// Custom close icon.
 | 
				
			||||||
@ -66,35 +208,22 @@ public partial class DialogInstance : UIComponent, IDisposable
 | 
				
			|||||||
	private bool CloseButton { get; set; }
 | 
						private bool CloseButton { get; set; }
 | 
				
			||||||
	private bool FullScreen { get; set; }
 | 
						private bool FullScreen { get; set; }
 | 
				
			||||||
	private bool FullWidth { get; set; }
 | 
						private bool FullWidth { get; set; }
 | 
				
			||||||
 | 
						[CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; }
 | 
				
			||||||
 | 
						[Parameter]
 | 
				
			||||||
	protected override void OnInitialized()
 | 
						[Category(CategoryTypes.Dialog.Misc)]  // Behavior and Appearance
 | 
				
			||||||
 | 
						public DialogOptions Options
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ConfigureInstance();
 | 
							get
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protected override async Task OnAfterRenderAsync(bool firstRender)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (firstRender)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			//Since CloseOnEscapeKey is the only thing to be handled, turn interceptor off
 | 
								if (_options == null)
 | 
				
			||||||
			if (CloseOnEscapeKey)
 | 
									_options = new DialogOptions();
 | 
				
			||||||
			{
 | 
								return _options;
 | 
				
			||||||
				_keyInterceptor = _keyInterceptorFactory.Create();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions()
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					TargetClass = "dialog",
 | 
					 | 
				
			||||||
					Keys = {
 | 
					 | 
				
			||||||
						 new KeyOptions { Key="Escape", SubscribeDown = true },
 | 
					 | 
				
			||||||
					 },
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
				_keyInterceptor.KeyDown += HandleKeyDown;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		await base.OnAfterRenderAsync(firstRender);
 | 
							set => _options = value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Behavior
 | 
				
			||||||
	internal void HandleKeyDown(KeyboardEventArgs args)
 | 
						internal void HandleKeyDown(KeyboardEventArgs args)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		switch (args.Key)
 | 
							switch (args.Key)
 | 
				
			||||||
@ -175,157 +304,34 @@ public partial class DialogInstance : UIComponent, IDisposable
 | 
				
			|||||||
		//AdditionalClassList = Classname;
 | 
							//AdditionalClassList = Classname;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private string SetPosition()
 | 
						#endregion
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		DialogPosition position;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (Options.Position.HasValue)
 | 
						#region Lifecycle
 | 
				
			||||||
 | 
						protected override void OnInitialized()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ConfigureInstance();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected override async Task OnAfterRenderAsync(bool firstRender)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (firstRender)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			position = Options.Position.Value;
 | 
								//Since CloseOnEscapeKey is the only thing to be handled, turn interceptor off
 | 
				
			||||||
 | 
								if (CloseOnEscapeKey)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									_keyInterceptor = _keyInterceptorFactory.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									await _keyInterceptor.Connect(_elementId, new KeyInterceptorOptions()
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										TargetClass = "dialog",
 | 
				
			||||||
 | 
										Keys = {
 | 
				
			||||||
 | 
											 new KeyOptions { Key="Escape", SubscribeDown = true },
 | 
				
			||||||
 | 
										 },
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
									_keyInterceptor.KeyDown += HandleKeyDown;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (GlobalDialogOptions.Position.HasValue)
 | 
							await base.OnAfterRenderAsync(firstRender);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			position = GlobalDialogOptions.Position.Value;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			position = DialogPosition.Center;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return $"dialog-{position.ToDescription()}";
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private string SetMaxWidth()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		MaxWidth maxWidth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (Options.MaxWidth.HasValue)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			maxWidth = Options.MaxWidth.Value;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else if (GlobalDialogOptions.MaxWidth.HasValue)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			maxWidth = GlobalDialogOptions.MaxWidth.Value;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			maxWidth = MaxWidth.Small;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return $"dialog-width-{maxWidth.ToDescription()}";
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetFullWidth()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.FullWidth.HasValue)
 | 
					 | 
				
			||||||
			return Options.FullWidth.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.FullWidth.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.FullWidth.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetFulScreen()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.FullScreen.HasValue)
 | 
					 | 
				
			||||||
			return Options.FullScreen.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.FullScreen.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.FullScreen.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protected string Classname =>
 | 
					 | 
				
			||||||
		new CssBuilder("dialog")
 | 
					 | 
				
			||||||
			.AddClass(DialogMaxWidth, !FullScreen)
 | 
					 | 
				
			||||||
			.AddClass("dialog-width-full", FullWidth && !FullScreen)
 | 
					 | 
				
			||||||
			.AddClass("dialog-fullscreen", FullScreen)
 | 
					 | 
				
			||||||
			.AddClass("dialog-rtl", RightToLeft)
 | 
					 | 
				
			||||||
			.AddClass(_dialog?.AdditionalClassList)
 | 
					 | 
				
			||||||
		.Build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetHideHeader()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.NoHeader.HasValue)
 | 
					 | 
				
			||||||
			return Options.NoHeader.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.NoHeader.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.NoHeader.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetCloseButton()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.CloseButton.HasValue)
 | 
					 | 
				
			||||||
			return Options.CloseButton.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.CloseButton.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.CloseButton.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetDisableBackdropClick()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.DisableBackdropClick.HasValue)
 | 
					 | 
				
			||||||
			return Options.DisableBackdropClick.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.DisableBackdropClick.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.DisableBackdropClick.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private bool SetCloseOnEscapeKey()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Options.CloseOnEscapeKey.HasValue)
 | 
					 | 
				
			||||||
			return Options.CloseOnEscapeKey.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (GlobalDialogOptions.CloseOnEscapeKey.HasValue)
 | 
					 | 
				
			||||||
			return GlobalDialogOptions.CloseOnEscapeKey.Value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void HandleBackgroundClick()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (DisableBackdropClick)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (_dialog?.OnBackdropClick == null)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Cancel();
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		_dialog?.OnBackdropClick.Invoke();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Dialog _dialog;
 | 
					 | 
				
			||||||
	private bool _disposedValue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void Register(Dialog dialog)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (dialog == null)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		_dialog = dialog;
 | 
					 | 
				
			||||||
		//AdditionalClassList = dialog.AdditionalClassList;
 | 
					 | 
				
			||||||
		TitleContent = dialog.TitleContent;
 | 
					 | 
				
			||||||
		StateHasChanged();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void ForceRender()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		StateHasChanged();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Cancels all dialogs in dialog provider collection.
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public void CancelAll()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Parent?.DismissAll();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected virtual void Dispose(bool disposing)
 | 
						protected virtual void Dispose(bool disposing)
 | 
				
			||||||
@ -350,4 +356,6 @@ public partial class DialogInstance : UIComponent, IDisposable
 | 
				
			|||||||
		Dispose(disposing: true);
 | 
							Dispose(disposing: true);
 | 
				
			||||||
		GC.SuppressFinalize(this);
 | 
							GC.SuppressFinalize(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,94 +15,101 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public partial class DialogProvider : IDisposable
 | 
					public partial class DialogProvider : IDisposable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   [Inject] private IDialogService DialogService { get; set; }
 | 
					 | 
				
			||||||
   [Inject] private NavigationManager NavigationManager { get; set; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? NoHeader { get; set; }
 | 
						#region Variables
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseButton { get; set; }
 | 
						[Inject] private IDialogService DialogService { get; set; }
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? DisableBackdropClick { get; set; }
 | 
						[Inject] private NavigationManager NavigationManager { get; set; }
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseOnEscapeKey { get; set; }
 | 
						[Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? NoHeader { get; set; }
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Appearance)] public bool? FullWidth { get; set; }
 | 
						[Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseButton { get; set; }
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Appearance)] public DialogPosition? Position { get; set; }
 | 
						[Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? DisableBackdropClick { get; set; }
 | 
				
			||||||
   [Parameter][Category(CategoryTypes.Dialog.Appearance)] public MaxWidth? MaxWidth { get; set; }
 | 
						[Parameter][Category(CategoryTypes.Dialog.Behavior)] public bool? CloseOnEscapeKey { get; set; }
 | 
				
			||||||
 | 
						[Parameter][Category(CategoryTypes.Dialog.Appearance)] public bool? FullWidth { get; set; }
 | 
				
			||||||
 | 
						[Parameter][Category(CategoryTypes.Dialog.Appearance)] public DialogPosition? Position { get; set; }
 | 
				
			||||||
 | 
						[Parameter][Category(CategoryTypes.Dialog.Appearance)] public MaxWidth? MaxWidth { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private readonly Collection<IDialogReference> _dialogs = new();
 | 
						private readonly Collection<IDialogReference> _dialogs = new();
 | 
				
			||||||
   private readonly DialogOptions _globalDialogOptions = new();
 | 
						private readonly DialogOptions _globalDialogOptions = new();
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   protected override void OnInitialized()
 | 
						#region Events
 | 
				
			||||||
   {
 | 
						private void AddInstance(IDialogReference dialog)
 | 
				
			||||||
      DialogService.OnDialogInstanceAdded += AddInstance;
 | 
						{
 | 
				
			||||||
      DialogService.OnDialogCloseRequested += DismissInstance;
 | 
							_dialogs.Add(dialog);
 | 
				
			||||||
      NavigationManager.LocationChanged += LocationChanged;
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						internal void DismissInstance(Guid id, DialogResult result)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							var reference = GetDialogReference(id);
 | 
				
			||||||
 | 
							if (reference != null)
 | 
				
			||||||
 | 
								DismissInstance(reference, result);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      _globalDialogOptions.DisableBackdropClick = DisableBackdropClick;
 | 
						public void DismissAll()
 | 
				
			||||||
      _globalDialogOptions.CloseOnEscapeKey = CloseOnEscapeKey;
 | 
						{
 | 
				
			||||||
      _globalDialogOptions.CloseButton = CloseButton;
 | 
							_dialogs.ToList().ForEach(r => DismissInstance(r, DialogResult.Cancel()));
 | 
				
			||||||
      _globalDialogOptions.NoHeader = NoHeader;
 | 
							StateHasChanged();
 | 
				
			||||||
      _globalDialogOptions.Position = Position;
 | 
						}
 | 
				
			||||||
      _globalDialogOptions.FullWidth = FullWidth;
 | 
					 | 
				
			||||||
      _globalDialogOptions.MaxWidth = MaxWidth;
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   protected override Task OnAfterRenderAsync(bool firstRender)
 | 
						private void DismissInstance(IDialogReference dialog, DialogResult result)
 | 
				
			||||||
   {
 | 
						{
 | 
				
			||||||
      if (!firstRender)
 | 
							if (!dialog.Dismiss(result)) return;
 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         foreach (var dialogReference in _dialogs.Where(x => !x.Result.IsCompleted))
 | 
					 | 
				
			||||||
         {
 | 
					 | 
				
			||||||
            dialogReference.RenderCompleteTaskCompletionSource.TrySetResult(true);
 | 
					 | 
				
			||||||
         }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return base.OnAfterRenderAsync(firstRender);
 | 
							_dialogs.Remove(dialog);
 | 
				
			||||||
   }
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   internal void DismissInstance(Guid id, DialogResult result)
 | 
						private IDialogReference GetDialogReference(Guid id)
 | 
				
			||||||
   {
 | 
						{
 | 
				
			||||||
      var reference = GetDialogReference(id);
 | 
							return _dialogs.SingleOrDefault(x => x.Id == id);
 | 
				
			||||||
      if (reference != null)
 | 
						}
 | 
				
			||||||
         DismissInstance(reference, result);
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private void AddInstance(IDialogReference dialog)
 | 
						private void LocationChanged(object sender, LocationChangedEventArgs args)
 | 
				
			||||||
   {
 | 
						{
 | 
				
			||||||
      _dialogs.Add(dialog);
 | 
							DismissAll();
 | 
				
			||||||
      StateHasChanged();
 | 
						}
 | 
				
			||||||
   }
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   public void DismissAll()
 | 
						#region Lifecycle
 | 
				
			||||||
   {
 | 
						protected override void OnInitialized()
 | 
				
			||||||
      _dialogs.ToList().ForEach(r => DismissInstance(r, DialogResult.Cancel()));
 | 
						{
 | 
				
			||||||
      StateHasChanged();
 | 
							DialogService.OnDialogInstanceAdded += AddInstance;
 | 
				
			||||||
   }
 | 
							DialogService.OnDialogCloseRequested += DismissInstance;
 | 
				
			||||||
 | 
							NavigationManager.LocationChanged += LocationChanged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private void DismissInstance(IDialogReference dialog, DialogResult result)
 | 
							_globalDialogOptions.DisableBackdropClick = DisableBackdropClick;
 | 
				
			||||||
   {
 | 
							_globalDialogOptions.CloseOnEscapeKey = CloseOnEscapeKey;
 | 
				
			||||||
      if (!dialog.Dismiss(result)) return;
 | 
							_globalDialogOptions.CloseButton = CloseButton;
 | 
				
			||||||
 | 
							_globalDialogOptions.NoHeader = NoHeader;
 | 
				
			||||||
 | 
							_globalDialogOptions.Position = Position;
 | 
				
			||||||
 | 
							_globalDialogOptions.FullWidth = FullWidth;
 | 
				
			||||||
 | 
							_globalDialogOptions.MaxWidth = MaxWidth;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      _dialogs.Remove(dialog);
 | 
						protected override Task OnAfterRenderAsync(bool firstRender)
 | 
				
			||||||
      StateHasChanged();
 | 
						{
 | 
				
			||||||
   }
 | 
							if (!firstRender)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								foreach (var dialogReference in _dialogs.Where(x => !x.Result.IsCompleted))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									dialogReference.RenderCompleteTaskCompletionSource.TrySetResult(true);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private IDialogReference GetDialogReference(Guid id)
 | 
							return base.OnAfterRenderAsync(firstRender);
 | 
				
			||||||
   {
 | 
						}
 | 
				
			||||||
      return _dialogs.SingleOrDefault(x => x.Id == id);
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private void LocationChanged(object sender, LocationChangedEventArgs args)
 | 
						public void Dispose()
 | 
				
			||||||
   {
 | 
						{
 | 
				
			||||||
      DismissAll();
 | 
							if (NavigationManager != null)
 | 
				
			||||||
   }
 | 
								NavigationManager.LocationChanged -= LocationChanged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   public void Dispose()
 | 
							if (DialogService != null)
 | 
				
			||||||
   {
 | 
							{
 | 
				
			||||||
      if (NavigationManager != null)
 | 
								DialogService.OnDialogInstanceAdded -= AddInstance;
 | 
				
			||||||
         NavigationManager.LocationChanged -= LocationChanged;
 | 
								DialogService.OnDialogCloseRequested -= DismissInstance;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
      if (DialogService != null)
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
         DialogService.OnDialogInstanceAdded -= AddInstance;
 | 
					 | 
				
			||||||
         DialogService.OnDialogCloseRequested -= DismissInstance;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,8 @@ using Microsoft.AspNetCore.Components;
 | 
				
			|||||||
namespace Connected.Components;
 | 
					namespace Connected.Components;
 | 
				
			||||||
public partial class Divider : UIComponent
 | 
					public partial class Divider : UIComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   protected string Classname =>
 | 
						#region Styling
 | 
				
			||||||
 | 
						protected string Classname =>
 | 
				
			||||||
   new CssBuilder("divider")
 | 
					   new CssBuilder("divider")
 | 
				
			||||||
     .AddClass($"divider-absolute", Absolute)
 | 
					     .AddClass($"divider-absolute", Absolute)
 | 
				
			||||||
     .AddClass($"divider-flexitem", FlexItem)
 | 
					     .AddClass($"divider-flexitem", FlexItem)
 | 
				
			||||||
@ -50,4 +51,6 @@ public partial class Divider : UIComponent
 | 
				
			|||||||
   [Parameter]
 | 
					   [Parameter]
 | 
				
			||||||
   [Category(CategoryTypes.Divider.Appearance)]
 | 
					   [Category(CategoryTypes.Divider.Appearance)]
 | 
				
			||||||
   public DividerType DividerType { get; set; } = DividerType.FullWidth;
 | 
					   public DividerType DividerType { get; set; } = DividerType.FullWidth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
 | 
					public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						#region Variables
 | 
				
			||||||
	private double _height;
 | 
						private double _height;
 | 
				
			||||||
	private ElementReference _contentRef;
 | 
						private ElementReference _contentRef;
 | 
				
			||||||
	private DrawerClipMode _clipMode;
 | 
						private DrawerClipMode _clipMode;
 | 
				
			||||||
@ -21,8 +22,16 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
 | 
				
			|||||||
	private Breakpoint _screenBreakpoint = Breakpoint.None;
 | 
						private Breakpoint _screenBreakpoint = Breakpoint.None;
 | 
				
			||||||
	private Guid _breakpointListenerSubscriptionId;
 | 
						private Guid _breakpointListenerSubscriptionId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region EventCallbacks
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Events
 | 
				
			||||||
 | 
						private void CloseDrawer()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Open)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								OpenChanged.InvokeAsync(false);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[Parameter] public EventCallback<bool> OpenChanged { get; set; }
 | 
						[Parameter] public EventCallback<bool> OpenChanged { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -351,13 +360,7 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
 | 
				
			|||||||
			OpenChanged.InvokeAsync(_open);
 | 
								OpenChanged.InvokeAsync(_open);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	private void CloseDrawer()
 | 
						
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Open)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			OpenChanged.InvokeAsync(false);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// Width of left/right drawer. Only for non-fixed drawers.
 | 
						/// Width of left/right drawer. Only for non-fixed drawers.
 | 
				
			||||||
 | 
				
			|||||||
@ -6,16 +6,33 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public partial class DrawerContainer : UIComponent
 | 
					public partial class DrawerContainer : UIComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						#region Variables
 | 
				
			||||||
	protected bool Fixed { get; set; } = false;
 | 
						protected bool Fixed { get; set; } = false;
 | 
				
			||||||
	private List<Drawer> _drawers = new();
 | 
						private List<Drawer> _drawers = new();
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region Event callbacks
 | 
						#region Events
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	internal void FireDrawersChanged() => StateHasChanged();
 | 
						internal void FireDrawersChanged() => StateHasChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						internal void Add(Drawer drawer)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (Fixed && !drawer.Fixed)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_drawers.Add(drawer);
 | 
				
			||||||
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						internal void Remove(Drawer drawer)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							_drawers.Remove(drawer);
 | 
				
			||||||
 | 
							StateHasChanged();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#endregion
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region Content placeholders
 | 
						#region Content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; }
 | 
						[CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,7 +100,7 @@ public partial class DrawerContainer : UIComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#endregion
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region Styling properties
 | 
						#region Styling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected virtual CssBuilder CompiledClassList
 | 
						protected virtual CssBuilder CompiledClassList
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -142,18 +159,5 @@ public partial class DrawerContainer : UIComponent
 | 
				
			|||||||
	#endregion
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	internal void Add(Drawer drawer)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (Fixed && !drawer.Fixed)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		_drawers.Add(drawer);
 | 
					 | 
				
			||||||
		StateHasChanged();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	internal void Remove(Drawer drawer)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		_drawers.Remove(drawer);
 | 
					 | 
				
			||||||
		StateHasChanged();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,10 +4,8 @@ using Microsoft.AspNetCore.Components;
 | 
				
			|||||||
namespace Connected.Components;
 | 
					namespace Connected.Components;
 | 
				
			||||||
public partial class DrawerHeader : UIComponent
 | 
					public partial class DrawerHeader : UIComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	#region Event callbacks
 | 
					 | 
				
			||||||
	#endregion
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region Content placeholders
 | 
						#region Content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// If true, compact padding will be used, same as the Appbar.
 | 
						/// If true, compact padding will be used, same as the Appbar.
 | 
				
			||||||
@ -29,7 +27,7 @@ public partial class DrawerHeader : UIComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	#endregion
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#region Styling properties
 | 
						#region Styling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A space separated list of class names, added on top of the default class list.
 | 
						/// A space separated list of class names, added on top of the default class list.
 | 
				
			||||||
@ -37,11 +35,13 @@ public partial class DrawerHeader : UIComponent
 | 
				
			|||||||
	[Parameter]
 | 
						[Parameter]
 | 
				
			||||||
	public string? ClassList { get; set; }
 | 
						public string? ClassList { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// A space separated list of class names, added on top of the default class list.
 | 
						/// A space separated list of class names, added on top of the default class list.
 | 
				
			||||||
	/// </summary>
 | 
						/// </summary>
 | 
				
			||||||
	[Parameter]
 | 
						[Parameter]
 | 
				
			||||||
	public string? StyleList { get; set; }
 | 
						public string? StyleList { get; set; }
 | 
				
			||||||
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected virtual CssBuilder CompiledClassList
 | 
						protected virtual CssBuilder CompiledClassList
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -56,5 +56,4 @@ public partial class DrawerHeader : UIComponent
 | 
				
			|||||||
	#endregion
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,13 @@ namespace Connected.Components;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public class DragAndDropIndexChangedEventArgs : EventArgs
 | 
					public class DragAndDropIndexChangedEventArgs : EventArgs
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						#region Variables
 | 
				
			||||||
 | 
						public string ZoneIdentifier { get; }
 | 
				
			||||||
 | 
						public int Index { get; }
 | 
				
			||||||
 | 
						public string OldZoneIdentifier { get; }
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Events
 | 
				
			||||||
	public DragAndDropIndexChangedEventArgs(string zoneIdentifier, string oldZoneIdentifier, int index)
 | 
						public DragAndDropIndexChangedEventArgs(string zoneIdentifier, string oldZoneIdentifier, int index)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ZoneIdentifier = zoneIdentifier;
 | 
							ZoneIdentifier = zoneIdentifier;
 | 
				
			||||||
@ -17,41 +24,17 @@ public class DragAndDropIndexChangedEventArgs : EventArgs
 | 
				
			|||||||
		OldZoneIdentifier = oldZoneIdentifier;
 | 
							OldZoneIdentifier = oldZoneIdentifier;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public string ZoneIdentifier { get; }
 | 
						#endregion
 | 
				
			||||||
	public int Index { get; }
 | 
					 | 
				
			||||||
	public string OldZoneIdentifier { get; }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// <summary>
 | 
					 | 
				
			||||||
/// Used to encapsulate data for a drag and drop transaction
 | 
					 | 
				
			||||||
/// </summary>
 | 
					 | 
				
			||||||
/// <typeparam name="T"></typeparam>
 | 
					 | 
				
			||||||
public class DragAndDropItemTransaction<T>
 | 
					public class DragAndDropItemTransaction<T>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						#region Variables
 | 
				
			||||||
	private Func<Task> _commitCallback;
 | 
						private Func<Task> _commitCallback;
 | 
				
			||||||
	private Func<Task> _cancelCallback;
 | 
						private Func<Task> _cancelCallback;
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						#region Events
 | 
				
			||||||
	/// The Item that is dragged during the transaction
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public T Item { get; init; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The index of the item in the current drop zone
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public int Index { get; private set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The index of the item when the transaction started
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public int SourceIndex { get; private set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Identifier for drop zone where the transaction started
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	public string SourceZoneIdentifier { get; init; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public string CurrentZone { get; private set; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
						/// <summary>
 | 
				
			||||||
	/// create a new instance of a drag and drop transaction encapsulating the item and source
 | 
						/// create a new instance of a drag and drop transaction encapsulating the item and source
 | 
				
			||||||
@ -101,8 +84,53 @@ public class DragAndDropItemTransaction<T>
 | 
				
			|||||||
		Index = -1;
 | 
							Index = -1;
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// The Item that is dragged during the transaction
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public T Item { get; init; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// The index of the item in the current drop zone
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public int Index { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// The index of the item when the transaction started
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public int SourceIndex { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// Identifier for drop zone where the transaction started
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						public string SourceZoneIdentifier { get; init; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public string CurrentZone { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Styling
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Behavior
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#region Lifecycle
 | 
				
			||||||
 | 
						#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Used to encapsulate data for a drag and drop transaction
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <typeparam name="T"></typeparam>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
/// Record encaplusalting data regaring a completed transaction
 | 
					/// Record encaplusalting data regaring a completed transaction
 | 
				
			||||||
/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
@ -112,237 +140,237 @@ public class DragAndDropItemTransaction<T>
 | 
				
			|||||||
/// <param name="IndexInZone">The index of the item within in the dropzone</param>
 | 
					/// <param name="IndexInZone">The index of the item within in the dropzone</param>
 | 
				
			||||||
public record ItemDropInfo<T>(T Item, string DropzoneIdentifier, int IndexInZone);
 | 
					public record ItemDropInfo<T>(T Item, string DropzoneIdentifier, int IndexInZone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class DragAndDropTransactionFinishedEventArgs<T> : EventArgs
 | 
						public class DragAndDropTransactionFinishedEventArgs<T> : EventArgs
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	public DragAndDropTransactionFinishedEventArgs(DragAndDropItemTransaction<T> transaction) :
 | 
					 | 
				
			||||||
		this(string.Empty, false, transaction)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							public DragAndDropTransactionFinishedEventArgs(DragAndDropItemTransaction<T> transaction) :
 | 
				
			||||||
	}
 | 
								this(string.Empty, false, transaction)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	public DragAndDropTransactionFinishedEventArgs(string destinationDropzoneIdentifier, bool success, DragAndDropItemTransaction<T> transaction)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Item = transaction.Item;
 | 
					 | 
				
			||||||
		Success = success;
 | 
					 | 
				
			||||||
		OriginatedDropzoneIdentifier = transaction.SourceZoneIdentifier;
 | 
					 | 
				
			||||||
		DestinationDropzoneIdentifier = destinationDropzoneIdentifier;
 | 
					 | 
				
			||||||
		OriginIndex = transaction.SourceIndex;
 | 
					 | 
				
			||||||
		DestinationIndex = transaction.Index;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public T Item { get; }
 | 
					 | 
				
			||||||
	public bool Success { get; }
 | 
					 | 
				
			||||||
	public string OriginatedDropzoneIdentifier { get; }
 | 
					 | 
				
			||||||
	public string DestinationDropzoneIdentifier { get; }
 | 
					 | 
				
			||||||
	public int OriginIndex { get; }
 | 
					 | 
				
			||||||
	public int DestinationIndex { get; }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// <summary>
 | 
					 | 
				
			||||||
/// The container of a drag and drop zones
 | 
					 | 
				
			||||||
/// </summary>
 | 
					 | 
				
			||||||
/// <typeparam name="T">Datetype of items</typeparam>
 | 
					 | 
				
			||||||
public partial class DropContainer<T> : UIComponent
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	private DragAndDropItemTransaction<T> _transaction;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	protected string Classname =>
 | 
					 | 
				
			||||||
	new CssBuilder("drop-container")
 | 
					 | 
				
			||||||
		.AddClass(AdditionalClassList)
 | 
					 | 
				
			||||||
		.Build();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Child content of component. This should include the drop zones
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Appearance)]
 | 
					 | 
				
			||||||
	public RenderFragment ChildContent { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The items that can be drag and dropped within the container
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Items)]
 | 
					 | 
				
			||||||
	public IEnumerable<T> Items { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The render fragment (template) that should be used to render the items within a drop zone
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Items)]
 | 
					 | 
				
			||||||
	public RenderFragment<T> ItemRenderer { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The method is used to determinate if an item can be dropped within a drop zone
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Items)]
 | 
					 | 
				
			||||||
	public Func<T, string, bool> ItemsSelector { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// Callback that indicates that an item has been dropped on a drop zone. Should be used to update the "status" of the data item
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Items)]
 | 
					 | 
				
			||||||
	public EventCallback<ItemDropInfo<T>> ItemDropped { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The method is used to determinate if an item can be dropped within a drop zone
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DropRules)]
 | 
					 | 
				
			||||||
	public Func<T, string, bool> CanDrop { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The CSS class(es), that is applied to drop zones that are a valid target for drag and drop transaction
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DropRules)]
 | 
					 | 
				
			||||||
	public string CanDropClass { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The CSS class(es), that is applied to drop zones that are NOT valid target for drag and drop transaction
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DropRules)]
 | 
					 | 
				
			||||||
	public string NoDropClass { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// If true, drop classes CanDropClass <see cref="CanDropClass"/>  or NoDropClass <see cref="NoDropClass"/> or applied as soon, as a transaction has started
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DropRules)]
 | 
					 | 
				
			||||||
	public bool ApplyDropClassesOnDragStarted { get; set; } = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// The method is used to determinate if an item should be disabled for dragging. Defaults to allow all items
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Disabled)]
 | 
					 | 
				
			||||||
	public Func<T, bool> ItemIsDisabled { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// If a drop item is disabled (determinate by <see cref="ItemIsDisabled"/>). This class is applied to the element
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.Disabled)]
 | 
					 | 
				
			||||||
	public string DisabledClass { get; set; } = "disabled";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An additional class that is applied to the drop zone where a drag operation started
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DraggingClass)]
 | 
					 | 
				
			||||||
	public string DraggingClass { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// <summary>
 | 
					 | 
				
			||||||
	/// An additional class that is applied to an drop item, when it is dragged
 | 
					 | 
				
			||||||
	/// </summary>
 | 
					 | 
				
			||||||
	[Parameter]
 | 
					 | 
				
			||||||
	[Category(CategoryTypes.DropZone.DraggingClass)]
 | 
					 | 
				
			||||||
	public string ItemDraggingClass { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public event EventHandler<DragAndDropItemTransaction<T>> TransactionStarted;
 | 
					 | 
				
			||||||
	public event EventHandler<DragAndDropIndexChangedEventArgs> TransactionIndexChanged;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public event EventHandler<DragAndDropTransactionFinishedEventArgs<T>> TransactionEnded;
 | 
					 | 
				
			||||||
	public event EventHandler RefreshRequested;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public void StartTransaction(T item, string identifier, int index, Func<Task> commitCallback, Func<Task> cancelCallback)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		_transaction = new DragAndDropItemTransaction<T>(item, identifier, index, commitCallback, cancelCallback);
 | 
					 | 
				
			||||||
		TransactionStarted?.Invoke(this, _transaction);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public T GetTransactionItem() => _transaction.Item;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public bool TransactionInProgress() => _transaction != null;
 | 
					 | 
				
			||||||
	public string GetTransactionOrignZoneIdentiifer() => _transaction?.SourceZoneIdentifier ?? string.Empty;
 | 
					 | 
				
			||||||
	public string GetTransactionCurrentZoneIdentiifer() => _transaction?.CurrentZone ?? string.Empty;
 | 
					 | 
				
			||||||
	public bool IsTransactionOriginatedFromInside(string identifier) => _transaction.SourceZoneIdentifier == identifier;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	public int GetTransactionIndex() => _transaction?.Index ?? -1;
 | 
					 | 
				
			||||||
	public bool IsItemMovedDownwards() => _transaction.Index > _transaction.SourceIndex;
 | 
					 | 
				
			||||||
	public bool HasTransactionIndexChanged()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (_transaction == null)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return false;
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (_transaction.CurrentZone != _transaction.SourceZoneIdentifier)
 | 
							public DragAndDropTransactionFinishedEventArgs(string destinationDropzoneIdentifier, bool success, DragAndDropItemTransaction<T> transaction)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return true;
 | 
								Item = transaction.Item;
 | 
				
			||||||
 | 
								Success = success;
 | 
				
			||||||
 | 
								OriginatedDropzoneIdentifier = transaction.SourceZoneIdentifier;
 | 
				
			||||||
 | 
								DestinationDropzoneIdentifier = destinationDropzoneIdentifier;
 | 
				
			||||||
 | 
								OriginIndex = transaction.SourceIndex;
 | 
				
			||||||
 | 
								DestinationIndex = transaction.Index;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return _transaction.Index != _transaction.SourceIndex;
 | 
							public T Item { get; }
 | 
				
			||||||
 | 
							public bool Success { get; }
 | 
				
			||||||
 | 
							public string OriginatedDropzoneIdentifier { get; }
 | 
				
			||||||
 | 
							public string DestinationDropzoneIdentifier { get; }
 | 
				
			||||||
 | 
							public int OriginIndex { get; }
 | 
				
			||||||
 | 
							public int DestinationIndex { get; }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public bool IsOrign(int index, string identifier)
 | 
					
 | 
				
			||||||
 | 
						/// <summary>
 | 
				
			||||||
 | 
						/// The container of a drag and drop zones
 | 
				
			||||||
 | 
						/// </summary>
 | 
				
			||||||
 | 
						/// <typeparam name="T">Datetype of items</typeparam>
 | 
				
			||||||
 | 
						public partial class DropContainer<T> : UIComponent
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (_transaction == null)
 | 
							private DragAndDropItemTransaction<T> _transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							protected string Classname =>
 | 
				
			||||||
 | 
							new CssBuilder("drop-container")
 | 
				
			||||||
 | 
								.AddClass(AdditionalClassList)
 | 
				
			||||||
 | 
								.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Child content of component. This should include the drop zones
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Appearance)]
 | 
				
			||||||
 | 
							public RenderFragment ChildContent { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The items that can be drag and dropped within the container
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Items)]
 | 
				
			||||||
 | 
							public IEnumerable<T> Items { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The render fragment (template) that should be used to render the items within a drop zone
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Items)]
 | 
				
			||||||
 | 
							public RenderFragment<T> ItemRenderer { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The method is used to determinate if an item can be dropped within a drop zone
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Items)]
 | 
				
			||||||
 | 
							public Func<T, string, bool> ItemsSelector { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Callback that indicates that an item has been dropped on a drop zone. Should be used to update the "status" of the data item
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Items)]
 | 
				
			||||||
 | 
							public EventCallback<ItemDropInfo<T>> ItemDropped { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The method is used to determinate if an item can be dropped within a drop zone
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DropRules)]
 | 
				
			||||||
 | 
							public Func<T, string, bool> CanDrop { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The CSS class(es), that is applied to drop zones that are a valid target for drag and drop transaction
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DropRules)]
 | 
				
			||||||
 | 
							public string CanDropClass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The CSS class(es), that is applied to drop zones that are NOT valid target for drag and drop transaction
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DropRules)]
 | 
				
			||||||
 | 
							public string NoDropClass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// If true, drop classes CanDropClass <see cref="CanDropClass"/>  or NoDropClass <see cref="NoDropClass"/> or applied as soon, as a transaction has started
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DropRules)]
 | 
				
			||||||
 | 
							public bool ApplyDropClassesOnDragStarted { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The method is used to determinate if an item should be disabled for dragging. Defaults to allow all items
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Disabled)]
 | 
				
			||||||
 | 
							public Func<T, bool> ItemIsDisabled { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// If a drop item is disabled (determinate by <see cref="ItemIsDisabled"/>). This class is applied to the element
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.Disabled)]
 | 
				
			||||||
 | 
							public string DisabledClass { get; set; } = "disabled";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// An additional class that is applied to the drop zone where a drag operation started
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DraggingClass)]
 | 
				
			||||||
 | 
							public string DraggingClass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// An additional class that is applied to an drop item, when it is dragged
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							[Parameter]
 | 
				
			||||||
 | 
							[Category(CategoryTypes.DropZone.DraggingClass)]
 | 
				
			||||||
 | 
							public string ItemDraggingClass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public event EventHandler<DragAndDropItemTransaction<T>> TransactionStarted;
 | 
				
			||||||
 | 
							public event EventHandler<DragAndDropIndexChangedEventArgs> TransactionIndexChanged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public event EventHandler<DragAndDropTransactionFinishedEventArgs<T>> TransactionEnded;
 | 
				
			||||||
 | 
							public event EventHandler RefreshRequested;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void StartTransaction(T item, string identifier, int index, Func<Task> commitCallback, Func<Task> cancelCallback)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return false;
 | 
								_transaction = new DragAndDropItemTransaction<T>(item, identifier, index, commitCallback, cancelCallback);
 | 
				
			||||||
 | 
								TransactionStarted?.Invoke(this, _transaction);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (identifier != _transaction.SourceZoneIdentifier)
 | 
							public T GetTransactionItem() => _transaction.Item;
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return _transaction.SourceIndex == index || _transaction.SourceIndex - 1 == index;
 | 
							public bool TransactionInProgress() => _transaction != null;
 | 
				
			||||||
	}
 | 
							public string GetTransactionOrignZoneIdentiifer() => _transaction?.SourceZoneIdentifier ?? string.Empty;
 | 
				
			||||||
 | 
							public string GetTransactionCurrentZoneIdentiifer() => _transaction?.CurrentZone ?? string.Empty;
 | 
				
			||||||
 | 
							public bool IsTransactionOriginatedFromInside(string identifier) => _transaction.SourceZoneIdentifier == identifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public async Task CommitTransaction(string dropzoneIdentifier, bool reorderIsAllowed)
 | 
							public int GetTransactionIndex() => _transaction?.Index ?? -1;
 | 
				
			||||||
	{
 | 
							public bool IsItemMovedDownwards() => _transaction.Index > _transaction.SourceIndex;
 | 
				
			||||||
		await _transaction.Commit();
 | 
							public bool HasTransactionIndexChanged()
 | 
				
			||||||
		var index = -1;
 | 
					 | 
				
			||||||
		if (reorderIsAllowed == true)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			index = GetTransactionIndex() + 1;
 | 
								if (_transaction == null)
 | 
				
			||||||
			if (_transaction.SourceZoneIdentifier == _transaction.CurrentZone && IsItemMovedDownwards() == true)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				index -= 1;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (_transaction.CurrentZone != _transaction.SourceZoneIdentifier)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return _transaction.Index != _transaction.SourceIndex;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		await ItemDropped.InvokeAsync(new ItemDropInfo<T>(_transaction.Item, dropzoneIdentifier, index));
 | 
							public bool IsOrign(int index, string identifier)
 | 
				
			||||||
		var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs<T>(dropzoneIdentifier, true, _transaction);
 | 
							{
 | 
				
			||||||
		_transaction = null;
 | 
								if (_transaction == null)
 | 
				
			||||||
		TransactionEnded?.Invoke(this, transactionFinishedEventArgs);
 | 
								{
 | 
				
			||||||
	}
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public async Task CancelTransaction()
 | 
								if (identifier != _transaction.SourceZoneIdentifier)
 | 
				
			||||||
	{
 | 
								{
 | 
				
			||||||
		await _transaction.Cancel();
 | 
									return false;
 | 
				
			||||||
		var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs<T>(_transaction);
 | 
								}
 | 
				
			||||||
		_transaction = null;
 | 
					 | 
				
			||||||
		TransactionEnded?.Invoke(this, transactionFinishedEventArgs);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void UpdateTransactionIndex(int index)
 | 
								return _transaction.SourceIndex == index || _transaction.SourceIndex - 1 == index;
 | 
				
			||||||
	{
 | 
							}
 | 
				
			||||||
		var changed = _transaction.UpdateIndex(index);
 | 
					 | 
				
			||||||
		if (changed == false) { return; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, _transaction.CurrentZone, _transaction.Index));
 | 
							public async Task CommitTransaction(string dropzoneIdentifier, bool reorderIsAllowed)
 | 
				
			||||||
	}
 | 
							{
 | 
				
			||||||
 | 
								await _transaction.Commit();
 | 
				
			||||||
 | 
								var index = -1;
 | 
				
			||||||
 | 
								if (reorderIsAllowed == true)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									index = GetTransactionIndex() + 1;
 | 
				
			||||||
 | 
									if (_transaction.SourceZoneIdentifier == _transaction.CurrentZone && IsItemMovedDownwards() == true)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										index -= 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	internal void UpdateTransactionZone(string identifier)
 | 
								await ItemDropped.InvokeAsync(new ItemDropInfo<T>(_transaction.Item, dropzoneIdentifier, index));
 | 
				
			||||||
	{
 | 
								var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs<T>(dropzoneIdentifier, true, _transaction);
 | 
				
			||||||
		var oldValue = _transaction.CurrentZone;
 | 
								_transaction = null;
 | 
				
			||||||
		var changed = _transaction.UpdateZone(identifier);
 | 
								TransactionEnded?.Invoke(this, transactionFinishedEventArgs);
 | 
				
			||||||
		if (changed == false) { return; }
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, oldValue, _transaction.Index));
 | 
							public async Task CancelTransaction()
 | 
				
			||||||
	}
 | 
							{
 | 
				
			||||||
 | 
								await _transaction.Cancel();
 | 
				
			||||||
 | 
								var transactionFinishedEventArgs = new DragAndDropTransactionFinishedEventArgs<T>(_transaction);
 | 
				
			||||||
 | 
								_transaction = null;
 | 
				
			||||||
 | 
								TransactionEnded?.Invoke(this, transactionFinishedEventArgs);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void UpdateTransactionIndex(int index)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var changed = _transaction.UpdateIndex(index);
 | 
				
			||||||
 | 
								if (changed == false) { return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, _transaction.CurrentZone, _transaction.Index));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							internal void UpdateTransactionZone(string identifier)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var oldValue = _transaction.CurrentZone;
 | 
				
			||||||
 | 
								var changed = _transaction.UpdateZone(identifier);
 | 
				
			||||||
 | 
								if (changed == false) { return; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								TransactionIndexChanged?.Invoke(this, new DragAndDropIndexChangedEventArgs(_transaction.CurrentZone, oldValue, _transaction.Index));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
	/// Refreshes the dropzone and all items within. This is neded in case of adding items to the collection or changed values of items
 | 
							/// Refreshes the dropzone and all items within. This is neded in case of adding items to the collection or changed values of items
 | 
				
			||||||
	/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
	public void Refresh() => RefreshRequested?.Invoke(this, EventArgs.Empty);
 | 
							public void Refresh() => RefreshRequested?.Invoke(this, EventArgs.Empty);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user