## ----setup, include = FALSE---------------------------------------------------
source("shots.R")

## ----reading, eval = FALSE, shot = TRUE---------------------------------------
# ui <- el_page(
#   el_select("city", choices = c("Beijing", "Shanghai"), value = "Shanghai"),
#   verbatimTextOutput("picked")
# )
# 
# server <- function(input, output, session) {
#   output$picked <- renderPrint(input$city)
# }
# 
# shinyApp(ui, server)

## ----methods, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#ask_container button').click()", shot_wait = 2----
# ui <- el_page(
#   el_tree(
#     "tree",
#     show_checkbox = TRUE,
#     node_key = "id",
#     default_expand_all = TRUE,
#     default_checked_keys = c("b1", "c"),
#     data = list(
#       list(
#         id = "a",
#         label = "Fruit",
#         children = list(
#           list(id = "b1", label = "Apple"),
#           list(id = "b2", label = "Pear")
#         )
#       ),
#       list(id = "c", label = "Bread")
#     )
#   ),
#   el_button("ask", "Which are checked?"),
#   verbatimTextOutput("answer")
# )
# 
# server <- function(input, output, session) {
#   observeEvent(input$ask, call_el(session, "tree", "getCheckedKeys"))
#   output$answer <- renderPrint(input$tree_get_checked_keys)
# }
# 
# shinyApp(ui, server)

## ----flush-vue, eval = FALSE--------------------------------------------------
# observeEvent(input$run, {
#   flush_vue({
#     update_el_table(session, "tbl", loading = TRUE)
#   })
#   result <- slow_query() # the table shows its mask meanwhile
#   update_el_table(session, "tbl", data = result, loading = FALSE)
# })

## ----task-button, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#save .el-button').click()", shot_wait = 0.5----
# ui <- el_page(el_button("save", "Save", type = "primary", task = TRUE))
# 
# server <- function(input, output, session) {
#   save <- ExtendedTask$new(function() {
#     promises::promise(function(resolve, reject) {
#       later::later(function() resolve(TRUE), 3)
#     })
#   })
#   bslib::bind_task_button(save, "save")
#   observeEvent(input$save, save$invoke())
# }
# 
# shinyApp(ui, server)

## ----el-events-list, eval = FALSE---------------------------------------------
# el_events("el_tree")
# #> el_tree() reports, as input$<id>...:
# #>
# #> Unasked
# #>   input$<id>          the key of the node last clicked
# #>   input$<id>_checked  the keys of the checked nodes
# #>   input$<id>_load     with `lazy = TRUE`, a node asking for its children; ...
# #>
# #> When asked for, with `events =`
# #>   input$<id>_check_change     `list(data, checked, indeterminate)`
# #>   input$<id>_node_drop        `list(dragging, drop, type)`: ...
# #>   ...
# 
# el_tree("tree", data = tree_data, draggable = TRUE, events = "node_drop")
# # -> input$tree_node_drop

## ----on-handler, eval = FALSE, shot = TRUE, shot_js = "var i = document.querySelector('#q_container input'); i.value = 'leek'; i.dispatchEvent(new Event('input')); i.dispatchEvent(new KeyboardEvent('keyup', {key: 'Enter', bubbles: true}));", shot_wait = 2, shot_expect = "document.getElementById('searched').innerText.indexOf('leek') >= 0"----
# ui <- el_page(
#   el_input(
#     "q",
#     placeholder = "Type, then Enter",
#     on = list(
#       "keyup.enter" = JS("function(report, e) { report('enter', e.target.value); }")
#     )
#   ),
#   verbatimTextOutput("searched")
# )
# 
# server <- function(input, output, session) {
#   # input$q follows each keystroke; input$q_enter, only Enter
#   output$searched <- renderText(paste("searched for:", input$q_enter))
# }
# 
# shinyApp(ui, server)

## ----event-inputs, eval = FALSE, shot = TRUE, shot_js = "var td = document.querySelectorAll('#shot .el-table__body tr')[1].querySelector('td'); td.click(); setTimeout(function(){ td.click(); }, 600);", shot_wait = 2.5----
# ui <- el_page(
#   el_table_output("tbl"),
#   verbatimTextOutput("polled"),
#   verbatimTextOutput("latched")
# )
# 
# server <- function(input, output, session) {
#   output$tbl <- render_el_table(
#     el_table(data = head(iris[, c(1, 5)], 3), events = "row_click")
#   )
# 
#   # Reading the value: the last row clicked, but not how many times
#   output$polled <- renderText({
#     paste("last row clicked:", input$tbl_row_click$row_index)
#   })
# 
#   # Observing the event: runs once per click, repeats included
#   clicks <- reactiveVal(0)
#   observeEvent(input$tbl_row_click, clicks(clicks() + 1))
#   output$latched <- renderText(paste("clicks seen:", clicks()))
# }
# 
# shinyApp(ui, server)

