diff --git a/src/TDesign/Components/Popup/PopperExtensions.cs b/src/TDesign/Components/Popup/PopperExtensions.cs deleted file mode 100644 index 7d72d66a..00000000 --- a/src/TDesign/Components/Popup/PopperExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.JSInterop; - -namespace TDesign; -/// -/// Popup 的 JS 扩展。 -/// -public static class PopperExtensions -{ - /// - /// 调用 popup 组件 - /// - /// - /// 触发 popup 组件的元素引用。 - /// Popup组件元素的引用。 - /// Popup的配置。 - public static async ValueTask InvokePopupAsync(this IJSRuntime js, ElementReference selectorRef, ElementReference popupRef, PopperOptions options,Func clickToHide) - { - var tdesignModule = await js.ImportTDesignModuleAsync("popup"); - - var popperModule = await tdesignModule.Module.InvokeAsync("popup.show", selectorRef, popupRef, options, DotNetObjectReference.Create(options),JSInvokeMethodFactory.Create(clickToHide)); - - return new(tdesignModule.Module, popperModule, options); - } -} diff --git a/src/TDesign/Components/Popup/TPopup.cs b/src/TDesign/Components/Popup/TPopup.cs index fd093cc8..70cafd31 100644 --- a/src/TDesign/Components/Popup/TPopup.cs +++ b/src/TDesign/Components/Popup/TPopup.cs @@ -1,23 +1,13 @@ -namespace TDesign; +using Microsoft.JSInterop; +using System.Text.Json.Serialization; + +namespace TDesign; /// /// 具备悬浮提示的弹出层。 /// [CssClass("t-popup")] public class TPopup : TDesignAdditionParameterWithChildContentComponentBase { - const string ANIMATION_ENTER = "t-popup--animation-enter"; - const string ANIMATION_ENTER_FROM = "t-popup--animation-enter-from"; - const string ANIMATION_EXITING = "t-popup--animation-exiting"; - const string ANIMATION_LEAVE_TO = "t-popup--animation-leave-to"; - - const string ANIMATION_ENTER_TO = "t-popup--animation-enter-to"; - const string ANIMATION_ENTERING = "t-popup--animation-entering"; - const string ANIMATION_LEAVE_FROM = "t-popup--animation-leave-from"; - const string ANIMATION_LEAVE = "t-popup--animation-leave"; - - const string ANIMATION_ENTER_ACTIVE = "t-popup--animation-enter-active"; - const string ANIMATION_LEAVE_ACTIVE = "t-popup--animation-leave-active"; - /// /// 初始化 类的新实例。 /// @@ -63,7 +53,17 @@ public class TPopup : TDesignAdditionParameterWithChildContentComponentBase /// public bool Visible { get; private set; } - Popper? _instance; + Popper? _popper; + + IJSModule _popupModule; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if ( firstRender ) + { + _popupModule = await JS.ImportTDesignModuleAsync("popup"); + } + } /// protected override void OnParametersSet() @@ -94,14 +94,6 @@ protected override void AddContent(RenderTreeBuilder builder, int sequence) inner.Div("t-popup__arrow", Arrow).Close(); }) .Close(); - - protected override void BuildCssClass(ICssClassBuilder builder) - { - if ( !builder.Contains(ANIMATION_ENTER) ) - { - builder.Append(ANIMATION_ENTER); - } - } protected override void BuildStyle(IStyleBuilder builder) { builder.Append("display:none"); @@ -111,16 +103,13 @@ protected override void BuildStyle(IStyleBuilder builder) /// 触发指定元素引用并显示弹出层。 /// /// 被触发弹出层的元素引用。 - public async Task Show(IBlazorComponent selector) + public async Task Show(TDesignComponentBase selector) { - _instance = await JS.InvokePopupAsync(selector.Reference!.Value, Reference!.Value, new() + var options = new PopperOptions { Placement = Placement - }, Hide); - - CssClassBuilder.Remove(ANIMATION_ENTER).Remove(ANIMATION_LEAVE_ACTIVE).Append(ANIMATION_ENTER_ACTIVE).Append(ANIMATION_LEAVE); - Visible = true; - StateHasChanged(); + }; + await _popupModule.Module.InvokeVoidAsync("popup.show", selector.Reference, Reference, options, DotNetObjectReference.Create(this)); } /// @@ -128,15 +117,23 @@ public async Task Show(IBlazorComponent selector) /// public async Task Hide() { - if (_instance is not null) - { - await _instance.HideAsync(Reference); + await _popupModule.Module.InvokeVoidAsync("popup.hide", Reference, DotNetObjectReference.Create(this)); + } - CssClassBuilder.Remove(ANIMATION_LEAVE).Remove(ANIMATION_ENTER_ACTIVE).Append(ANIMATION_LEAVE_ACTIVE).Append(ANIMATION_ENTER); - Visible = false; - StateHasChanged(); - } + [JSInvokable("onHidden")] + public void InvokeOnHidden() + { + Visible = false; } + + [JSInvokable("onShown")] + public void InvokeOnShown() + { + Visible = true; + //_popper = new(_popupModule.Module, popper, new()); + } + + } /// diff --git a/src/TDesign/wwwroot/libs/tdesign-blazor-popup.js b/src/TDesign/wwwroot/libs/tdesign-blazor-popup.js index 8953718a..de257e78 100644 --- a/src/TDesign/wwwroot/libs/tdesign-blazor-popup.js +++ b/src/TDesign/wwwroot/libs/tdesign-blazor-popup.js @@ -4,34 +4,71 @@ * 弹出层 * */ let popup = { + animationClass: { + ANIMATION_ENTER: 't-popup--animation-enter', + ANIMATION_ENTER_FROM: 't-popup--animation-enter-from', + ANIMATION_EXITING: 't-popup--animation-exiting', + ANIMATION_LEAVE_TO: 't-popup--animation-leave-to', + ANIMATION_ENTER_TO: 't-popup--animation-enter-to', + ANIMATION_ENTERING: 't-popup--animation-entering', + ANIMATION_LEAVE_FROM: 't-popup--animation-leave-from', + ANIMATION_LEAVE: 't-popup--animation-leave', + ANIMATION_ENTER_ACTIVE: 't-popup--animation-enter-active', + ANIMATION_LEAVE_ACTIVE: 't-popup--animation-leave-active', + }, + popperList: [], /** * 创建一个新的弹出层引用 - * @param objRef 触发对象的引用 - * @param popupRef 弹出提示对象的引用 + * @param trigerElement 触发对象的引用 + * @param popupElement 弹出提示对象的引用 * @param options 弹出层配置 * @param optionDotNetHelper options 包装的 DotNetReference 对象 * @returns popper 对象 - * */ - show: function (trigerElement, popupElement, options, optionDotNetReference,dotNetHelper) { + * */ + show: function (trigerElement, popupElement, options, dotNetHelper) { + let popper; options.onFirstUpdate = state => { - optionDotNetReference.invokeMethodAsync("InvokeOnFirstUpdate", { placement: state.placement }); + console.debug('placement:' + state.placement); + //optionDotNetReference.invokeMethodAsync("InvokeOnFirstUpdate", { placement: state.placement }); } - let popper = createPopper(trigerElement, popupElement, options); + setTimeout(() => { + popper = createPopper(trigerElement, popupElement, options); + document.body.appendChild(popupElement); + window.addEventListener("click", () => { + this.hide(popupElement, dotNetHelper); + }, {once:true}); - window.addEventListener("click", () => { - dotNetHelper.invokeMethodAsync("Invoke"); - }); + //popupElement.style.display = ""; + popupElement.style.display = ""; + popupElement.classList.remove(this.animationClass.ANIMATION_ENTER, this.animationClass.ANIMATION_LEAVE_ACTIVE); + popupElement.classList.add(this.animationClass.ANIMATION_ENTER_ACTIVE, this.animationClass.ANIMATION_LEAVE); + dotNetHelper.invokeMethodAsync('onShown'); - document.body.appendChild(popupElement); - popupElement.style.display = ""; - return popper; + this.popperList[popupElement] = popper; + }, 400); + //return popper; }, - hide: function (popper, popupElement, options) { - if (popper) { - popper.destroy(); + hide: function (popupElement, dotNetHelper) { + if (popupElement) { + + const popper = this.popperList[popupElement]; + if (!popper) { + return; + } + popupElement.classList.remove(this.animationClass.ANIMATION_LEAVE, this.animationClass.ANIMATION_ENTER_ACTIVE); + popupElement.classList.add(this.animationClass.ANIMATION_LEAVE_ACTIVE, this.animationClass.ANIMATION_ENTER); + + setTimeout(() => { + popper.destroy(); + popupElement.style.display = 'none'; + dotNetHelper.invokeMethodAsync('onHidden'); + },400) } + }, + clear: () => { + this.popperList.clear(); } }