diff --git a/DESCRIPTION b/DESCRIPTION index 216e061..a2813e5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: shiny.emptystate Title: Empty State Components for 'Shiny' -Version: 0.1.0 +Version: 0.1.0.9000 Authors@R: c( person("Ryszard", "SzymaƄski", role = c("aut", "cre"), email = "opensource+ryszard@appsilon.com"), diff --git a/NEWS.md b/NEWS.md index c3c93d9..3c59d5d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# shiny.emptystate (development version) + +- `EmptyStateManager` has now an additional `z_index` argument, to set +[the stack level](https://drafts.csswg.org/css2/#z-index) for the empty state container. #52 + # [shiny.emptystate 0.1.0](https://github.com/Appsilon/shiny.emptystate/releases/tag/v0.1.0) First release. diff --git a/R/empty_state.R b/R/empty_state.R index 898959d..afe1725 100644 --- a/R/empty_state.R +++ b/R/empty_state.R @@ -98,11 +98,18 @@ EmptyStateManager <- R6Class( # nolint: object_name_linter #' Defaults to `default_empty_state_component()` #' @param color Background color of empty state content. #' Defaults to `NULL` + #' @param z_index The stack level for the empty state container. + #' Defaults to `9999` #' @return A new `EmptyStateManager` R6 class object. - initialize = function(id, html_content = default_empty_state_component(), color = NULL) { + initialize = function( + id, + html_content = default_empty_state_component(), + color = NULL, + z_index = 9999) { private$.id <- id private$.html_content <- private$process_html(html_content) private$.color <- color + private$.z_index <- z_index }, #' @description @@ -152,6 +159,7 @@ EmptyStateManager <- R6Class( # nolint: object_name_linter .id = NA, .html_content = NA, .color = NA, + .z_index = NA, empty_state_shown = FALSE, get_session = function() { getDefaultReactiveDomain() @@ -160,7 +168,8 @@ EmptyStateManager <- R6Class( # nolint: object_name_linter list( id = private$.id, html_content = private$.html_content, - color = private$.color + color = private$.color, + z_index = private$.z_index ) }, create_hide_message = function() { diff --git a/inst/emptystate.css b/inst/emptystate.css index 7482a54..7512af4 100644 --- a/inst/emptystate.css +++ b/inst/emptystate.css @@ -5,10 +5,6 @@ height: 100%; } -.empty-state-container { - z-index: 9999; -} - .empty-state-content .empty-state-component { display: flex; flex-direction: column; diff --git a/inst/emptystate.js b/inst/emptystate.js index 92a36d6..ac19717 100644 --- a/inst/emptystate.js +++ b/inst/emptystate.js @@ -20,7 +20,7 @@ function createEmptyStateContentElement(htmlContent) { return emptyStateContentElement; } -function createEmptyStateContainer(elementToReplace) { +function createEmptyStateContainer(elementToReplace, zIndex) { const emptyStateContainer = document.createElement("div"); emptyStateContainer.style.position = "absolute"; @@ -29,6 +29,7 @@ function createEmptyStateContainer(elementToReplace) { emptyStateContainer.style.width = elementToReplace.offsetWidth + "px"; emptyStateContainer.style.left = elementToReplace.offsetLeft + "px"; emptyStateContainer.style.top = elementToReplace.offsetTop + "px"; + emptyStateContainer.style.zIndex = zIndex; emptyStateContainer.classList.add("empty-state-container"); @@ -48,13 +49,14 @@ function findElementById(elementId) { function showEmptyState(message) { const elementId = message.id; const emptyStateContent = message.html_content; + const zIndex = message.z_index const white = "#FFFFFF" const backgroundColor = (message.color === null) ? white : message.color; elementToReplace = findElementById(elementId); - const emptyStateContainer = createEmptyStateContainer(elementToReplace); + const emptyStateContainer = createEmptyStateContainer(elementToReplace, zIndex); const emptyStateContentElement = createEmptyStateContentElement(emptyStateContent); emptyStateContainer.appendChild(emptyStateContentElement); diff --git a/man/EmptyStateManager.Rd b/man/EmptyStateManager.Rd index c205efd..4983c6b 100644 --- a/man/EmptyStateManager.Rd +++ b/man/EmptyStateManager.Rd @@ -76,7 +76,8 @@ Creates a new empty state manager object. \if{html}{\out{
}}\preformatted{EmptyStateManager$new( id, html_content = default_empty_state_component(), - color = NULL + color = NULL, + z_index = 9999 )}\if{html}{\out{
}} } @@ -90,6 +91,9 @@ Defaults to \code{default_empty_state_component()}} \item{\code{color}}{Background color of empty state content. Defaults to \code{NULL}} + +\item{\code{z_index}}{The stack level for the empty state container. +Defaults to \code{9999}} } \if{html}{\out{}} } diff --git a/tests/testthat/test-empty_state.R b/tests/testthat/test-empty_state.R index aa25bdd..db05a5a 100644 --- a/tests/testthat/test-empty_state.R +++ b/tests/testthat/test-empty_state.R @@ -59,6 +59,66 @@ describe("EmptyStateManager", { expect_null(app$get_html(selector = ".empty-state-content")) app$stop() }) + + it("uses a default z-index for its container when not specified", { + skip_on_cran() + app <- shinytest2::AppDriver$new(test_app(), name = "test") + app$click("show") + + js_get_z_index <- "function getZIndex() { + const container = document.querySelector('.empty-state-container'); + return window.getComputedStyle(container).zIndex; + }; + + getZIndex();" + + expect_equal(app$get_js(js_get_z_index), "9999") + app$stop() + }) + + it("can use an arbitrary z-index value for its container", { + skip_on_cran() + + test_app <- function() { + shiny::shinyApp( + ui = shiny::fluidPage( + use_empty_state(), + shiny::actionButton("show", "Show empty state!"), + shiny::actionButton("hide", "Hide empty state!"), + shiny::tableOutput("my_table") + ), + server = function(input, output) { + empty_state_content <- htmltools::div(class = "myDiv") + empty_state_manager <- EmptyStateManager$new( + id = "my_table", + html_content = empty_state_content, + z_index = 3 + ) + shiny::observeEvent(input$show, { + empty_state_manager$show() + }) + shiny::observeEvent(input$hide, { + empty_state_manager$hide() + }) + output$my_table <- shiny::renderTable(data.frame(NA)) + } + ) + } + + + app <- shinytest2::AppDriver$new(test_app(), name = "test") + app$click("show") + + js_get_z_index <- "function getZIndex() { + const container = document.querySelector('.empty-state-container'); + return window.getComputedStyle(container).zIndex; + }; + + getZIndex();" + + expect_equal(app$get_js(js_get_z_index), "3") + app$stop() + }) }) describe("use_empty_state()", {