mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-12-02 12:07:44 +08:00
fix: multiple bugs originating from js (#1342)
* fix: multiple bugs originating from js * fix(module:input): remove preventScroll from Focus method fix: keep focus on clear * fix(module:input): debug info clean-up * fix(module:select): wait for browser to finish render * fix(module:select): wait for ElementReference.Id * fix doc assets * fix(module:select): increase wait time for ElementRefernece.Id Co-authored-by: James Yeung <shunjiey@hotmail.com>
This commit is contained in:
parent
d4a7e29b77
commit
242084e774
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using AntDesign.Core.Extensions;
|
||||
|
||||
namespace AntDesign
|
||||
{
|
||||
@ -103,6 +104,8 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task FocusAsync(ElementReference target, bool preventScroll = false) => await Js.FocusAsync(target, preventScroll);
|
||||
|
||||
protected bool IsDisposed { get; private set; }
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
|
@ -1,4 +1,7 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
|
||||
namespace AntDesign.Core.Extensions
|
||||
@ -6,5 +9,22 @@ namespace AntDesign.Core.Extensions
|
||||
public static class JSRuntimeExtensions
|
||||
{
|
||||
public static bool IsBrowser(this IJSRuntime jsRuntime) => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));
|
||||
|
||||
public static async Task FocusAsync(this IJSRuntime jSRuntime, ElementReference target, bool preventScroll = false)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
await target.FocusAsync();
|
||||
#else
|
||||
try
|
||||
{
|
||||
await jSRuntime.InvokeVoidAsync(JSInteropConstants.Focus, target, preventScroll);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,8 +164,8 @@ export function addDomEventListener(element, eventName, preventDefault, invoker)
|
||||
if (v instanceof Node) return 'Node';
|
||||
if (v instanceof Window) return 'Window';
|
||||
return v;
|
||||
}, ' ');
|
||||
invoker.invokeMethodAsync('Invoke', json);
|
||||
}, ' ');
|
||||
setTimeout(function () { invoker.invokeMethodAsync('Invoke', json) }, 0);
|
||||
if (preventDefault === true) {
|
||||
args.preventDefault();
|
||||
}
|
||||
@ -225,9 +225,9 @@ export function copy(text) {
|
||||
export function focus(selector, noScroll: boolean=false) {
|
||||
let dom = getDom(selector);
|
||||
if (!(dom instanceof HTMLElement))
|
||||
throw new Error("Unable to focus an invalid element.");
|
||||
throw new Error("Unable to focus an invalid element.");
|
||||
dom.focus({
|
||||
preventScroll: noScroll
|
||||
preventScroll: noScroll
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
if (!_inputEnd.IsOnFocused)
|
||||
{
|
||||
await Blur(0);
|
||||
|
@ -439,7 +439,7 @@ namespace AntDesign
|
||||
if (input != null)
|
||||
{
|
||||
input.IsOnFocused = true;
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, input.Ref);
|
||||
await FocusAsync(input.Ref);
|
||||
_needRefresh = true;
|
||||
}
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ namespace AntDesign
|
||||
private async Task SetFocus()
|
||||
{
|
||||
_focused = true;
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, Ref);
|
||||
await FocusAsync(Ref);
|
||||
}
|
||||
|
||||
private void OnInput(ChangeEventArgs args)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -44,7 +45,15 @@ namespace AntDesign
|
||||
public string Placeholder { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool AutoFocus { get; set; }
|
||||
public bool AutoFocus
|
||||
{
|
||||
get { return _autoFocus; }
|
||||
set {
|
||||
_autoFocus = value;
|
||||
if (!_isInitialized && _autoFocus)
|
||||
IsFocused = _autoFocus;
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public TValue DefaultValue { get; set; }
|
||||
@ -101,6 +110,9 @@ namespace AntDesign
|
||||
private TValue _inputValue;
|
||||
private bool _compositionInputting;
|
||||
private Timer _debounceTimer;
|
||||
private bool _autoFocus;
|
||||
private bool _isInitialized;
|
||||
|
||||
private bool DebounceEnabled => DebounceMilliseconds != 0;
|
||||
|
||||
protected bool IsFocused { get; set; }
|
||||
@ -115,6 +127,7 @@ namespace AntDesign
|
||||
}
|
||||
|
||||
SetClasses();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
protected virtual void SetClasses()
|
||||
@ -173,11 +186,6 @@ namespace AntDesign
|
||||
SetClasses();
|
||||
}
|
||||
|
||||
public async Task Focus()
|
||||
{
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, Ref);
|
||||
}
|
||||
|
||||
protected virtual async Task OnChangeAsync(ChangeEventArgs args)
|
||||
{
|
||||
if (CurrentValueAsString != args?.Value?.ToString())
|
||||
@ -238,6 +246,8 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnFocusInternal(JsonElement e) => await OnFocusAsync(new());
|
||||
|
||||
internal virtual async Task OnFocusAsync(FocusEventArgs e)
|
||||
{
|
||||
IsFocused = true;
|
||||
@ -274,11 +284,13 @@ namespace AntDesign
|
||||
{
|
||||
builder.AddAttribute(34, "Style", "visibility: visible;");
|
||||
}
|
||||
builder.AddAttribute(35, "OnClick", CallbackFactory.Create<MouseEventArgs>(this, (args) =>
|
||||
builder.AddAttribute(35, "OnClick", CallbackFactory.Create<MouseEventArgs>(this, async (args) =>
|
||||
{
|
||||
CurrentValue = default;
|
||||
IsFocused = true;
|
||||
await this.FocusAsync(Ref);
|
||||
if (OnChange.HasDelegate)
|
||||
OnChange.InvokeAsync(Value);
|
||||
await OnChange.InvokeAsync(Value);
|
||||
ToggleClearBtn();
|
||||
}));
|
||||
builder.CloseComponent();
|
||||
@ -334,11 +346,12 @@ namespace AntDesign
|
||||
{
|
||||
DomEventService.AddEventListener(Ref, "compositionstart", OnCompositionStart);
|
||||
DomEventService.AddEventListener(Ref, "compositionend", OnCompositionEnd);
|
||||
|
||||
if (this.AutoFocus)
|
||||
{
|
||||
await this.Focus();
|
||||
IsFocused = true;
|
||||
await this.FocusAsync(Ref);
|
||||
}
|
||||
DomEventService.AddEventListener(Ref, "focus", OnFocusInternal, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,6 +359,7 @@ namespace AntDesign
|
||||
{
|
||||
DomEventService.RemoveEventListerner<JsonElement>(Ref, "compositionstart", OnCompositionStart);
|
||||
DomEventService.RemoveEventListerner<JsonElement>(Ref, "compositionend", OnCompositionEnd);
|
||||
DomEventService.RemoveEventListerner<JsonElement>(Ref, "focus", OnFocusInternal);
|
||||
|
||||
_debounceTimer?.Dispose();
|
||||
|
||||
@ -487,7 +501,9 @@ namespace AntDesign
|
||||
builder.AddAttribute(73, "onkeydown", CallbackFactory.Create(this, OnkeyDownAsync));
|
||||
builder.AddAttribute(74, "onkeyup", CallbackFactory.Create(this, OnKeyUpAsync));
|
||||
builder.AddAttribute(75, "oninput", CallbackFactory.Create(this, OnInputAsync));
|
||||
builder.AddAttribute(76, "onfocus", CallbackFactory.Create(this, OnFocusAsync));
|
||||
|
||||
//TODO: Use built in @onfocus once https://github.com/dotnet/aspnetcore/issues/30070 is solved
|
||||
//builder.AddAttribute(76, "onfocus", CallbackFactory.Create(this, OnFocusAsync));
|
||||
builder.AddAttribute(77, "onmouseup", CallbackFactory.Create(this, OnMouseUpAsync));
|
||||
builder.AddElementReferenceCapture(90, r => Ref = r);
|
||||
builder.CloseElement();
|
||||
|
@ -232,7 +232,7 @@ namespace AntDesign
|
||||
if (OnFocus.HasDelegate)
|
||||
await OnFocus.InvokeAsync(args);
|
||||
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, Ref);
|
||||
await FocusAsync(Ref);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace AntDesign
|
||||
{
|
||||
if (this.AutoFocus)
|
||||
{
|
||||
await this.Focus();
|
||||
await FocusAsync(this.InputRef);
|
||||
}
|
||||
|
||||
await base.OnFirstAfterRenderAsync();
|
||||
@ -140,11 +140,6 @@ namespace AntDesign
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task Focus()
|
||||
{
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, this.InputRef);
|
||||
}
|
||||
|
||||
protected async Task Blur()
|
||||
{
|
||||
await JsInvokeAsync(JSInteropConstants.Blur, this.InputRef);
|
||||
|
@ -2079,7 +2079,7 @@ namespace AntDesign
|
||||
|
||||
SetClassMap();
|
||||
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, _inputRef);
|
||||
await FocusAsync(_inputRef);
|
||||
|
||||
OnFocus?.Invoke();
|
||||
}
|
||||
|
@ -16,9 +16,7 @@
|
||||
<input @ref="ParentSelect._inputRef"
|
||||
@oninput="OnInput"
|
||||
@onkeyup="OnKeyUp"
|
||||
@onkeydown="OnKeyDown"
|
||||
@onfocus="OnFocus"
|
||||
@onblur="OnBlur"
|
||||
@onkeydown="OnKeyDown"
|
||||
@attributes=@AdditonalAttributes()
|
||||
@onkeypress="@OnKeyPressEventHandler"
|
||||
@onkeypress:preventDefault="@_suppressInput"
|
||||
@ -252,9 +250,7 @@ else //ParentSelect.SelectMode != SelectMode.Default
|
||||
<input @ref="ParentSelect._inputRef"
|
||||
@oninput="OnInput"
|
||||
@onkeyup="OnKeyUp"
|
||||
@onkeydown="OnKeyDown"
|
||||
@onfocus="OnFocus"
|
||||
@onblur="OnBlur"
|
||||
@onkeydown="OnKeyDown"
|
||||
@attributes=@AdditonalAttributes()
|
||||
@onkeypress="@OnKeyPressEventHandler"
|
||||
@onkeypress:preventDefault="@_suppressInput"
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AntDesign.Core.Extensions;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using AntDesign.Core.Extensions;
|
||||
using AntDesign.JsInterop;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
@ -101,12 +101,16 @@ namespace AntDesign.Select.Internal
|
||||
if (ParentSelect.IsResponsive)
|
||||
{
|
||||
_currentItemCount = ParentSelect.SelectedOptionItems.Count;
|
||||
Console.WriteLine("Getting _aggregateTagElement from OnAfterRenderAsync");
|
||||
//in blazor Wasm there has to be a delay here, otherwise _aggregateTagElement is not found and is set to null
|
||||
if (Js.IsBrowser())
|
||||
await Task.Delay(1);
|
||||
//even though it is run in OnAfterRender, it may happen that the browser
|
||||
//did not manage to render yet the element; force a continuous check
|
||||
//until the element gets the id
|
||||
while (_aggregateTag.Id is null)
|
||||
{
|
||||
await Task.Delay(5);
|
||||
}
|
||||
|
||||
_aggregateTagElement = await Js.InvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, _aggregateTag, _aggregateTag.Id, true);
|
||||
|
||||
_aggregateTagElement = await Js.InvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, _aggregateTag);
|
||||
if (_prefixRef.Id != default)
|
||||
{
|
||||
_prefixElement = await Js.InvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, _prefixRef);
|
||||
@ -120,6 +124,8 @@ namespace AntDesign.Select.Internal
|
||||
DomEventService.AddEventListener("window", "resize", OnWindowResize, false);
|
||||
await CalculateResponsiveTags();
|
||||
}
|
||||
DomEventService.AddEventListener(ParentSelect._inputRef, "focusout", OnBlurInternal, true);
|
||||
DomEventService.AddEventListener(ParentSelect._inputRef, "focus", OnFocusInternal, true);
|
||||
}
|
||||
else if (_currentItemCount != ParentSelect.SelectedOptionItems.Count)
|
||||
{
|
||||
@ -137,11 +143,13 @@ namespace AntDesign.Select.Internal
|
||||
|
||||
internal async Task CalculateResponsiveTags(bool forceInputFocus = false)
|
||||
{
|
||||
if (!ParentSelect.IsResponsive)
|
||||
return;
|
||||
|
||||
_overflowElement = await Js.InvokeAsync<DomRect>(JSInteropConstants.GetBoundingClientRect, _overflow);
|
||||
|
||||
//distance between items is margin-inline-left=4px
|
||||
decimal accumulatedWidth = _prefixElement.width + _suffixElement.width + (4 + (SearchValue?.Length ?? 0) * 8);
|
||||
var accumulatedWidthSource = new StringBuilder(accumulatedWidth.ToString());
|
||||
int i = 0;
|
||||
bool overflowing = false;
|
||||
bool renderAgain = false;
|
||||
@ -179,7 +187,6 @@ namespace AntDesign.Select.Internal
|
||||
else
|
||||
{
|
||||
accumulatedWidth += item.Width;
|
||||
accumulatedWidthSource.Append("," + item.Width.ToString());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@ -198,16 +205,11 @@ namespace AntDesign.Select.Internal
|
||||
var isFocused = await Js.InvokeAsync<bool>(JSInteropConstants.HasFocus, ParentSelect._inputRef);
|
||||
if (!isFocused)
|
||||
{
|
||||
#if NET5_0
|
||||
await ParentSelect._inputRef.FocusAsync();
|
||||
#else
|
||||
await Js.InvokeVoidAsync(JSInteropConstants.Focus, ParentSelect._inputRef);
|
||||
#endif
|
||||
await Js.FocusAsync(ParentSelect._inputRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetInputWidth()
|
||||
{
|
||||
_inputWidth = string.Empty;
|
||||
@ -373,6 +375,13 @@ namespace AntDesign.Select.Internal
|
||||
await OnClearClick.InvokeAsync(args);
|
||||
}
|
||||
|
||||
//TODO: Use built in @onfocus once https://github.com/dotnet/aspnetcore/issues/30070 is solved
|
||||
private async void OnFocusInternal(JsonElement e) => await OnFocus.InvokeAsync(new());
|
||||
|
||||
//TODO: Use built in @onblur once https://github.com/dotnet/aspnetcore/issues/30070 is solved
|
||||
private async void OnBlurInternal(JsonElement e) => await OnBlur.InvokeAsync(new());
|
||||
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
@ -386,6 +395,8 @@ namespace AntDesign.Select.Internal
|
||||
await Js.InvokeVoidAsync(JSInteropConstants.RemovePreventEnterOnOverlayVisible, ParentSelect._inputRef);
|
||||
});
|
||||
}
|
||||
DomEventService.RemoveEventListerner<JsonElement>(ParentSelect._inputRef, "focus", OnFocusInternal);
|
||||
DomEventService.RemoveEventListerner<JsonElement>(ParentSelect._inputRef, "focusout", OnBlurInternal);
|
||||
DomEventService.RemoveEventListerner<JsonElement>("window", "beforeunload", Reloading);
|
||||
if (ParentSelect.IsResponsive)
|
||||
DomEventService.RemoveEventListerner<JsonElement>("window", "resize", OnWindowResize);
|
||||
|
@ -660,8 +660,8 @@ namespace AntDesign
|
||||
_right = false;
|
||||
if (_mouseDown)
|
||||
RightValue = _initialLeftValue;
|
||||
LeftValue = rightV;
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, _leftHandle);
|
||||
LeftValue = rightV;
|
||||
await FocusAsync(_leftHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -707,8 +707,8 @@ namespace AntDesign
|
||||
_right = true;
|
||||
if (_mouseDown)
|
||||
LeftValue = _initialRightValue;
|
||||
RightValue = leftV;
|
||||
await JsInvokeAsync(JSInteropConstants.Focus, _rightHandle);
|
||||
RightValue = leftV;
|
||||
await FocusAsync(_rightHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user