gt
gt copied to clipboard
Correct way to do sticky headers on non-interactive tables?
Prework
- [x] Read and agree to the code of conduct and contributing guidelines.
- [x] If there is already a relevant issue, whether open or closed, comment on the existing thread instead of posting a new issue.
- [x] For any problems you identify, a minimal reproducible example so the maintainer can troubleshoot. A reproducible example is:
- [x] Runnable: post enough R code and data so any onlooker can create the error on their own computer.
- [x] Minimal: reduce runtime wherever possible and remove complicated details that are irrelevant to the issue at hand.
- [x] Readable: format your code according to the tidyverse style guide.
Question
I've been trying to get sticky headers to work and have found it quite hard to get working well.
I'm wondering if there are any recommendations for the best way(s) to do sticky headers.
Examples
This simple Shiny app has problems where the scrolling content scrolls above the header
library(tidyverse)
library(gt)
library(reactable)
library(shiny)
g_output <- gt_output("iris_table")
ui <- fluidPage(
shiny::fluidRow(
column(width=4,
h4("Great"),
tags$div(id="great",
style="height:400px;",
g_output)
)
)
)
server <- function(input, output, session) {
output$iris_table <- render_gt({
iris |>
gt() |>
tab_options(column_labels.background.color = "pink") |>
tab_options(
container.height = px(400)
) |>
tab_style(
style = css(position = "sticky", top = px(0)),
locations = list(cells_column_spanners(), cells_column_labels())
)
})
}
shinyApp(ui, server)
It can be fixed by tweaking some tab_option and tab_style calls:
library(tidyverse)
library(gt)
library(reactable)
library(shiny)
g_output <- gt_output("iris_table")
ui <- fluidPage(
shiny::fluidRow(
column(width=4,
h4("Great"),
tags$div(id="great",
style="height:400px;",
g_output)
)
)
)
server <- function(input, output, session) {
output$iris_table <- render_gt({
iris |>
gt() |>
tab_options(column_labels.background.color = "pink") |>
tab_options(
container.height = px(400),
container.padding.y = px(0)
) |>
tab_style(
style = css(position = "sticky", top = px(-1), zIndex = 100),
locations = list(cells_column_spanners(), cells_column_labels())
)
})
}
shinyApp(ui, server)
giving
but this feels quite technical and unpleasant (especially things like px(-1)
- are there any recommendations for better ways to achieve this?
Additional Question
I've really struggled (not found a solution yet) to get column_spanners to work with fixed headers:
library(tidyverse)
library(gt)
library(reactable)
library(shiny)
g_output <- gt_output("iris_table")
ui <- fluidPage(
shiny::fluidRow(
column(width=4,
h4("Great"),
tags$div(id="great",
style="height:400px;",
g_output)
)
)
)
server <- function(input, output, session) {
output$iris_table <- render_gt({
iris |>
gt() |>
tab_options(column_labels.background.color = "pink") |>
tab_options(
container.height = px(400),
container.padding.y = px(0)
) |>
tab_spanner("Petals", columns = c(Petal.Length, Petal.Width)) |>
tab_style(
style = css(position = "sticky", top = px(0), zIndex = 100),
locations = list(cells_column_spanners(), cells_column_labels())
)
})
}
shinyApp(ui, server)
gives
Is there any recommendation for working with fixed headers and spanner columns? Does my locations
and/or css
code just need some tweaking?
As a feature request, maybe a column_labels.sticky
argument in tab_options()
would be great too!
As soon as the spanner issue is solved I’m all for including this as a basic feature :)