如何让shiny.semantic的showNotification/toast支持top attached定位?
解决shiny.semantic中showNotification/toast支持'top attached'定位的问题
问题背景
根据Fomantic UI文档,原生JS可直接生成top attached类型的toast:
$.toast({ position: 'top attached', title: 'Watch out!', message: `I am a top attached toast` });
但在shiny.semantic包中,showNotification函数无法识别'top attached'参数,常规位置(如bottom left)则可正常生效。
解决方案
方案1:扩展showNotification的位置映射
shiny.semantic的showNotification内部会将position参数转换为对应CSS类,默认未包含top attached这类带附加属性的位置。我们可以自定义包装函数手动处理:
library(shiny) library(shiny.semantic) # 自定义支持top attached的showNotification showNotificationCustom <- function(ui, type = "default", position = "top right", ...) { if (position == "top attached") { # 构造带top attached类的通知元素 notification_tag <- div( class = paste("ui", type, "top attached notification"), ui, tags$button(class = "close icon", tags$i(class = "close icon")) ) # 发送通知到页面 session <- shiny::getDefaultReactiveDomain() session$sendCustomMessage( "addNotification", list(html = as.character(notification_tag), position = "top") ) # 绑定关闭事件 session$sendCustomMessage( "setupNotificationClose", list(selector = ".top.attached.notification") ) } else { # 常规位置调用原函数 showNotification(ui, type = type, position = position, ...) } } # 测试应用 if (interactive()) { shinyApp( ui = semanticPage( title = 'Title', actionButton('bottom_left', 'Bottom left!'), actionButton('top_attached', 'Top attached!') ), server = function(input, output) { observeEvent(input$bottom_left, { showNotification( ui = 'Bottom left notification', type = 'default', position = 'bottom left' ) }) observeEvent(input$top_attached, { showNotificationCustom( ui = 'Top attached notification', type = 'default', position = 'top attached' ) }) } ) }
方案2:直接调用原生Fomantic UI Toast(更简洁)
利用shiny::tags$script执行原生JS代码,绕过shiny.semantic封装,完全支持Fomantic UI所有toast参数:
library(shiny) library(shiny.semantic) # 封装自定义toast函数 toastCustom <- function(title, message, position = "top right", type = "default") { session <- shiny::getDefaultReactiveDomain() # 构造JS执行代码 js_code <- sprintf( "$.toast({ position: '%s', title: '%s', message: '%s', class: '%s' });", position, title, message, type ) session$sendCustomMessage("executeJS", list(code = js_code)) } # 测试应用 if (interactive()) { shinyApp( ui = semanticPage( title = 'Title', actionButton('show_top_attached', 'Show Top Attached Toast!'), actionButton('show_bottom_left', 'Show Bottom Left Toast!') ), server = function(input, output) { observeEvent(input$show_top_attached, { toastCustom( title = 'Watch out!', message = 'I am a top attached toast', position = 'top attached', type = 'warning' ) }) observeEvent(input$show_bottom_left, { toastCustom( title = 'Hello!', message = 'I am a bottom left toast', position = 'bottom left', type = 'info' ) }) } ) }
方案3:修正原toast函数的toast_tags使用
你提供的示例中toast函数的toast_tags写法会重复创建toast,正确做法是通过toast_tags修改已创建toast的CSS类:
observeEvent(input$show, { toast( title = 'See me!', message = 'Where am I?', toast_tags = tags$script( "$('.ui.toast').removeClass('top-right').addClass('top attached');" ) ) })
该方法在toast创建后修改样式,也能实现效果,但不如前两种方案优雅。
内容的提问来源于stack exchange,提问作者Serkan
相关产品推荐
相关产品推荐