## ----module, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#orders-rows .el-table__body .el-button').click()", shot_wait = 2----
# orders_ui <- function(id) {
#   ns <- NS(id)
#   tagList(
#     el_select(ns("status"), choices = c("paid", "pending"), selected = "paid"),
#     el_table_output(ns("rows")),
#     uiOutput(ns("more")),
#     verbatimTextOutput(ns("seen"))
#   )
# }
# 
# orders_server <- function(id) {
#   moduleServer(id, function(input, output, session) {
#     output$rows <- render_el_table(el_table(
#       data = data.frame(order = c(101, 102)),
#       columns = list(
#         list(prop = "order", label = "Order"),
#         list(
#           label = "",
#           cell = el$button(
#             size = "small",
#             "@click" = "rowAction('open', scope)",
#             "Open"
#           )
#         )
#       )
#     ))
#     # Built in the server, still wrapped in ns() once
#     output$more <- renderUI(el_switch(
#       session$ns("urgent"),
#       active_text = "Urgent"
#     ))
#     output$seen <- renderPrint(list(
#       status = input$status,
#       urgent = input$urgent,
#       opened = input$rows_open$row_index
#     ))
#   })
# }
# 
# ui <- el_page(orders_ui("orders"))
# server <- function(input, output, session) orders_server("orders")
# shinyApp(ui, server)

## ----bookmark, eval = FALSE---------------------------------------------------
# ui <- function(request) {
#   el_page(
#     el_select("city", choices = c("Beijing", "Shanghai")),
#     el_tabs(
#       "views",
#       tabs = list(
#         list(name = "table", label = "Table", content = tags$p("...")),
#         list(name = "chart", label = "Chart", content = tags$p("..."))
#       )
#     ),
#     bookmarkButton()
#   )
# }
# server <- function(input, output, session) {}
# shinyApp(ui, server, enableBookmarking = "url")

## ----container, eval = FALSE, shot = TRUE-------------------------------------
# el_collapse(
#   "panels",
#   value = "one",
#   items = list(
#     list(
#       name = "one",
#       title = "Settings",
#       content = tagList(
#         el_switch("dark", value = TRUE, active_text = "Dark mode"),
#         el_rate("stars", value = 4)
#       )
#     ),
#     list(name = "two", title = "About", content = tags$p("Version 0.1.0"))
#   )
# )

## ----absorb, eval = FALSE, shot = TRUE, shot_js = "var b = document.querySelector('#shot .el-button'); b.click(); b.click(); ['mouseenter','mouseover'].forEach(function(t){ b.dispatchEvent(new MouseEvent(t, {bubbles: true})); });", shot_sel = ".el-tooltip__popper", shot_wait = 1.5----
# ui <- el_page(
#   el_tooltip("hint", el_button("save", "Save", type = "primary"),
#              content = "Writes to disk", placement = "right"),
#   verbatimTextOutput("clicks")
# )
# 
# server <- function(input, output, session) {
#   output$clicks <- renderText(paste("Saved", input$save, "times"))   # still reports
# }
# 
# shinyApp(ui, server)

## ----absorbed-update, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#busy_container button').click()", shot_wait = 2, shot_expect = "document.querySelector('.el-button.is-loading').innerText.trim() === 'Saving...'"----
# ui <- el_page(
#   el_tooltip(
#     "hint",
#     el_button("save", "Save", type = "primary"),
#     content = "Writes to disk"
#   ),
#   el_button("busy", "Mark as saving")
# )
# 
# server <- function(input, output, session) {
#   observeEvent(input$busy, {
#     update_el_button(session, "save", label = "Saving...", loading = TRUE)
#   })
# }
# 
# shinyApp(ui, server)

## ----slots, eval = FALSE, shot = TRUE-----------------------------------------
# el_alert(
#   "problem",
#   type = "error",
#   show_icon = TRUE,
#   description = "The upload was larger than 5 MB.",
#   slots = list(title = tags$span(tags$b("Upload failed"), " -- try again"))
# )

## ----scoped-slot, eval = FALSE, shot = TRUE-----------------------------------
# el_calendar(
#   "cal",
#   value = "2026-03-15",
#   slots = list(
#     dateCell = template(
#       htmltools::HTML(paste0(
#         "<div>{{ data.day.slice(8) }}",
#         "<b v-if=\"data.day.slice(8) === '15'\" style=\"color:#F56C6C\">",
#         " due</b></div>"
#       )),
#       slot = "dateCell",
#       scope = "{date, data}"
#     )
#   )
# )

## ----raw-tags, eval = FALSE, shot = TRUE--------------------------------------
# # The tooltip's instance compiles the raw button it wraps
# el_tooltip(
#   "hint",
#   el$button(type = "primary", "Markup only"),
#   content = "No input"
# )
# el_button("save", "A component", type = "primary") # reports input$save

## ----vue-counter, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#counter button').click()", shot_wait = 1----
# ui <- fluidPage(
#   vue_app(
#     "counter",
#     template = tags$div(
#       tags$button(`@click` = "n++", "Add one"),
#       tags$span(" clicked {{ n }} times, {{ doubled }} doubled")
#     ),
#     data = list(n = 0),
#     computed = list(doubled = JS("function() { return this.n * 2; }")),
#     input = "n"
#   ),
#   verbatimTextOutput("n")
# )
# 
# server <- function(input, output, session) {
#   output$n <- renderPrint(input$counter)
# }
# 
# shinyApp(ui, server)

