From 6d06dc30867371bbd8bab181ed9c899eb0678b00 Mon Sep 17 00:00:00 2001 From: Olu Adetayo Date: Mon, 13 Jan 2025 17:34:01 +0000 Subject: [PATCH 1/8] add wrapper function for reactable --- DESCRIPTION | 3 +- NAMESPACE | 1 + R/dfe_reactable.R | 105 ++++++++++++++++++++++++ man/dfe_reactable.Rd | 120 ++++++++++++++++++++++++++++ tests/testthat/test-dfe_reactable.R | 57 +++++++++++++ 5 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 R/dfe_reactable.R create mode 100644 man/dfe_reactable.Rd create mode 100644 tests/testthat/test-dfe_reactable.R diff --git a/DESCRIPTION b/DESCRIPTION index 4f22cb5..7046cc0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,8 @@ Imports: shinyGovstyle, shinyjs, stringr, - styler + styler, + reactable Suggests: devtools, diffviewer, diff --git a/NAMESPACE b/NAMESPACE index 0ba2b68..15e1808 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,6 +7,7 @@ export(cookies_panel_server) export(cookies_panel_ui) export(custom_disconnect_message) export(dfe_cookies_script) +export(dfe_reactable) export(external_link) export(header) export(init_analytics) diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R new file mode 100644 index 0000000..9b5f555 --- /dev/null +++ b/R/dfe_reactable.R @@ -0,0 +1,105 @@ +#' Department for Education Reactable Wrapper +#' +#' A wrapper around the `reactable` function for creating styled, accessible, +#' and user-friendly tables tailored to the Department for Education's requirements. +#' +#' @param data A data frame to display in the table. +#' @param columns A named list of column definitions created with `reactable::colDef()`. +#' @param columnGroups A list of column groups created with `reactable::colGroup()`. +#' @param rownames Logical or character. If `TRUE`, show row names. If a string, the row names +#' will be displayed in a column with that name. Defaults to `NULL`. +#' @param groupBy A character vector of column names to group rows by. +#' @param sortable Logical. Enable sorting for all columns by default. +#' @param filterable Logical. Enable column filters. +#' @param searchable Logical. Add a global search box. +#' @param searchMethod Custom search function for global search. +#' @param defaultColDef Default column settings created with `reactable::colDef()`. +#' @param defaultColGroup Default column group settings created with `reactable::colGroup()`. +#' @param defaultSortOrder The default sort order for sortable columns. One of `"asc"` or `"desc"`. +#' @param defaultSorted A named list or character vector of columns to sort by default. +#' @param pagination Logical. Enable pagination. +#' @param defaultPageSize Number of rows to show per page by default. +#' @param showPageSizeOptions Logical. Allow users to change the page size. +#' @param pageSizeOptions A vector of page size options for the page size dropdown. +#' @param paginationType Pagination control type. One of `"numbers"` or `"jump"`. +#' @param showPagination Logical. Show pagination controls. +#' @param showPageInfo Logical. Show page info (e.g., "1–10 of 100 rows"). +#' @param minRows Minimum number of rows to show, even when the data has fewer rows. +#' @param paginateSubRows Logical. Paginate sub rows when rows are grouped. +#' @param details A function or formula for creating expandable row details. +#' @param defaultExpanded Logical or character vector. Expand rows by default. +#' @param selection Selection mode. One of `"multiple"`, `"single"`, or `"none"`. +#' @param defaultSelected A character vector of row names or indices to select by default. +#' @param onClick Callback function for row click events. +#' @param striped Logical. Add zebra-striping to rows. +#' @param compact Logical. Make rows compact. +#' @param wrap Logical. Allow cell text to wrap. +#' @param class CSS class to apply to the table. +#' @param style Inline styles to apply to the table. +#' @param rowClass CSS class to apply to each row. +#' @param rowStyle Inline styles to apply to each row. +#' @param width Table width in pixels or as a CSS value. +#' @param height Table height in pixels or as a CSS value. +#' @param meta Arbitrary metadata to include with the table. +#' @param elementId Element ID for the table widget. +#' @param static Logical. Render a static (non-interactive) table. +#' @param selectionId Element ID to store selected row indices. +#' @param ... Additional arguments passed to `reactable::reactable`. +#' +#' @details +#' The `dfe_reactable` function provides a pre-configured version of the `reactable` function with: +#' \itemize{ +#' \item **Highlighting**: Row highlighting enabled. +#' \item **Borderless Table**: Removes borders for a clean look. +#' \item **Sort Icons Hidden**: Sort icons are not displayed by default. +#' \item **Resizable Columns**: Users can resize columns. +#' \item **Full Width**: Table expands to the full width of the container. +#' \item **Default Column Definition**: Custom column header styles, NA value handling, +#' and alignment. +#' \item **Custom Search Input**: A search bar styled to the Department for Education's specifications. +#' \item **Custom Language**: Provides a user-friendly search placeholder text. +#' } +#' +#' @return A `reactable` HTML widget object. +#' +#' @examples +#' if (interactive()) { +#' library(reactable) +#' dfe_reactable(mtcars) +#' } +#' +#' @export + + +dfe_reactable <- function(data, ...) { + reactable::reactable( + data, + highlight = TRUE, + borderless = TRUE, + showSortIcon = FALSE, + resizable = TRUE, + fullWidth = TRUE, + defaultColDef = reactable::colDef( + headerClass = "bar-sort-header", + html = TRUE, + na = "NA", + minWidth = 65, + align = "left" + ), + language = reactable::reactableLang( + searchPlaceholder = "Search table..." + ), + theme = reactable::reactableTheme( + searchInputStyle = list( + float = "right", + width = "25%", + marginBottom = "10px", + padding = "5px", + fontSize = "14px", + border = "1px solid #ccc", + borderRadius = "5px" + ) + ), + ... + ) +} diff --git a/man/dfe_reactable.Rd b/man/dfe_reactable.Rd new file mode 100644 index 0000000..97cf61a --- /dev/null +++ b/man/dfe_reactable.Rd @@ -0,0 +1,120 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dfe_reactable.R +\name{dfe_reactable} +\alias{dfe_reactable} +\title{Department for Education Reactable Wrapper} +\usage{ +dfe_reactable(data, ...) +} +\arguments{ +\item{data}{A data frame to display in the table.} + +\item{...}{Additional arguments passed to \code{reactable::reactable}.} + +\item{columns}{A named list of column definitions created with \code{reactable::colDef()}.} + +\item{columnGroups}{A list of column groups created with \code{reactable::colGroup()}.} + +\item{rownames}{Logical or character. If \code{TRUE}, show row names. If a string, the row names +will be displayed in a column with that name. Defaults to \code{NULL}.} + +\item{groupBy}{A character vector of column names to group rows by.} + +\item{sortable}{Logical. Enable sorting for all columns by default.} + +\item{filterable}{Logical. Enable column filters.} + +\item{searchable}{Logical. Add a global search box.} + +\item{searchMethod}{Custom search function for global search.} + +\item{defaultColDef}{Default column settings created with \code{reactable::colDef()}.} + +\item{defaultColGroup}{Default column group settings created with \code{reactable::colGroup()}.} + +\item{defaultSortOrder}{The default sort order for sortable columns. One of \code{"asc"} or \code{"desc"}.} + +\item{defaultSorted}{A named list or character vector of columns to sort by default.} + +\item{pagination}{Logical. Enable pagination.} + +\item{defaultPageSize}{Number of rows to show per page by default.} + +\item{showPageSizeOptions}{Logical. Allow users to change the page size.} + +\item{pageSizeOptions}{A vector of page size options for the page size dropdown.} + +\item{paginationType}{Pagination control type. One of \code{"numbers"} or \code{"jump"}.} + +\item{showPagination}{Logical. Show pagination controls.} + +\item{showPageInfo}{Logical. Show page info (e.g., "1–10 of 100 rows").} + +\item{minRows}{Minimum number of rows to show, even when the data has fewer rows.} + +\item{paginateSubRows}{Logical. Paginate sub rows when rows are grouped.} + +\item{details}{A function or formula for creating expandable row details.} + +\item{defaultExpanded}{Logical or character vector. Expand rows by default.} + +\item{selection}{Selection mode. One of \code{"multiple"}, \code{"single"}, or \code{"none"}.} + +\item{defaultSelected}{A character vector of row names or indices to select by default.} + +\item{onClick}{Callback function for row click events.} + +\item{striped}{Logical. Add zebra-striping to rows.} + +\item{compact}{Logical. Make rows compact.} + +\item{wrap}{Logical. Allow cell text to wrap.} + +\item{class}{CSS class to apply to the table.} + +\item{style}{Inline styles to apply to the table.} + +\item{rowClass}{CSS class to apply to each row.} + +\item{rowStyle}{Inline styles to apply to each row.} + +\item{width}{Table width in pixels or as a CSS value.} + +\item{height}{Table height in pixels or as a CSS value.} + +\item{meta}{Arbitrary metadata to include with the table.} + +\item{elementId}{Element ID for the table widget.} + +\item{static}{Logical. Render a static (non-interactive) table.} + +\item{selectionId}{Element ID to store selected row indices.} +} +\value{ +A \code{reactable} HTML widget object. +} +\description{ +A wrapper around the \code{reactable} function for creating styled, accessible, +and user-friendly tables tailored to the Department for Education's requirements. +} +\details{ +The \code{dfe_reactable} function provides a pre-configured version of the \code{reactable} function with: +\itemize{ +\item \strong{Highlighting}: Row highlighting enabled. +\item \strong{Borderless Table}: Removes borders for a clean look. +\item \strong{Sort Icons Hidden}: Sort icons are not displayed by default. +\item \strong{Resizable Columns}: Users can resize columns. +\item \strong{Full Width}: Table expands to the full width of the container. +\item \strong{Default Column Definition}: Custom column header styles, NA value handling, +and alignment. +\item \strong{Custom Search Input}: A search bar styled to the Department for Education's specifications. +\item \strong{Custom Language}: Provides a user-friendly search placeholder text. +} +} +\examples{ +if (interactive()) { + library(reactable) + dfe_reactable(mtcars) +} + +} diff --git a/tests/testthat/test-dfe_reactable.R b/tests/testthat/test-dfe_reactable.R new file mode 100644 index 0000000..788480f --- /dev/null +++ b/tests/testthat/test-dfe_reactable.R @@ -0,0 +1,57 @@ +test_that("dfe_reactable produces a properly configured reactable object", { + # Generate a small sample dataset + sample_data <- data.frame( + Name = c("Alice", "Bob", "Charlie"), + Age = c(25, 30, 35), + Score = c(85.5, 90.3, 88.7) + ) + + # Run the function + table_output <- dfe_reactable(sample_data) + + # Test if the output is a reactable object + expect_s3_class(table_output, "reactable") + expect_s3_class(table_output, "htmlwidget") + + # Check the main attributes + expect_type(table_output$x, "list") + expect_true("tag" %in% names(table_output$x)) + + # Check the tag attribs + attribs <- table_output$x$tag$attribs + expect_type(attribs, "list") + + # Verify key preconfigured attributes + expect_equal(attribs$resizable, TRUE) + expect_equal(attribs$highlight, TRUE) + expect_equal(attribs$borderless, TRUE) + expect_equal(attribs$showSortIcon, FALSE) + + # Verify column definitions + columns <- attribs$columns + expect_equal(length(columns), 3) # Ensure 3 columns are defined + + # Validate the first column's attributes + col1 <- columns[[1]] + expect_equal(col1$id, "Name") + expect_equal(col1$name, "Name") + expect_equal(col1$type, "character") + expect_equal(col1$html, TRUE) + expect_equal(col1$headerClassName, "bar-sort-header") + + # Validate language configuration + language <- attribs$language + expect_type(language, "list") + expect_equal(language$searchPlaceholder, "Search table...") + + # Validate theme configuration + theme <- attribs$theme + expect_type(theme, "list") + expect_equal(theme$searchInputStyle$float, "right") + expect_equal(theme$searchInputStyle$width, "25%") + expect_equal(theme$searchInputStyle$border, "1px solid #ccc") + + # Validate the widget's overall class and package + expect_equal(attr(table_output, "class"), c("reactable", "htmlwidget")) + expect_equal(attr(table_output, "package"), "reactable") +}) From 0c3803663a8347b13693b589a9234047be2687e4 Mon Sep 17 00:00:00 2001 From: Olu Adetayo Date: Wed, 15 Jan 2025 09:55:17 +0000 Subject: [PATCH 2/8] add shiny tests and update dfe_reactable docs --- NAMESPACE | 1 - R/dfe_reactable.R | 52 ++--------- _pkgdown.yml | 4 + man/dfe_reactable.Rd | 90 ++----------------- tests/test_dashboard/server.R | 2 + .../_snaps/UI-04-table/table_example-001.json | 5 ++ .../tests/testthat/test-UI-04-table.R | 13 +++ tests/test_dashboard/ui.R | 8 ++ 8 files changed, 48 insertions(+), 127 deletions(-) create mode 100644 tests/test_dashboard/tests/testthat/_snaps/UI-04-table/table_example-001.json create mode 100644 tests/test_dashboard/tests/testthat/test-UI-04-table.R diff --git a/NAMESPACE b/NAMESPACE index 15e1808..0ba2b68 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,7 +7,6 @@ export(cookies_panel_server) export(cookies_panel_ui) export(custom_disconnect_message) export(dfe_cookies_script) -export(dfe_reactable) export(external_link) export(header) export(init_analytics) diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R index 9b5f555..f967d67 100644 --- a/R/dfe_reactable.R +++ b/R/dfe_reactable.R @@ -4,46 +4,6 @@ #' and user-friendly tables tailored to the Department for Education's requirements. #' #' @param data A data frame to display in the table. -#' @param columns A named list of column definitions created with `reactable::colDef()`. -#' @param columnGroups A list of column groups created with `reactable::colGroup()`. -#' @param rownames Logical or character. If `TRUE`, show row names. If a string, the row names -#' will be displayed in a column with that name. Defaults to `NULL`. -#' @param groupBy A character vector of column names to group rows by. -#' @param sortable Logical. Enable sorting for all columns by default. -#' @param filterable Logical. Enable column filters. -#' @param searchable Logical. Add a global search box. -#' @param searchMethod Custom search function for global search. -#' @param defaultColDef Default column settings created with `reactable::colDef()`. -#' @param defaultColGroup Default column group settings created with `reactable::colGroup()`. -#' @param defaultSortOrder The default sort order for sortable columns. One of `"asc"` or `"desc"`. -#' @param defaultSorted A named list or character vector of columns to sort by default. -#' @param pagination Logical. Enable pagination. -#' @param defaultPageSize Number of rows to show per page by default. -#' @param showPageSizeOptions Logical. Allow users to change the page size. -#' @param pageSizeOptions A vector of page size options for the page size dropdown. -#' @param paginationType Pagination control type. One of `"numbers"` or `"jump"`. -#' @param showPagination Logical. Show pagination controls. -#' @param showPageInfo Logical. Show page info (e.g., "1–10 of 100 rows"). -#' @param minRows Minimum number of rows to show, even when the data has fewer rows. -#' @param paginateSubRows Logical. Paginate sub rows when rows are grouped. -#' @param details A function or formula for creating expandable row details. -#' @param defaultExpanded Logical or character vector. Expand rows by default. -#' @param selection Selection mode. One of `"multiple"`, `"single"`, or `"none"`. -#' @param defaultSelected A character vector of row names or indices to select by default. -#' @param onClick Callback function for row click events. -#' @param striped Logical. Add zebra-striping to rows. -#' @param compact Logical. Make rows compact. -#' @param wrap Logical. Allow cell text to wrap. -#' @param class CSS class to apply to the table. -#' @param style Inline styles to apply to the table. -#' @param rowClass CSS class to apply to each row. -#' @param rowStyle Inline styles to apply to each row. -#' @param width Table width in pixels or as a CSS value. -#' @param height Table height in pixels or as a CSS value. -#' @param meta Arbitrary metadata to include with the table. -#' @param elementId Element ID for the table widget. -#' @param static Logical. Render a static (non-interactive) table. -#' @param selectionId Element ID to store selected row indices. #' @param ... Additional arguments passed to `reactable::reactable`. #' #' @details @@ -64,11 +24,15 @@ #' #' @examples #' if (interactive()) { -#' library(reactable) -#' dfe_reactable(mtcars) +#' library(shiny) +#' library(dfeshiny) +#' ui <- fluidPage( +#' h1("Example of dfe_reactable in a Shiny app"), +#' dfe_reactable(mtcars) +#' ) +#' server <- function(input, output, session) {} +#' shinyApp(ui, server) #' } -#' -#' @export dfe_reactable <- function(data, ...) { diff --git a/_pkgdown.yml b/_pkgdown.yml index 1e51cb2..af1103b 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -32,3 +32,7 @@ reference: desc: A wrapper for shinyGovstyle::header() that automatically uses the DfE logo. contents: - header +- title: Charts and Tables + desc: Functions to create and manage tables and visualisations. + contents: + - dfe_reactable diff --git a/man/dfe_reactable.Rd b/man/dfe_reactable.Rd index 97cf61a..385ad22 100644 --- a/man/dfe_reactable.Rd +++ b/man/dfe_reactable.Rd @@ -10,85 +10,6 @@ dfe_reactable(data, ...) \item{data}{A data frame to display in the table.} \item{...}{Additional arguments passed to \code{reactable::reactable}.} - -\item{columns}{A named list of column definitions created with \code{reactable::colDef()}.} - -\item{columnGroups}{A list of column groups created with \code{reactable::colGroup()}.} - -\item{rownames}{Logical or character. If \code{TRUE}, show row names. If a string, the row names -will be displayed in a column with that name. Defaults to \code{NULL}.} - -\item{groupBy}{A character vector of column names to group rows by.} - -\item{sortable}{Logical. Enable sorting for all columns by default.} - -\item{filterable}{Logical. Enable column filters.} - -\item{searchable}{Logical. Add a global search box.} - -\item{searchMethod}{Custom search function for global search.} - -\item{defaultColDef}{Default column settings created with \code{reactable::colDef()}.} - -\item{defaultColGroup}{Default column group settings created with \code{reactable::colGroup()}.} - -\item{defaultSortOrder}{The default sort order for sortable columns. One of \code{"asc"} or \code{"desc"}.} - -\item{defaultSorted}{A named list or character vector of columns to sort by default.} - -\item{pagination}{Logical. Enable pagination.} - -\item{defaultPageSize}{Number of rows to show per page by default.} - -\item{showPageSizeOptions}{Logical. Allow users to change the page size.} - -\item{pageSizeOptions}{A vector of page size options for the page size dropdown.} - -\item{paginationType}{Pagination control type. One of \code{"numbers"} or \code{"jump"}.} - -\item{showPagination}{Logical. Show pagination controls.} - -\item{showPageInfo}{Logical. Show page info (e.g., "1–10 of 100 rows").} - -\item{minRows}{Minimum number of rows to show, even when the data has fewer rows.} - -\item{paginateSubRows}{Logical. Paginate sub rows when rows are grouped.} - -\item{details}{A function or formula for creating expandable row details.} - -\item{defaultExpanded}{Logical or character vector. Expand rows by default.} - -\item{selection}{Selection mode. One of \code{"multiple"}, \code{"single"}, or \code{"none"}.} - -\item{defaultSelected}{A character vector of row names or indices to select by default.} - -\item{onClick}{Callback function for row click events.} - -\item{striped}{Logical. Add zebra-striping to rows.} - -\item{compact}{Logical. Make rows compact.} - -\item{wrap}{Logical. Allow cell text to wrap.} - -\item{class}{CSS class to apply to the table.} - -\item{style}{Inline styles to apply to the table.} - -\item{rowClass}{CSS class to apply to each row.} - -\item{rowStyle}{Inline styles to apply to each row.} - -\item{width}{Table width in pixels or as a CSS value.} - -\item{height}{Table height in pixels or as a CSS value.} - -\item{meta}{Arbitrary metadata to include with the table.} - -\item{elementId}{Element ID for the table widget.} - -\item{static}{Logical. Render a static (non-interactive) table.} - -\item{selectionId}{Element ID to store selected row indices.} } \value{ A \code{reactable} HTML widget object. @@ -113,8 +34,13 @@ and alignment. } \examples{ if (interactive()) { - library(reactable) - dfe_reactable(mtcars) + library(shiny) + library(dfeshiny) + ui <- fluidPage( + h1("Example of dfe_reactable in a Shiny app"), + dfe_reactable(mtcars) + ) + server <- function(input, output, session) {} + shinyApp(ui, server) } - } diff --git a/tests/test_dashboard/server.R b/tests/test_dashboard/server.R index 56103a8..531a107 100644 --- a/tests/test_dashboard/server.R +++ b/tests/test_dashboard/server.R @@ -15,4 +15,6 @@ server <- function(input, output, session) { input_cookies = shiny::reactive(input$cookies), google_analytics_key = ga_key # nolint: [object_usage_linter] ) + + output$reactable_example <- reactable::renderReactable(dfe_reactable(mtcars)) } diff --git a/tests/test_dashboard/tests/testthat/_snaps/UI-04-table/table_example-001.json b/tests/test_dashboard/tests/testthat/_snaps/UI-04-table/table_example-001.json new file mode 100644 index 0000000..fd2ae4b --- /dev/null +++ b/tests/test_dashboard/tests/testthat/_snaps/UI-04-table/table_example-001.json @@ -0,0 +1,5 @@ +{ + "output": { + + } +} diff --git a/tests/test_dashboard/tests/testthat/test-UI-04-table.R b/tests/test_dashboard/tests/testthat/test-UI-04-table.R new file mode 100644 index 0000000..5b5512c --- /dev/null +++ b/tests/test_dashboard/tests/testthat/test-UI-04-table.R @@ -0,0 +1,13 @@ +app <- AppDriver$new( + name = "table_example", + expect_values_screenshot_args = FALSE +) + +app$wait_for_idle(50) + +test_that("Table renders as expected", { + # Check the initial rendering of the table + app$wait_for_idle(50) + app$expect_values(output = "reactable_example") +}) + diff --git a/tests/test_dashboard/ui.R b/tests/test_dashboard/ui.R index 285e6e9..c9bf086 100644 --- a/tests/test_dashboard/ui.R +++ b/tests/test_dashboard/ui.R @@ -99,6 +99,14 @@ ui <- function(input, output, session) { ), " code in a cave without distractions." ) + ), + + ## Example table panel -------------------------------------------------------- + shiny::tabPanel( + value = "table_panel_ui", + "Table example", + shiny::tags$h1("Reactable example"), + reactable::reactableOutput("reactable_example") ) ) ) From 642788cd54d191b69765813aba9e8acb76a52c79 Mon Sep 17 00:00:00 2001 From: Olu Adetayo Date: Wed, 15 Jan 2025 09:59:30 +0000 Subject: [PATCH 3/8] resolve lint issue --- R/dfe_reactable.R | 17 ++++++++++------- man/dfe_reactable.Rd | 15 ++++++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R index f967d67..88b4e7c 100644 --- a/R/dfe_reactable.R +++ b/R/dfe_reactable.R @@ -1,23 +1,28 @@ #' Department for Education Reactable Wrapper #' #' A wrapper around the `reactable` function for creating styled, accessible, -#' and user-friendly tables tailored to the Department for Education's requirements. +#' and user-friendly tables tailored to the Department for Education's +#' requirements. #' #' @param data A data frame to display in the table. #' @param ... Additional arguments passed to `reactable::reactable`. #' #' @details -#' The `dfe_reactable` function provides a pre-configured version of the `reactable` function with: +#' The `dfe_reactable` function provides a pre-configured version of +#' the `reactable` function with: #' \itemize{ #' \item **Highlighting**: Row highlighting enabled. #' \item **Borderless Table**: Removes borders for a clean look. #' \item **Sort Icons Hidden**: Sort icons are not displayed by default. #' \item **Resizable Columns**: Users can resize columns. #' \item **Full Width**: Table expands to the full width of the container. -#' \item **Default Column Definition**: Custom column header styles, NA value handling, +#' \item **Default Column Definition**: Custom column header styles, +#' NA value handling, #' and alignment. -#' \item **Custom Search Input**: A search bar styled to the Department for Education's specifications. -#' \item **Custom Language**: Provides a user-friendly search placeholder text. +#' \item **Custom Search Input**: A search bar styled to the Department +#' for Education's specifications. +#' \item **Custom Language**: Provides a user-friendly search placeholder +#' text. #' } #' #' @return A `reactable` HTML widget object. @@ -33,8 +38,6 @@ #' server <- function(input, output, session) {} #' shinyApp(ui, server) #' } - - dfe_reactable <- function(data, ...) { reactable::reactable( data, diff --git a/man/dfe_reactable.Rd b/man/dfe_reactable.Rd index 385ad22..a1419a2 100644 --- a/man/dfe_reactable.Rd +++ b/man/dfe_reactable.Rd @@ -16,20 +16,25 @@ A \code{reactable} HTML widget object. } \description{ A wrapper around the \code{reactable} function for creating styled, accessible, -and user-friendly tables tailored to the Department for Education's requirements. +and user-friendly tables tailored to the Department for Education's +requirements. } \details{ -The \code{dfe_reactable} function provides a pre-configured version of the \code{reactable} function with: +The \code{dfe_reactable} function provides a pre-configured version of +the \code{reactable} function with: \itemize{ \item \strong{Highlighting}: Row highlighting enabled. \item \strong{Borderless Table}: Removes borders for a clean look. \item \strong{Sort Icons Hidden}: Sort icons are not displayed by default. \item \strong{Resizable Columns}: Users can resize columns. \item \strong{Full Width}: Table expands to the full width of the container. -\item \strong{Default Column Definition}: Custom column header styles, NA value handling, +\item \strong{Default Column Definition}: Custom column header styles, +NA value handling, and alignment. -\item \strong{Custom Search Input}: A search bar styled to the Department for Education's specifications. -\item \strong{Custom Language}: Provides a user-friendly search placeholder text. +\item \strong{Custom Search Input}: A search bar styled to the Department +for Education's specifications. +\item \strong{Custom Language}: Provides a user-friendly search placeholder +text. } } \examples{ From 8378b281e9a71d0a5c5eec54536f16832c715d2b Mon Sep 17 00:00:00 2001 From: Olu Adetayo Date: Fri, 17 Jan 2025 10:32:14 +0000 Subject: [PATCH 4/8] add dfe css styling --- R/dfe_reactable.R | 7 ++-- inst/www/css/reactable_wrapper.css | 51 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 inst/www/css/reactable_wrapper.css diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R index 88b4e7c..cb12b12 100644 --- a/R/dfe_reactable.R +++ b/R/dfe_reactable.R @@ -47,12 +47,14 @@ dfe_reactable <- function(data, ...) { resizable = TRUE, fullWidth = TRUE, defaultColDef = reactable::colDef( - headerClass = "bar-sort-header", + headerClass = "govuk-table__header", html = TRUE, na = "NA", minWidth = 65, - align = "left" + align = "left", + class = "govuk-table__cell" ), + rowClass = "govuk-table__cell", language = reactable::reactableLang( searchPlaceholder = "Search table..." ), @@ -67,6 +69,7 @@ dfe_reactable <- function(data, ...) { borderRadius = "5px" ) ), + class = "gov-table", ... ) } diff --git a/inst/www/css/reactable_wrapper.css b/inst/www/css/reactable_wrapper.css new file mode 100644 index 0000000..2f519ec --- /dev/null +++ b/inst/www/css/reactable_wrapper.css @@ -0,0 +1,51 @@ +.govuk-table { + font-family: GDS Transport, arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: 400; + font-size: 1rem; + line-height: 1.25; + color: #0b0c0c; + width: 100%; + margin-bottom: 20px; + border-spacing: 0; + border-collapse: collapse +} + +@media print { + .govuk-table { + font-family: sans-serif + } +} + +@media (min-width:40.0625em) { + .govuk-table { + font-size: 1.1875rem; + line-height: 1.3157894737 + } +} + +@media print { + .govuk-table { + font-size: 14pt; + line-height: 1.15; + color: #000 + } +} + +@media (min-width:40.0625em) { + .govuk-table { + margin-bottom: 30px + } +} + +.govuk-table__header { + font-weight: 700 +} + +.govuk-table__cell, .govuk-table__header { + padding: 10px 20px 10px 0; + border-bottom: 1px solid #b1b4b6; + text-align: left; + vertical-align: top +} From b1715b63168e301f8688bb63e93876bfcce30f6b Mon Sep 17 00:00:00 2001 From: Olu Adetayo Date: Fri, 17 Jan 2025 10:39:35 +0000 Subject: [PATCH 5/8] update unit tests --- tests/testthat/test-dfe_reactable.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-dfe_reactable.R b/tests/testthat/test-dfe_reactable.R index 788480f..163d899 100644 --- a/tests/testthat/test-dfe_reactable.R +++ b/tests/testthat/test-dfe_reactable.R @@ -37,7 +37,7 @@ test_that("dfe_reactable produces a properly configured reactable object", { expect_equal(col1$name, "Name") expect_equal(col1$type, "character") expect_equal(col1$html, TRUE) - expect_equal(col1$headerClassName, "bar-sort-header") + expect_equal(col1$headerClassName, "govuk-table__header") # Validate language configuration language <- attribs$language From fa926968958bd7ae58f582f0a95bdb40c186ab3d Mon Sep 17 00:00:00 2001 From: OAJ Date: Fri, 17 Jan 2025 12:20:56 +0000 Subject: [PATCH 6/8] Update tests/test_dashboard/server.R Co-authored-by: Rich Bielby --- tests/test_dashboard/server.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_dashboard/server.R b/tests/test_dashboard/server.R index 531a107..a9bf5fe 100644 --- a/tests/test_dashboard/server.R +++ b/tests/test_dashboard/server.R @@ -16,5 +16,7 @@ server <- function(input, output, session) { google_analytics_key = ga_key # nolint: [object_usage_linter] ) - output$reactable_example <- reactable::renderReactable(dfe_reactable(mtcars)) + output$reactable_example <- reactable::renderReactable( + dfe_reactable(mtcars |> dplyr::select("mpg", "cyl", "hp", "gear")) + ) } From 7e81bd3826999c3469377a8264c81159fb8e4c58 Mon Sep 17 00:00:00 2001 From: OAJ Date: Fri, 17 Jan 2025 12:21:08 +0000 Subject: [PATCH 7/8] Update R/dfe_reactable.R Co-authored-by: Rich Bielby --- R/dfe_reactable.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R index cb12b12..9bb57f4 100644 --- a/R/dfe_reactable.R +++ b/R/dfe_reactable.R @@ -43,7 +43,7 @@ dfe_reactable <- function(data, ...) { data, highlight = TRUE, borderless = TRUE, - showSortIcon = FALSE, + showSortIcon = TRUE, resizable = TRUE, fullWidth = TRUE, defaultColDef = reactable::colDef( From 9b6b1fb9615fafdd71c0cc192fcda9a79845ea2b Mon Sep 17 00:00:00 2001 From: OAJ Date: Fri, 17 Jan 2025 12:21:19 +0000 Subject: [PATCH 8/8] Update R/dfe_reactable.R Co-authored-by: Rich Bielby --- R/dfe_reactable.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/dfe_reactable.R b/R/dfe_reactable.R index 9bb57f4..9c1fdd3 100644 --- a/R/dfe_reactable.R +++ b/R/dfe_reactable.R @@ -54,7 +54,7 @@ dfe_reactable <- function(data, ...) { align = "left", class = "govuk-table__cell" ), - rowClass = "govuk-table__cell", + rowClass = "govuk-table__row", language = reactable::reactableLang( searchPlaceholder = "Search table..." ),