javascriptrshinyfluent

Horizontal scrolling in shiny.fluent DetailsList (R shiny app with Microsoft Fluent UI)


In a Shiny application, I would like to display a table with a lot of columns using DetailsList from the shiny.fluent R package. I am struggling: How can I add an horizontal scroll bar ?

Here is the code for a minimal example. At this stage, only a small subset of the columns are visible. How can I allow horizontal scrolling? Maybe a JS solution?

library(shiny)
library(shiny.fluent)
library(glue)

makeCard <- function(title, content, size = 12, style = "") {
  div(
    class = glue("card ms-depth-8 ms-sm{size} ms-xl{size}"),
    style = style,
    Stack(
      tokens = list(childrenGap = 5),
      Text(variant = "large", title, block = TRUE),
      content
    )
  )
}
ui <- fluentPage(
  tags$style(".card { padding: 28px; margin-bottom: 28px; }"),
  uiOutput("analysis")
)
server <- function(input, output, session) {
  output$analysis <- renderUI({
    Stack(
      tokens = list(childrenGap = 10), horizontal = TRUE,
      makeCard("Top results", div(style="max-height: 500px; overflow: auto", 
      DetailsList(items = cbind(cbind(fluentSalesDeals,fluentSalesDeals), fluentSalesDeals))))
    )
  })
}
shinyApp(ui, server)

I am quite new to shiny.fluent, maybe another Fluent component would be more appropriate?

NB: I know that I can always fall back on renderDataTable (or any other of this kind) but I'd like to discover new UI components.


Solution

  • If you provide columns to your DetailsList the horizontal scroll bar is properly added. However, in the default setting it is only visible if you scroll down to the end of the table. To remedy this, you can add constrainMode = 0.

    N.B. I rendered only one version of fluentSalesDeals instead of 3 for the sake of simplicity.

    library(shiny)
    library(shiny.fluent)
    library(glue)
    library(tibble)
    
    makeCard <- function(title, content, size = 12, style = "") {
       div(
          class = glue("card ms-depth-8 ms-sm{size} ms-xl{size}"),
          style = style,
          Stack(
             tokens = list(childrenGap = 5),
             Text(variant = "large", title, block = TRUE),
             content
          )
       )
    }
    ui <- fluentPage(
       tags$style(".card { padding: 28px; margin-bottom: 28px; }"),
       uiOutput("analysis")
    )
    server <- function(input, output, session) {
       output$analysis <- renderUI({
          div(
             class = "ms-Grid", dir = "ltr", 
             div(class = "ms-Grid-row",
                 div(class = "ms-Grid-col ms-sm11",
                     Stack(
                        tokens = list(childrenGap = 10), horizontal = TRUE,
                        makeCard("Top results", 
                                 div(style="max-height: 300px; overflow: auto", 
                                     DetailsList(items = fluentSalesDeals,
                                                 columns = tibble(fieldName = names(fluentSalesDeals),
                                                                  name = names(fluentSalesDeals))
                                                 #, constrainMode = 1 ## default
                                     )
                                 )
                        )
                     )
                 )
             ),
             div(class = "ms-Grid-row",
                 div(class = "ms-Grid-col ms-sm11",
                     Stack(
                        tokens = list(childrenGap = 10), horizontal = TRUE,
                        makeCard("Top results", 
                                 div(style="max-height: 300px; overflow: auto", 
                                     DetailsList(items = fluentSalesDeals,
                                                 columns = tibble(fieldName = names(fluentSalesDeals),
                                                                  name = names(fluentSalesDeals)),
                                                 constrainMode = 0
                                     )
                                 )
                        )
                     )
                 )
             )
          )
       })
    }
    shinyApp(ui, server)
    

    Fluent User Interface with two tables. The table on the bottom shows a horizontal scroll bar.