-
Notifications
You must be signed in to change notification settings - Fork 65
feat: Toasts #1246
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
base: main
Are you sure you want to change the base?
feat: Toasts #1246
Conversation
Implement core R functions for toast notifications: - toast(): Create toast objects with customizable options - show_toast(): Display toasts in Shiny apps - hide_toast(): Manually dismiss toasts - toast_header(): Create structured headers with icons/status Follows bslib component patterns with object-oriented design and server-side creation model. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implement client-side toast functionality: - ToastContainerManager for auto-creating position-specific containers - showToast handler to display toasts with Bootstrap Toast API - hideToast handler to manually dismiss toasts - Auto-cleanup of toast elements and empty containers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add minimal custom styles for toast component: - CSS variable for runtime theming support - Ensure close button visibility on colored backgrounds 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Import toast component to ensure message handlers are registered when the components bundle is loaded. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Test coverage includes: - Toast object creation and validation - Position and type argument validation - Accessibility attribute generation - Close button rendering logic - HTML structure generation - toast_header() functionality - All type and position options 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Create comprehensive demo app showcasing toast features: - Basic toasts with different types (success, error, warning, info) - Position options (all 9 positions) - Advanced features (persistent, long duration, no close button) - Interactive toasts with action buttons - Multiple toasts and stacking behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Change from direct import to window.bootstrap access pattern: - Import Toast type only, not implementation - Access Toast from window.bootstrap with class fallback - Add console warning if Bootstrap is not available - Follows pattern used by tooltip and popover components 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace basic examples with comprehensive toast builder: - Interactive form with all toast options - input_switch() for binary settings (header, icon, status, autohide, etc) - Conditional panels to show/hide relevant options - Select menus for type, position, and icon choices - Slider for duration control - Custom ID option for manual toast management - Two buttons: show toast and hide last toast - Keep advanced features and interactive toast examples Users can now experiment with all toast parameters interactively. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Change the status parameter in toast_header() from a colored indicator to status text (e.g., "11 mins ago", "just now") that appears as small muted text in the header, matching Bootstrap's toast examples. - Remove validation for status parameter - Render status as <small class="text-muted"> instead of badge - Update documentation and examples - Update tests to match new behavior
Replace separate autohide (logical) and duration (milliseconds) parameters with single autohide_s parameter in seconds: - autohide_s = 0, NA, or NULL disables auto-hiding - autohide_s > 0 enables auto-hiding after N seconds - Internally converts to milliseconds for Bootstrap Toast - Simplifies API: one parameter instead of two Updates: - toast() function signature and implementation - All examples in demo app - All tests to use new parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add two interactive features for autohiding toasts: 1. Progress Bar Animation: - Animated bar at top of toast shows remaining time - Uses CSS transform animation for smooth performance - Gradient styling with primary color theme integration - Automatically added only to autohiding toasts 2. Hover Pause Behavior: - Mouse hover pauses the auto-hide timer - Progress bar animation pauses when hovered - Both resume when mouse leaves - Override Bootstrap's hide() to check hover state Implementation: - addProgressBar(): Creates and styles progress element - setupHoverPause(): Configures hover event handlers - CSS keyframe animation for progress bar - Toast positioned relative with overflow hidden 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Change progress bar animation from emptying (1 → 0) to filling (0 → 1) to better indicate time passing. Bar now grows from left to right as the toast approaches auto-hide time. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Extract random ID generation into `toast_random_id()` helper function - Replace duplicate ID generation logic with centralized helper - Simplify `show_toast()` by using `processDeps()` instead of manual HTML rendering and dependency resolution - Remove redundant comments and streamline code flow
…simplify implementation - Consolidate documentation for `show_toast()` and `hide_toast()` into a single help page using `@describeIn` - Remove `session$onFlush()` callbacks in favor of immediate `sendCustomMessage()` calls - Make `hide_toast()` accept toast objects with IDs and return the ID consistently - Add error handling for hiding toasts without IDs - Update documentation examples and parameter descriptions - Add tests for `show_toast()` return value and `hide_toast()` functionality
| observeEvent(input$hide_toast, { | ||
| req(last_toast_id()) | ||
| hide_toast(last_toast_id()) | ||
| last_toast_id(NULL) | ||
| }) |
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.
If I click 'show' repeatedly, then 'hide' repeatedly, only the 1st hide works (since we're only tracking the last ID).
Related to this problem, would it make sense for hide_toast() to remove the "oldest" toast? Or provide access to a input[["toast_id"]] == T/F ?
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.
Yeah, that's why I labelled the button "Hide Last Toast". We certainly could keep track of a stack of toasts, but I don't think it's worth it for this example app.
I'm also fairly strongly against creating inputs for toasts to track their state. Toasts are primarily ephemeral by design; I don't think it's a good idea to add to the input namespace for something that is intended to be short-lived in the app.
I could be convinced to add a toast_state(id) helper that would return a reactive value indicating whether a toast with the given ID is currently visible or not. But I don't think it's a necessary feature so I'd rather hold off on that for now.
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Introduces a comprehensive toast notification system for Shiny applications, including
toast()(withtoast_header()helper),show_toast()andhide_toast().Toasts are small notification messages that are shown temporarily on screen. By default they autohide after 5 seconds, but this delay can be customized. bslib toasts have a few interesting features above and beyond the Bootstrap standard toasts:
show_toast()returns the ID of the toast that was shown (either auto-generated or from thetoastobject being shown). This ID can then be used withhide_toast()to hide the toast.bslib toasts come with an additional demo app to try out all of the features:
Examples
Basic toast
Toast with
headershow_toast( toast( "This is a toast notification!", header = toast_header( title = "Notification Title", icon = bsicons::bs_icon("star"), status = "16s ago" ) ) )Toast with
headerandtype = "success"show_toast( toast( "Your profile has been updated successfully", header = toast_header( title = "Profile updated", icon = bsicons::bs_icon("check", class = "text-success"), status = "just now" ) ) )Toast with Shiny controls
show_toast( toast( id = "unsaved_changes_toast", p("Would you like to save your changes?"), actionButton("save_yes", "Save", class = "btn-sm btn-primary me-2"), actionButton( "save_no", "Don't Save", class = "btn-sm btn-secondary" ), header = "Unsaved Changes", type = "warning", duration_s = 0 ) )