-
-
Notifications
You must be signed in to change notification settings - Fork 364
refactor(Toast): perfect AutoHide logic #6039
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 GuideRefactored Toast.razor.js to centralize progress element management, streamline event handling, introduce a transitionend auto-hide trigger, refine autohide update behavior, and ensure complete cleanup in dispose. Sequence Diagram: Toast Auto-Hide on Progress Transition EndsequenceDiagram
participant Caller
participant ToastModule as "Toast.razor.js init()"
participant BootstrapToast as "bootstrap.Toast"
participant ProgressElement as "progressElement"
participant EventHandler
Caller->>ToastModule: init(id, invoke, callback)
ToastModule->>ToastModule: Get progressElement from DOM
ToastModule->>ToastModule: Create toastObject (now includes progressElement reference)
alt autohide is true
ToastModule->>ProgressElement: style.transition = `width linear ${delay}s`
end
ToastModule->>EventHandler: on(el, 'shown.bs.toast', ...)
ToastModule->>EventHandler: on(el, 'hidden.bs.toast', ...)
ToastModule->>EventHandler: on(progressElement, 'transitionend', handleTransitionEndCallback)
ToastModule->>BootstrapToast: show()
EventHandler-->>ToastModule: 'shown.bs.toast' event received
alt autohide is true
ToastModule->>ProgressElement: style.width = '100%' (progress animation starts)
end
Note over ProgressElement: Progress bar animates to 100%
EventHandler-->>ToastModule: 'transitionend' event received (from progressElement)
ToastModule->>BootstrapToast: hide() // Toast hiding is triggered by progress completion
EventHandler-->>ToastModule: 'hidden.bs.toast' event received
ToastModule->>Caller: invoke.invokeMethodAsync(callback) // Notify .NET about closure
Sequence Diagram: Toast Update Logic for AutoHide ConfigurationsequenceDiagram
participant Caller
participant ToastModuleUpdate as "Toast.razor.js update()"
participant ToastObject
participant BootstrapToastConfig as "bootstrap.Toast._config"
participant ProgressElementStyle as "progressElement.style"
Caller->>ToastModuleUpdate: update(id)
ToastModuleUpdate->>ToastObject: Get toast data (element, toast, progressElement)
ToastModuleUpdate->>ToastObject: Read autohide & delay from element attributes
alt autohide is true (based on element attributes)
ToastModuleUpdate->>BootstrapToastConfig: toast._config.autohide = true
ToastModuleUpdate->>BootstrapToastConfig: toast._config.delay = newDelay
ToastModuleUpdate->>ProgressElementStyle: progressElement.style.width = '100%'
ToastModuleUpdate->>ProgressElementStyle: progressElement.style.transition = `width linear ${newDelay / 1000}s`
else autohide is false (based on element attributes)
ToastModuleUpdate->>BootstrapToastConfig: toast._config.autohide = false
ToastModuleUpdate->>ProgressElementStyle: progressElement.style.removeProperty('width')
ToastModuleUpdate->>ProgressElementStyle: progressElement.style.removeProperty('transition')
end
Class Diagram: Structure of the Internal Toast ObjectclassDiagram
class ToastObject {
+element: HTMLElement
+invoke: DotNetObjectReference
+callback: string
+toast: BootstrapToast
+progressElement: HTMLElement // Centralized property
+showProgress(): boolean
}
note for ToastObject "Internal object created by Toast.razor.js#init() to manage a toast instance. `progressElement` is now a direct and centralized property, simplifying its access and management."
class BootstrapToast {
<<External Library>>
_config: object
show()
hide()
dispose()
}
class EventHandler {
<<Utility Module>>
static on(element, eventName, handler)
static off(element, eventName, handler)
}
namespace ToastRazorJs {
class Functions {
<<JavaScript Module Functions>>
init(id, invoke, callback): ToastObject
update(id): void
dispose(id): void
}
}
note for Functions "Exported functions in Toast.razor.js that operate on ToastObject instances stored in a Data cache."
Functions ..> ToastObject : Creates & Manages
ToastObject "1" *-- "1" BootstrapToast : aggregates via `toast` property
ToastObject "1" *-- "1" HTMLElement : holds `element` (the main toast DOM element)
ToastObject "1" *-- "1" HTMLElement : holds `progressElement` (the progress bar DOM element)
Functions ..> EventHandler : Uses for event binding and unbinding
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 and they look great!
Here's what I looked at during the review
- 🟡 General issues: 2 issues found
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
|
||
| toast._config.autohide = autoHide; | ||
| toast._config.delay = delay; | ||
|
|
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 (bug_risk): Specify radix in parseInt
Include a radix of 10 (parseInt(..., 10)) to ensure decimal parsing; without it, leading zeros can cause unexpected results.
| const delay = parseInt(element.getAttribute('data-bs-delay'), 10); |
| EventHandler.on(progressElement, 'transitionend', e => { | ||
| toast.toast.hide(); | ||
| }); |
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 (bug_risk): Filter transitionend by property name
Guard with if (e.propertyName !== 'width') return; so only the width transition triggers hide and other transitions won’t call it.
| EventHandler.on(progressElement, 'transitionend', e => { | |
| toast.toast.hide(); | |
| }); | |
| EventHandler.on(progressElement, 'transitionend', e => { | |
| if (e.propertyName !== 'width') return; | |
| toast.toast.hide(); | |
| }); |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6039 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 701 701
Lines 30955 30955
Branches 4377 4377
=========================================
Hits 30955 30955 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Link issues
fixes #6038
Summary By Copilot
This pull request refactors the
Toast.razor.jsfile to improve code maintainability and fix issues related to the toast progress bar and event handling. Key changes include centralizing theprogressElementlogic, updating event handlers, and enhancing the handling of theautohideconfiguration.Refactoring and code improvements:
progressElementlogic by moving its initialization to theinitfunction and ensuring consistent usage across methods. This eliminates redundant queries for the.toast-progresselement.el(the toast element) instead of repeatedly referencingtoast.element. This improves readability and reduces potential errors.Functional enhancements:
transitionendevent on theprogressElementto automatically hide the toast when the progress bar animation completes.updatefunction to handle cases whereautohideis disabled by removing the progress bar's width and transition properties. This ensures proper behavior for non-autohiding toasts.Cleanup and disposal:
disposefunction to cleanly remove all associated event handlers, including the newtransitionendevent on the `progressElementRegression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Refactor toast component to improve auto-hide logic by centralizing progress bar handling, adding a transitionend listener to trigger hide on animation completion, handling disabled autohide by clearing styles, and ensuring proper cleanup of event listeners
Bug Fixes:
Enhancements: