protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { // Resolve (import) required javascript // Note: We want to use synchronous js calls whenever possible (for performance) if (JSRuntime is IJSInProcessRuntime) { _jsInProcessReference = await JSRuntime.InvokeAsync <IJSInProcessObjectReference>("import", ModulePath); _jsReference = _jsInProcessReference; } else { _jsReference = await JSRuntime.InvokeAsync <IJSObjectReference>("import", ModulePath); } // Trigger re-render after javascript was resolved StateHasChanged(); return; } // Ensure that reference was resolved (important!) // Lifecycle method could be called twice very fast: // If that's the case the second call (is not "firstRender") would // try to call a function on the js-object which is not yet resolved if (_jsReference == null) { return; } // When a target element was supplied we want to use it if (Target != null && Target.HasValue) { _target = Target.Current; } // Check whether the target element exists in DOM if (_target.Id == null) { return; } if (_isActive) { // Check if we need to show the content if (_state == TransitionState.Leaving || _state == TransitionState.Left) { _state = TransitionState.Entering; // Set correct state before registering js callback // When possible use the synchronous js call if (_jsInProcessReference != null) { RegisterCallback(); } else { await RegisterCallbackAsync(); } await StateChanged.InvokeAsync(_state); } return; } // Check if we need to hide the content if (_state == TransitionState.Entering || _state == TransitionState.Entered) { _state = TransitionState.Leaving; // Set correct state before registering js callback // When possible use the synchronous js call if (_jsInProcessReference != null) { RegisterCallback(); } else { await RegisterCallbackAsync(); } await StateChanged.InvokeAsync(_state); } }