Pushing the limits of expandable row details
In a {reactable} table, you can have a row expand to reveal more details by supplying the details
argument with a function returning an image, raw html, another reactable table, etc. There are many examples of this in the package vignette, and they give you a good sense of just how flexible and powerful this feature is.
My first reaction to this was that it seemed like just about anything that can be displayed on a web page can be embedded in the expandable details. So what about something very unusual like… videos? Can {reactable} handle it? Are there potential usecases of this?
While entertaining this idea, I remembered coming across a tweet by Alex Cookson with a link to a very detailed spreadsheet containing timestamped notes of David Robinson’s live #tidytuesday screencasts.
Anyone other #rstats people find @drob's #TidyTuesday screencasts useful?
— Alex Cookson (@alexcookson) January 13, 2020
I made a spreadsheet with timestamps for hundreds of specific tasks he does: https://t.co/HvJbLk1chd
Useful if, like me, you keep going back and ask, “Where in the video did he do [this thing] again?”
So I turned the spreadsheet into a {reactable} table with rows that can expand to reveal a Youtube video at the timestamp. I actually think this makes a really cool use case - it’s easier here than in Google Spreadsheet to navigate around the table with pagination and search bar, and you don’t need to constantly open and close Youtube videos in new windows (in fact, you can keep multiple videos open across rows here!).
Try it out for yourself!
library(tidyverse)
library(htmltools)
library(reactable)
# David Robinson's (@drob) #tidytuesday screencast annotations, made by Alex Cookson (@alexcookson)
screencasts <-
gsheet::gsheet2tbl("docs.google.com/spreadsheets/d/1pjj_G9ncJZPGTYPkR1BYwzA6bhJoeTfY2fJeGKSbOKM") %>%
select(Screencast, Date, Timestamp = `Timestamp (sec)`, Link:Functions) %>%
mutate(Link = str_extract(Link, "(?<=v=).*(?=&)"))
###############
## The Table ##
###############
reactable(screencasts,
# Function to embed Youtube Video
details = function(index){
# Grab video info from hidden columns
link <- screencasts$Link[index]
time <- screencasts$Timestamp[index]
# Div container to add grey padding around the video
tags$div(style = "text-align:center; padding:10px; background:grey",
# The actual video
tags$iframe(
height = "640", width = "640", allow = "fullscreen",
src = glue::glue("https://www.youtube.com/embed/{link}?start={time}&autoplay=1")
)
)
},
# Column options
columns = list(
Link = colDef(show = F),
Timestamp = colDef(show = F),
Description = colDef(width = 500)
),
# Some theme options
searchable = TRUE,
bordered = TRUE,
fullWidth = TRUE,
theme = reactableTheme(
style = list(fontSize = '14px'),
searchInputStyle = list(width = "100%")
),
)