Repository navigation
Reactable #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Reactable #14
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,234 @@ | ||
| #' Reactable theme following Rijksoverheid huisstijl. | ||
| #' @description | ||
| #' Creates a `reactableTheme` object with table styling according to the | ||
| #' Rijksoverheid huisstijl. | ||
| #' | ||
| #' @importFrom ROvis.utils ro_check_if_font_available | ||
| #' | ||
| #' @param base_family Character. Font family to use for table text. Default is | ||
| #' "RijksoverheidSansWebText". If not installed, Verdana is used, then Arial, | ||
| #' then the first font found on your device, whichever is installed first. | ||
| #' @param sorting Logical. If `TRUE`, extra space is added to the right | ||
| #' in the column header for sort arrows. Default `FALSE`. | ||
| #' | ||
| #' @return A `reactable::reactableTheme` object. | ||
| #' @export | ||
| #' @family reactable | ||
| ro_reactable_theme <- function( | ||
| base_family = "RijksoverheidSansWebText", | ||
| sorting = FALSE | ||
| ) { | ||
| check_string(base_family) | ||
|
|
||
| base_family <- ROvis.utils::ro_check_if_font_available( | ||
| target_font_family = base_family | ||
| ) | ||
|
|
||
| header_padding <- if (sorting) "10px" else "3px" | ||
|
|
||
| reactable::reactableTheme( | ||
| tableStyle = list( | ||
| border = "1px solid #bababa", | ||
| borderCollapse = "collapse", | ||
| fontFamily = base_family | ||
| ), | ||
| headerStyle = list( | ||
| fontFamily = base_family, | ||
| fontWeight = "normal", | ||
| fontStyle = "normal", | ||
| fontSize = "13px", | ||
| textAlign = "right", | ||
| paddingTop = "1px", | ||
| paddingBottom = "1px", | ||
| paddingLeft = "3px", | ||
| paddingRight = header_padding, | ||
| borderBottom = "1px solid #222222", | ||
| borderLeft = "none", | ||
| borderRight = "none", | ||
| borderTop = "none" | ||
| ), | ||
| cellStyle = list( | ||
| fontFamily = base_family, | ||
| fontWeight = "normal", | ||
| fontStyle = "normal", | ||
| fontSize = "13px", | ||
| textAlign = "right", | ||
| paddingTop = "1px", | ||
| paddingBottom = "1px", | ||
| paddingLeft = "3px", | ||
| paddingRight = "3px", | ||
| border = "none" | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| #' Custom CSS for reactable tables | ||
| #' | ||
| #' @description | ||
| #' Returns a Shiny tags object with custom CSS for reactable tables, | ||
| #' with table styling according to the Rijksoverheid huisstijl. | ||
| #' | ||
| #' @importFrom shiny tags HTML | ||
| #' | ||
| #' @param sorting Logical. If `TRUE`, custom sorting arrows are shown in the | ||
| #' column headers. If `FALSE`, only the default arrows are hidden. | ||
| #' Default `TRUE`. | ||
| #' | ||
| #' @return A `shiny.tag` with a `<head>` tag that contains custom CSS | ||
| #' for reactable tables. | ||
| #' @export | ||
| #' @family reactable | ||
| #' | ||
| #' @examples | ||
| #' if (interactive()) { | ||
| #' library(shiny) | ||
| #' library(reactable) | ||
| #' | ||
| #' ui <- fluidPage( | ||
| #' ro_reactable_css(sorting = TRUE), | ||
| #' reactableOutput("mytable") | ||
| #' ) | ||
| #' | ||
| #' server <- function(input, output, session) { | ||
| #' output$mytable <- renderReactable( | ||
| #' reactable( | ||
| #' iris, | ||
| #' defaultColDef = colDef(align = "right", sortable = TRUE), | ||
| #' theme = ro_reactable_theme(sorting = TRUE) | ||
| #' ) | ||
| #' ) | ||
| #' } | ||
| #' | ||
| #' shinyApp(ui, server) | ||
| #' } | ||
| ro_reactable_css <- function(sorting = TRUE) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would put this default as sorting = FALSE, so it is aligned with the ro_reactable_theme default (and also with Laurens-table opinion). |
||
| arrow_css <- if (sorting) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not something for now, but maybe for the future(?):
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that sounds like a good idea @tkranenburgrivm! Keeps it DRY. We would also need to make sure that we avoid hard-coding any colors that are organisation-dependent. E.g. #44688f, #f2f2f2 and #007bff instead of coming from |
||
| " | ||
| /* Hide the extra sort arrow span */ | ||
| .reactable .rt-th .rt-sort-left { | ||
| display: none !important; | ||
| } | ||
|
|
||
| /* Custom sorting arrows based on aria-sort */ | ||
| .reactable .rt-th { | ||
| position: relative; | ||
| cursor: pointer; | ||
| } | ||
|
|
||
| /* Unsorted: double arrow */ | ||
| .reactable .rt-th[aria-sort='none']::after, | ||
| .reactable .rt-th:not([aria-sort])::after { | ||
| content: '\\2195'; | ||
| position: absolute; | ||
| right: 4px; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| color: #888888; | ||
| } | ||
|
|
||
| /* Ascending: up arrow */ | ||
| .reactable .rt-th[aria-sort='ascending']::after { | ||
| content: '\\2191'; | ||
| position: absolute; | ||
| right: 4px; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| font-size: 16px; | ||
| line-height: 1; | ||
| color: #007bff; | ||
| font-weight: 700; | ||
| } | ||
|
|
||
| /* Descending: down arrow */ | ||
| .reactable .rt-th[aria-sort='descending']::after { | ||
| content: '\\2193'; | ||
| position: absolute; | ||
| right: 4px; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| font-size: 16px; | ||
| color: #007bff; | ||
| font-weight: 700; | ||
| } | ||
| " | ||
| } else { | ||
| " | ||
| /* Hide the extra sort arrow span */ | ||
| .reactable .rt-th .rt-sort-left { | ||
| display: none !important; | ||
| } | ||
| " | ||
| } | ||
|
|
||
| shiny::tags$head( | ||
| shiny::tags$style( | ||
| shiny::HTML(paste0( | ||
| " | ||
| /* Caption styling (if a caption is used) */ | ||
| .reactable .rt-table caption { | ||
| caption-side: top; | ||
| text-align: right; | ||
| font-weight: normal; | ||
| font-style: normal; | ||
| font-size: 14px; | ||
| padding: 1px 3px; | ||
| color: #505050; | ||
| } | ||
|
|
||
| /* Vertical line after first column header */ | ||
| .reactable .rt-thead .rt-tr > .rt-th:first-child { | ||
| border-right: 1px solid #222222 !important; | ||
| } | ||
|
|
||
| /* Vertical line after first column in body */ | ||
| .reactable .rt-tbody .rt-tr-group .rt-tr > .rt-td:first-child { | ||
| border-right: 1px solid #222222 !important; | ||
| } | ||
|
|
||
| /* Zebra striping */ | ||
| .reactable .rt-tbody .rt-tr-group:nth-child(odd) { | ||
| background-color: #f2f2f2; | ||
| } | ||
| .reactable .rt-tbody .rt-tr-group:nth-child(even) { | ||
| background-color: #ffffff; | ||
| } | ||
|
|
||
| /* Hover effect */ | ||
| .reactable .rt-tbody .rt-tr-group:hover { | ||
| background-color: #44688f; | ||
| color: #ffffff; | ||
| } | ||
|
|
||
| /* Selected row */ | ||
| .reactable .rt-tr-group.rt-selected, | ||
| .reactable .rt-tr-group.rt-selected .rt-td { | ||
| background-color: #44688f !important; | ||
| color: #ffffff !important; | ||
| } | ||
|
|
||
| /* Focus indicators: table cells & header */ | ||
| .reactable .rt-td:focus, | ||
| .reactable .rt-th:focus { | ||
| outline: 2px dotted #000 !important; | ||
| box-shadow: none !important; | ||
| border: none !important; | ||
| } | ||
|
|
||
| /* Pagination buttons */ | ||
| .reactable .rt-pagination button:focus, | ||
| .reactable .rt-pagination button:focus-visible { | ||
| outline: 2px dotted #000 !important; | ||
| outline-offset: 2px !important; | ||
| box-shadow: none !important; | ||
| } | ||
| .reactable .rt-pagination button[aria-current='page'] { | ||
| border: 2px solid #949494 !important; | ||
| } | ||
| ", | ||
| arrow_css | ||
| )) | ||
| ) | ||
| ) | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| test_that("ro_reactable_theme applies the font resolved by ro_check_if_font_available", { | ||
| local_mocked_bindings( | ||
| ro_check_if_font_available = function(target_font_family) "Verdana" | ||
| ) | ||
| css <- ro_dt_theme()$children[[1]]$children[[1]] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test is using the ro_dt_theme instead of the ro_reactable_theme |
||
| expect_true(grepl("Verdana", css, fixed = TRUE)) | ||
| }) | ||
|
|
||
| test_that("ro_reactable_theme errors for an unavailable custom font", { | ||
| expect_error( | ||
| ro_dt_theme(base_family = "Not an installed font"), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test is using the ro_dt_theme instead of the ro_reactable_theme |
||
| "Can't find" | ||
| ) | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe something minor (I'm not sure if it has impact on anything): The gt and DT theme call it without the ROvis.utils::. It's already loaded with the NAMESPACE importFrom
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already imported here:
ROvis.table/R/ROvis.table-package.R
Line 13 in d286f68
importFromhere or callROvis.utils::