-
-
Notifications
You must be signed in to change notification settings - Fork 351
doc(Template5): add transition animation #6469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideThis PR adds a transition animation to the Template5 login sample by modularizing component logic into a partial class, loading a JavaScript module for step-by-step animations, restructuring the Razor markup and CSS for animated transitions, and updating the tutorial navigation and layout to register the new files. Sequence diagram for login step transition animationsequenceDiagram
actor User
participant BlazorComponent as Template5 (Blazor)
participant JSModule as Template5.razor.js
User->>BlazorComponent: Submit email
BlazorComponent->>JSModule: go(id) (transition to password)
JSModule-->>BlazorComponent: Animation complete
User->>BlazorComponent: Submit password
BlazorComponent->>BlazorComponent: Set isAuth = true
User->>BlazorComponent: Click reset
BlazorComponent->>BlazorComponent: Reset state
Class diagram for Template5 component structureclassDiagram
class Template5 {
- bool isAuth
- bool showEmailError
- bool isEmailEntered
- LoginModel _loginModel
+ Task OnEmailSubmit(EditContext)
+ Task OnPasswordSubmit(EditContext)
+ Task GoBack()
+ void OnReset()
+ Task OnAfterRenderAsync(bool)
}
class LoginModel {
string? Email
string? Password
}
Template5 o-- LoginModel
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ArgoZhang - I've reviewed your changes - here's some feedback:
- Use OnAfterRenderAsync to invoke the JS init function (e.g. InvokeVoidAsync("init", Id)) so the initial animation is properly triggered, or remove the empty override if it’s unused.
- Double-check whether Template5.razor.cs should be exposed in the TutorialsNavMenu file list—code-behind files are usually hidden from end-user samples.
- Confirm the removal of the Wwads component from TutorialsLayout was intentional, as it will change the ad placement in the tutorials sidebar.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Use OnAfterRenderAsync to invoke the JS init function (e.g. InvokeVoidAsync("init", Id)) so the initial animation is properly triggered, or remove the empty override if it’s unused.
- Double-check whether Template5.razor.cs should be exposed in the TutorialsNavMenu file list—code-behind files are usually hidden from end-user samples.
- Confirm the removal of the Wwads component from TutorialsLayout was intentional, as it will change the ad placement in the tutorials sidebar.
## Individual Comments
### Comment 1
<location> `src/BootstrapBlazor.Server/Components/Samples/Tutorials/LoginAndRegister/Template5.razor.js:1` </location>
<code_context>
+export function init(id) {
+ const el = document.getElementById(id);
+ if (el) {
+ const email = el.querySelector('.login-item-email');
+ if (email) {
+ email.classList.add('show');
+ }
+ }
+}
</code_context>
<issue_to_address>
The 'init' function is defined but not invoked from C#.
Call 'init' from the C# side (e.g., in OnAfterRenderAsync) to ensure the login form displays the email step correctly on first render.
</issue_to_address>
### Comment 2
<location> `src/BootstrapBlazor.Server/Components/Samples/Tutorials/LoginAndRegister/Template5.razor.js:36` </location>
<code_context>
+ const email = el.querySelector('.login-item-email');
+ if (email) {
+ email.classList.add('show');
+ email.classList.remove('animate-fade-out');
+ email.classList.add('animate-fade-in');
+ }
</code_context>
<issue_to_address>
Consider removing all animation classes before adding new ones to prevent animation conflicts.
Residual animation classes can cause unintended effects. Remove both 'animate-fade-in' and 'animate-fade-out' before adding the new class.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
const email = el.querySelector('.login-item-email');
if (email) {
email.classList.add('show');
email.classList.remove('animate-fade-out');
email.classList.add('animate-fade-in');
}
=======
const email = el.querySelector('.login-item-email');
if (email) {
// Remove all animation classes before adding new ones to prevent animation conflicts
email.classList.remove('animate-fade-in', 'animate-fade-out');
email.classList.add('show');
email.classList.add('animate-fade-in');
}
>>>>>>> REPLACE
</suggested_fix>
### Comment 3
<location> `src/BootstrapBlazor.Server/Components/Samples/Tutorials/LoginAndRegister/Template5.razor.cs:15` </location>
<code_context>
-
-@code {
- private bool isEmailEntered = false;
- private bool isAuth = false;
- private bool showEmailError = false;
- private LoginModel _loginModel = new LoginModel()
</code_context>
<issue_to_address>
Consider replacing multiple boolean flags with a single state enum, removing the unused lifecycle method, and extracting the model class to its own file for clarity.
Here are a few focused tweaks that preserve all functionality while collapsing the three bool flags into a single state enum, removing the no-op lifecycle hook, and pulling your model out of the component:
1. Introduce an enum and single `Stage` field:
```csharp
private enum Stage { EnterEmail, EnterPassword, Authenticated }
private Stage _stage = Stage.EnterEmail;
```
2. Update your handlers to drive that one state and drop all manual `StateHasChanged()` calls (Blazor auto-re-renders on events):
```csharp
private async Task OnEmailSubmit(EditContext ctx)
{
if (string.IsNullOrWhiteSpace(_loginModel.Email))
{
// e.g. set validation message via EditContext
return;
}
_stage = Stage.EnterPassword;
await InvokeVoidAsync("go", Id);
}
private Task OnPasswordSubmit(EditContext ctx)
{
_stage = Stage.Authenticated;
return Task.CompletedTask;
}
private async Task GoBack()
{
_stage = Stage.EnterEmail;
await InvokeVoidAsync("back", Id);
}
private void OnReset() => _stage = Stage.EnterEmail;
```
3. Remove the empty `OnAfterRenderAsync` override completely.
4. Extract `LoginModel` into its own file (e.g. `LoginModel.cs`) under the same namespace:
```csharp
namespace BootstrapBlazor.Server.Components.Samples.Tutorials.LoginAndRegister
{
public class LoginModel
{
public string? Email { get; set; }
public string? Password { get; set; }
}
}
```
5. In your Razor markup, branch on `_stage` instead of multiple booleans:
```razor
@if (_stage == Stage.EnterEmail)
{
<!-- email form -->
}
else if (_stage == Stage.EnterPassword)
{
<!-- password form -->
}
else
{
<!-- authenticated view -->
}
```
This collapses your three flags (`isAuth`, `showEmailError`, `isEmailEntered`) into one, removes redundant lifecycle overrides, and pulls the model to its own file.
</issue_to_address>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
export function init(id) { | ||
const el = document.getElementById(id); | ||
if (el) { | ||
const email = el.querySelector('.login-item-email'); | ||
if (email) { | ||
email.classList.add('show'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): The 'init' function is defined but not invoked from C#.
Call 'init' from the C# side (e.g., in OnAfterRenderAsync) to ensure the login form displays the email step correctly on first render.
const email = el.querySelector('.login-item-email'); | ||
if (email) { | ||
email.classList.add('show'); | ||
email.classList.remove('animate-fade-out'); | ||
email.classList.add('animate-fade-in'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider removing all animation classes before adding new ones to prevent animation conflicts.
Residual animation classes can cause unintended effects. Remove both 'animate-fade-in' and 'animate-fade-out' before adding the new class.
const email = el.querySelector('.login-item-email'); | |
if (email) { | |
email.classList.add('show'); | |
email.classList.remove('animate-fade-out'); | |
email.classList.add('animate-fade-in'); | |
} | |
const email = el.querySelector('.login-item-email'); | |
if (email) { | |
// Remove all animation classes before adding new ones to prevent animation conflicts | |
email.classList.remove('animate-fade-in', 'animate-fade-out'); | |
email.classList.add('show'); | |
email.classList.add('animate-fade-in'); | |
} |
/// </summary> | ||
public partial class Template5 | ||
{ | ||
private bool isAuth = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider replacing multiple boolean flags with a single state enum, removing the unused lifecycle method, and extracting the model class to its own file for clarity.
Here are a few focused tweaks that preserve all functionality while collapsing the three bool flags into a single state enum, removing the no-op lifecycle hook, and pulling your model out of the component:
- Introduce an enum and single
Stage
field:
private enum Stage { EnterEmail, EnterPassword, Authenticated }
private Stage _stage = Stage.EnterEmail;
- Update your handlers to drive that one state and drop all manual
StateHasChanged()
calls (Blazor auto-re-renders on events):
private async Task OnEmailSubmit(EditContext ctx)
{
if (string.IsNullOrWhiteSpace(_loginModel.Email))
{
// e.g. set validation message via EditContext
return;
}
_stage = Stage.EnterPassword;
await InvokeVoidAsync("go", Id);
}
private Task OnPasswordSubmit(EditContext ctx)
{
_stage = Stage.Authenticated;
return Task.CompletedTask;
}
private async Task GoBack()
{
_stage = Stage.EnterEmail;
await InvokeVoidAsync("back", Id);
}
private void OnReset() => _stage = Stage.EnterEmail;
-
Remove the empty
OnAfterRenderAsync
override completely. -
Extract
LoginModel
into its own file (e.g.LoginModel.cs
) under the same namespace:
namespace BootstrapBlazor.Server.Components.Samples.Tutorials.LoginAndRegister
{
public class LoginModel
{
public string? Email { get; set; }
public string? Password { get; set; }
}
}
- In your Razor markup, branch on
_stage
instead of multiple booleans:
@if (_stage == Stage.EnterEmail)
{
<!-- email form -->
}
else if (_stage == Stage.EnterPassword)
{
<!-- password form -->
}
else
{
<!-- authenticated view -->
}
This collapses your three flags (isAuth
, showEmailError
, isEmailEntered
) into one, removes redundant lifecycle overrides, and pulls the model to its own file.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6469 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 749 749
Lines 32364 32364
Branches 4572 4572
=========================================
Hits 32364 32364
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Link issues
fixes #6468
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Implement animated transitions for the Template5 login tutorial by refactoring the component into a code-behind structure, adding a JS module for fade-in/out effects, updating CSS rules, and adjusting layout navigation to load the new files.
New Features:
Enhancements: