@@ -1464,13 +1464,15 @@ create_body_rows_l <- function(
14641464) {
14651465
14661466 styles_tbl <- dt_styles_get(data = data )
1467- styles_tbl <- vctrs :: vec_slice(styles_tbl , styles_tbl $ locname %in% c(" stub" , " data" , " row_groups" ))
1467+ styles_tbl <- vctrs :: vec_slice(
1468+ styles_tbl ,
1469+ styles_tbl $ locname %in% c(" stub" , " stub_column" , " data" , " row_groups" )
1470+ )
14681471
14691472 # Obtain all of the visible (`"default"`), non-stub column names
14701473 # for the table from the `boxh` object
14711474 default_vars <- dt_boxhead_get_vars_default(data = data )
14721475
1473-
14741476 stub_layout <- get_stub_layout(data = data )
14751477
14761478 stub_is_2 <- length(stub_layout ) > 1L
@@ -1479,17 +1481,27 @@ create_body_rows_l <- function(
14791481 stub_vars <- dt_boxhead_get_var_stub(data = data )
14801482 n_stub_cols <- if (length(stub_vars ) == 1 && is.na(stub_vars )) 0 else length(stub_vars )
14811483
1484+ # For multi-column stubs, use actual column names as placeholders to enable
1485+ # per-column styling; for single-column stubs, use ::stub:: for backward compat
14821486 if (is.null(stub_layout )) {
14831487 vars <- default_vars
14841488 } else if (! is.null(stub_layout ) && ! stub_is_2 && stub_layout == " rowname" ) {
1485- # Create a ::stub:: placeholder for each stub column
1486- vars <- c(rep(" ::stub::" , n_stub_cols ), default_vars )
1489+ # Use actual stub column names as placeholders for proper style targeting
1490+ if (n_stub_cols > 1 ) {
1491+ vars <- c(paste0(" ::stub_" , stub_vars , " ::" ), default_vars )
1492+ } else {
1493+ vars <- c(" ::stub::" , default_vars )
1494+ }
14871495 } else if (! is.null(stub_layout ) && ! stub_is_2 && stub_layout == " group_label" ) {
14881496 vars <- c(" ::group::" , default_vars )
14891497 } else if (! is.null(stub_layout ) && stub_is_2 ) {
14901498 # When we have both group_label and rowname columns
1491- # Create a ::stub:: placeholder for each stub column, plus the group column
1492- vars <- c(" ::group::" , rep(" ::stub::" , n_stub_cols ), default_vars )
1499+ # Use actual stub column names as placeholders for proper style targeting
1500+ if (n_stub_cols > 1 ) {
1501+ vars <- c(" ::group::" , paste0(" ::stub_" , stub_vars , " ::" ), default_vars )
1502+ } else {
1503+ vars <- c(" ::group::" , " ::stub::" , default_vars )
1504+ }
14931505 }
14941506
14951507 if (" ::group::" %in% vars ) {
@@ -1537,11 +1549,40 @@ create_body_rows_l <- function(
15371549 } else if (
15381550 ! is.na(colname_i ) &&
15391551 colname_i == " ::stub::" &&
1540- " stub" %in% styles_tbl_i [[" locname" ]]
1552+ any(c( " stub" , " stub_column " ) %in% styles_tbl_i [[" locname" ]])
15411553 ) {
15421554
1543- styles_tbl_i_col <- vctrs :: vec_slice(styles_tbl_i , styles_tbl_i $ locname == " stub" )
1544- # styles_i_col <- styles_tbl_i_col[["styles"]]
1555+ # For single-column stubs, check both "stub" and "stub_column" locnames
1556+ styles_tbl_i_col <- vctrs :: vec_slice(
1557+ styles_tbl_i ,
1558+ styles_tbl_i $ locname %in% c(" stub" , " stub_column" )
1559+ )
1560+
1561+ } else if (
1562+ ! is.na(colname_i ) &&
1563+ grepl(" ^::stub_.*::$" , colname_i ) &&
1564+ any(c(" stub" , " stub_column" ) %in% styles_tbl_i [[" locname" ]])
1565+ ) {
1566+
1567+ # For multi-column stubs with named placeholders (e.g., ::stub_group::)
1568+ # Extract the actual column name from the placeholder
1569+ actual_col <- gsub(" ^::stub_(.*)::$" , " \\ 1" , colname_i )
1570+
1571+ # Get styles for this specific stub column (stub_column locname)
1572+ # or fall back to general stub styles
1573+ stub_col_styles <- vctrs :: vec_slice(
1574+ styles_tbl_i ,
1575+ styles_tbl_i $ locname == " stub_column" &
1576+ styles_tbl_i $ colname == actual_col
1577+ )
1578+ general_stub_styles <- vctrs :: vec_slice(
1579+ styles_tbl_i ,
1580+ styles_tbl_i $ locname == " stub"
1581+ )
1582+ styles_tbl_i_col <- vctrs :: vec_rbind(
1583+ stub_col_styles ,
1584+ general_stub_styles
1585+ )
15451586
15461587 } else if (
15471588 " data" %in% styles_tbl_i [[" locname" ]] &&
@@ -1560,17 +1601,20 @@ create_body_rows_l <- function(
15601601
15611602 styles_body <- consolidate_cell_styles_l(styles_tbl_i_col )
15621603
1563- if (identical(colname_i ," ::stub::" )){
1604+ if (
1605+ identical(colname_i , " ::stub::" ) ||
1606+ grepl(" ^::stub_.*::$" , colname_i )
1607+ ) {
15641608 colwidth_i <- dplyr :: filter(
15651609 colwidth_df ,
15661610 type == " stub" ,
15671611 )[i , ]
15681612
1569- }else {
1613+ } else {
15701614 colwidth_i <- dplyr :: filter(
15711615 colwidth_df ,
15721616 var == colname_i
1573- )
1617+ )
15741618 }
15751619
15761620 if (sum(colwidth_i $ unspec < 1 ) > 0 ){
@@ -1588,13 +1632,16 @@ create_body_rows_l <- function(
15881632
15891633 } else {
15901634
1591- if (identical(colname_i ," ::stub::" )){
1635+ if (
1636+ identical(colname_i , " ::stub::" ) ||
1637+ grepl(" ^::stub_.*::$" , colname_i )
1638+ ) {
15921639 colwidth_i <- dplyr :: filter(
15931640 colwidth_df ,
15941641 type == " stub" ,
15951642 )[i , ]
15961643
1597- }else {
1644+ } else {
15981645 colwidth_i <- dplyr :: filter(
15991646 colwidth_df ,
16001647 var == colname_i
0 commit comments