## ----vue-edits, eval = FALSE--------------------------------------------------
# update_vue(
#   session,
#   "todo",
#   insert = list(items = list(id = "t9", text = "Call Ann")),
#   at = 1
# )
# update_vue(session, "todo", replace = list(items = changed_rows), key = "id")
# update_vue(session, "todo", delete = list(items = c("t2", "t5")), key = "id")
# update_vue(
#   session,
#   "todo",
#   set = list("items[3].done" = TRUE, "user.name" = "Ann")
# )

## ----vue-data, eval = FALSE, shot = TRUE--------------------------------------
# ui <- fluidPage(
#   sliderInput("n", "Draws", 10, 1000, 100),
#   vue_app(
#     "summary",
#     tags$p(
#       `:style` = "{opacity: $recalculating.stats ? 0.4 : 1}",
#       "Mean {{ mean }}, sd {{ sd }} of {{ n }} draws"
#     ),
#     data = list(mean = NA, sd = NA, n = 0),
#     outputs = "stats"
#   )
# )
# 
# server <- function(input, output, session) {
#   output$stats <- render_vue_data({
#     x <- rnorm(input$n)
#     list(mean = round(mean(x), 2), sd = round(sd(x), 2), n = input$n)
#   })
# }
# 
# shinyApp(ui, server)

## ----vue-data-store, eval = FALSE---------------------------------------------
# ui <- fluidPage(
#   vue_store("sales", data = list(revenue = 0, growth = 0), outputs = "totals"),
#   vue_app("kpi", tags$b("{{ $store.sales.revenue }}")),
#   vue_app("trend", tags$i("{{ $store.sales.growth }} %"))
# )
# 
# server <- function(input, output, session) {
#   output$totals <- render_vue_data({
#     s <- summarise_sales(input$region)
#     list(revenue = s$revenue, growth = s$growth)
#   })
# }

## ----vue-store, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#add button').click(); document.querySelector('#add button').click()", shot_wait = 1----
# ui <- fluidPage(
#   vue_store("cart", data = list(count = 0), input = "count"),
#   vue_app("add", tags$button(`@click` = "$store.cart.count++", "Add to cart")),
#   vue_app("badge", tags$b(" {{ $store.cart.count }} in the cart")),
#   verbatimTextOutput("server_sees")
# )
# 
# server <- function(input, output, session) {
#   output$server_sees <- renderPrint(input$cart)
# }
# 
# shinyApp(ui, server)

## ----vue-composables, eval = FALSE--------------------------------------------
# vue_app(
#   "summary",
#   tags$p(
#     "{{ n }} rows, {{ stats.value && stats.value.mean }}",
#     "{{ busy ? '...' : '' }}"
#   ),
#   setup = JS(
#     "function() {
#     return {
#       pick: shinyVue.useInput('pick', 'a'),    // a ref, sent as input$pick
#       n: shinyVue.useInputValue('rows'),       // another input's value
#       stats: shinyVue.useOutput('stats'),      // {value, recalculating, error}
#       busy: shinyVue.useBusy()
#     };
#   }"
#   )
# )

## ----vue-islands, eval = FALSE, shot = TRUE, shot_wait = 2--------------------
# ui <- fluidPage(
#   vue_app(
#     "panel",
#     tags$div(
#       tags$label(
#         tags$input(type = "checkbox", `v-model` = "open"),
#         " Show the plot"
#       ),
#       tags$div(
#         `v-if` = "open",
#         selectInput("var", "Variable", names(mtcars)),
#         plotOutput("hist", height = "250px")
#       )
#     ),
#     data = list(open = TRUE)
#   )
# )
# 
# server <- function(input, output, session) {
#   output$hist <- renderPlot(hist(mtcars[[input$var]], main = input$var))
# }
# 
# shinyApp(ui, server)

## ----own-input, eval = FALSE, shot = TRUE, shot_js = "document.querySelector('#cheap_container button').click()", shot_wait = 2----
# price_range_input <- function(id, value = c(0, 100), min = 0, max = 1000) {
#   el_widget(
#     id = id,
#     markup = tags$div(
#       style = "display: flex; align-items: center; gap: 8px",
#       el$input_number(
#         "v-model" = "range[0]",
#         ":min" = "min",
#         ":max" = "range[1]",
#         "controls-position" = "right",
#         size = "small"
#       ),
#       tags$span("to"),
#       el$input_number(
#         "v-model" = "range[1]",
#         ":min" = "range[0]",
#         ":max" = "max",
#         "controls-position" = "right",
#         size = "small"
#       )
#     ),
#     data = list(range = as.list(value), min = min, max = max),
#     input = "range",
#     dependency = element_plus_dependency()
#   )
# }
# 
# ui <- el_page(
#   price_range_input("price", value = c(20, 300)),
#   el_button("cheap", "Under 50"),
#   verbatimTextOutput("picked")
# )
# 
# server <- function(input, output, session) {
#   observeEvent(input$cheap, update_vue(session, "price", value = list(0, 50)))
#   output$picked <- renderPrint(input$price)
# }
# 
# shinyApp(ui, server)

