最近发现了一个比较有意思的 DataTables 用例: https://www.canada.ca/en/news.html

大致使用 DT 复现了一下,目前不太清楚的是如何使得 title 和 description 单独占据整行,在溢出时自动换行,不知各位是否有比较好的实现方法:

df <- data.frame(
  title = c(
    as.character(htmltools::tags$a("Biography: Canada’s first Chief Accessibility Officer", href = "https://www.canada.ca/en/employment-social-development/news/2022/04/biography-stephanie-cadieux.html")),
    as.character(htmltools::tags$a("Equipment and expansions help South Shore businesses modernize and grow", href = "https://www.canada.ca/en/atlantic-canada-opportunities/news/2022/04/equipment-and-expansions-help-south-shore-businesses-modernize-and-grow.html"))
  ),
  time = c("2022-04-04 16:26:56", "2022-04-05 09:58:22"),
  from = c("Employment and Social Development Canada", "Atlantic Canada Opportunities Agency"),
  category = c("backgrounders", "news releases"),
  description = c(
    "Stephanie Cadieux is a change leader, an advocate for diversity, accessibility, disability inclusion and an entrepreneur with more than 15 years of experience in planning and leadership roles.",
    "A key part of Canada's economic recovery is supporting businesses as they adapt, grow and move forward from the COVID-19 pandemic. Small and medium-sized businesses and the organizations that support them represent the backbone of our economy. They generate quality local jobs and are a source of pride for their communities. To do so, businesses and entrepreneurs need a strong foundation, built on technological innovation, inclusivity, and clean growth to create the workforce of the future."
  ),
  stringsAsFactors = FALSE
)

htmltools::browsable({
  shiny::fluidPage(
    theme = bslib::bs_theme(version = 5, primary = "#295376"),
    shiny::includeCSS(textConnection(
      "table td:nth-child(1) { font-size: 22px; }
      table td:nth-child(4) { color: #555; }
      table td:nth-child(3) { color: #555; border-left: solid 1px #666; }
      table td:nth-child(4) { color: #555; border-left: solid 1px #666; }"
    )),
    DT::datatable(
      df,
      rownames = FALSE, escape = FALSE,
      options = list(
        headerCallback = DT::JS(
          "function(thead, data, start, end, display){",
          "  $(thead).remove();",
          "}"
        )
      )
    )
  )
})

td的样式设置成 display: block; 即可

df <- data.frame(
  title = c(
    as.character(htmltools::tags$a("Biography: Canada’s first Chief Accessibility Officer", href = "https://www.canada.ca/en/employment-social-development/news/2022/04/biography-stephanie-cadieux.html")),
    as.character(htmltools::tags$a("Equipment and expansions help South Shore businesses modernize and grow", href = "https://www.canada.ca/en/atlantic-canada-opportunities/news/2022/04/equipment-and-expansions-help-south-shore-businesses-modernize-and-grow.html"))
  ),
  time = c("2022-04-04 16:26:56", "2022-04-05 09:58:22"),
  from = c("Employment and Social Development Canada", "Atlantic Canada Opportunities Agency"),
  category = c("backgrounders", "news releases"),
  description = c(
    "Stephanie Cadieux is a change leader, an advocate for diversity, accessibility, disability inclusion and an entrepreneur with more than 15 years of experience in planning and leadership roles.",
    "A key part of Canada's economic recovery is supporting businesses as they adapt, grow and move forward from the COVID-19 pandemic. Small and medium-sized businesses and the organizations that support them represent the backbone of our economy. They generate quality local jobs and are a source of pride for their communities. To do so, businesses and entrepreneurs need a strong foundation, built on technological innovation, inclusivity, and clean growth to create the workforce of the future."
  ),
  stringsAsFactors = FALSE
)

htmltools::browsable({
  shiny::fluidPage(
    theme = bslib::bs_theme(version = 4, primary = "#295376"),
    shiny::includeCSS(textConnection(
      "table td:nth-child(1) { font-size: 22px; }
      table td:nth-child(4) { color: #555; }
      table td:nth-child(3) { color: #555; border-left: solid 1px #666; }
      table td:nth-child(4) { color: #555; border-left: solid 1px #666; }
      td {display: block}"
    )),
    DT::datatable(
      df,
      rownames = FALSE, escape = FALSE,
      options = list(
        headerCallback = DT::JS(
          "function(thead, data, start, end, display){",
          "  $(thead).remove();",
          "}"
        )
      )
    )
  )
})

@tctcab 赞!我又打磨了一下,引入了隐藏列用来展示元数据,加入了 crosstalk 用来做 filter。

df <- data.frame(
  title = c(
    as.character(htmltools::tags$a("Biography: Canada’s first Chief Accessibility Officer", href = "https://www.canada.ca/en/employment-social-development/news/2022/04/biography-stephanie-cadieux.html")),
    as.character(htmltools::tags$a("Equipment and expansions help South Shore businesses modernize and grow", href = "https://www.canada.ca/en/atlantic-canada-opportunities/news/2022/04/equipment-and-expansions-help-south-shore-businesses-modernize-and-grow.html"))
  ),
  time = c("2022-04-04 16:26:56", "2022-04-05 09:58:22"),
  from = c("Employment and Social Development Canada", "Atlantic Canada Opportunities Agency"),
  type = c("backgrounders", "news releases"),
  description = c(
    "Stephanie Cadieux is a change leader, an advocate for diversity, accessibility, disability inclusion and an entrepreneur with more than 15 years of experience in planning and leadership roles.",
    "A key part of Canada's economic recovery is supporting businesses as they adapt, grow and move forward from the COVID-19 pandemic. Small and medium-sized businesses and the organizations that support them represent the backbone of our economy. They generate quality local jobs and are a source of pride for their communities. To do so, businesses and entrepreneurs need a strong foundation, built on technological innovation, inclusivity, and clean growth to create the workforce of the future."
  ),
  stringsAsFactors = FALSE
)

df$metadata <- paste(df$time, df$from, df$type, sep = " &nbsp; | &nbsp; ")
df <- df[, c("title", "time", "from", "type", "metadata", "description")]
df <- df[order(df$time, decreasing = TRUE), ]

df_shared <- crosstalk::SharedData$new(df, key = ~type, group = "shared_objects")

htmltools::browsable({
  shiny::fluidPage(
    theme = bslib::bs_theme(version = 5, primary = "#295376"),
    shiny::includeCSS(textConnection(
      "table td { display: block; }
      table td:nth-child(1) { font-size: 1.375rem; }
      table td:nth-child(2) { color: #555; }"
    )),
    shiny::fluidRow(
      shiny::column(
        width = 10, offset = 1,
        shiny::fluidRow(
          shiny::column(
            width = 2,
            htmltools::tags$p("Use filters to search for the most recent news articles."),
            crosstalk::filter_select(
              id = "selector-type",
              label = "News type",
              sharedData = df_shared,
              group = ~type
            )
          ),
          shiny::column(
            width = 10,
            DT::datatable(
              df_shared,
              rownames = FALSE,
              escape = FALSE,
              selection = "none",
              style = "bootstrap4",
              class = c("table", "table-striped", "table-hover", "table-borderless"),
              options = list(
                columnDefs = list(list(visible = FALSE, targets = c(1, 2, 3))),
                headerCallback = DT::JS(
                  "function(thead, data, start, end, display){",
                  "  $(thead).remove();",
                  "}"
                )
              )
            )
          )
        )
      )
    )
  )
})