library(tidyverse)
bsf <- pkgnet::FunctionReporter$new()
bsf$set_package("bslib")
bsf$calculate_default_measures()
bslib_fns <-
bsf$nodes |>
as_tibble() |>
filter(!str_detect(node, "^[.%]")) |>
filter(isExported) |>
select(node, isExported, betweenness) |>
separate(node, c("prefix", "rest"), sep = "_", extra = "merge", fill = "right", remove = FALSE)
bslib_fns |>
count(prefix, sort = TRUE) |>
print(n = 25)
#> # A tibble: 27 × 2
#> prefix n
#> <chr> <int>
#> 1 bs 36
#> 2 nav 14
#> 3 accordion 8
#> 4 card 7
#> 5 navs 7
#> 6 navset 7
#> 7 page 7
#> 8 is 4
#> 9 as 3
#> 10 layout 3
#> 11 bootstrap 2
#> 12 showcase 2
#> 13 sidebar 2
#> 14 theme 2
#> 15 as.card 1
#> 16 bootswatch 1
#> 17 breakpoints 1
#> 18 builtin 1
#> 19 input 1
#> 20 is.card 1
#> 21 precompiled 1
#> 22 remove 1
#> 23 run 1
#> 24 update 1
#> 25 value 1
#> # ℹ 2 more rows
bslib_fns |>
filter(prefix %in% c("bs", "accordion", "card", "nav", "navset", "page", "layout", "input", "update")) |>
(\(x) split(x, x$prefix))()
#> $accordion
#> # A tibble: 8 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 accordion accordion <NA> TRUE 190
#> 2 accordion_panel accordion panel TRUE 0
#> 3 accordion_panel_close accordion panel_close TRUE 0
#> 4 accordion_panel_insert accordion panel_insert TRUE 0
#> 5 accordion_panel_open accordion panel_open TRUE 0
#> 6 accordion_panel_remove accordion panel_remove TRUE 0
#> 7 accordion_panel_set accordion panel_set TRUE 0
#> 8 accordion_panel_update accordion panel_update TRUE 0
#>
#> $bs
#> # A tibble: 36 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 bs_add_declarations bs add_declarations TRUE 0
#> 2 bs_add_functions bs add_functions TRUE 0
#> 3 bs_add_mixins bs add_mixins TRUE 0
#> 4 bs_add_rules bs add_rules TRUE 1
#> 5 bs_add_variables bs add_variables TRUE 139.
#> 6 bs_bundle bs bundle TRUE 18.5
#> 7 bs_current_theme bs current_theme TRUE 52.5
#> 8 bs_dependency bs dependency TRUE 0
#> 9 bs_dependency_defer bs dependency_defer TRUE 43
#> 10 bs_get_contrast bs get_contrast TRUE 5.23
#> # ℹ 26 more rows
#>
#> $card
#> # A tibble: 7 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 card card <NA> TRUE 129
#> 2 card_body card body TRUE 21
#> 3 card_body_fill card body_fill TRUE 0
#> 4 card_footer card footer TRUE 0.333
#> 5 card_header card header TRUE 0.833
#> 6 card_image card image TRUE 0
#> 7 card_title card title TRUE 0
#>
#> $input
#> # A tibble: 1 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 input_switch input switch TRUE 0
#>
#> $layout
#> # A tibble: 3 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 layout_column_wrap layout column_wrap TRUE 93
#> 2 layout_columns layout columns TRUE 0
#> 3 layout_sidebar layout sidebar TRUE 217.
#>
#> $nav
#> # A tibble: 14 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 nav nav <NA> TRUE 0
#> 2 nav_append nav append TRUE 0
#> 3 nav_content nav content TRUE 0
#> 4 nav_hide nav hide TRUE 0
#> 5 nav_insert nav insert TRUE 0
#> 6 nav_item nav item TRUE 0
#> 7 nav_menu nav menu TRUE 0
#> 8 nav_panel nav panel TRUE 0
#> 9 nav_panel_hidden nav panel_hidden TRUE 0
#> 10 nav_prepend nav prepend TRUE 0
#> 11 nav_remove nav remove TRUE 0
#> 12 nav_select nav select TRUE 0
#> 13 nav_show nav show TRUE 0
#> 14 nav_spacer nav spacer TRUE 0
#>
#> $navset
#> # A tibble: 7 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 navset_bar navset bar TRUE 0
#> 2 navset_card_pill navset card_pill TRUE 0
#> 3 navset_card_tab navset card_tab TRUE 0
#> 4 navset_hidden navset hidden TRUE 0
#> 5 navset_pill navset pill TRUE 18.5
#> 6 navset_pill_list navset pill_list TRUE 0
#> 7 navset_tab navset tab TRUE 18.5
#>
#> $page
#> # A tibble: 7 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 page page <NA> TRUE 30
#> 2 page_fill page fill TRUE 0
#> 3 page_fillable page fillable TRUE 12
#> 4 page_fixed page fixed TRUE 0
#> 5 page_fluid page fluid TRUE 0
#> 6 page_navbar page navbar TRUE 0
#> 7 page_sidebar page sidebar TRUE 0
#>
#> $update
#> # A tibble: 1 × 5
#> node prefix rest isExported betweenness
#> <chr> <chr> <chr> <lgl> <dbl>
#> 1 update_switch update switch TRUE 0
In general, I think things input_{type}
pairs well with update_{type}
and similarly output_{type}
with render_{type}
. I'm very tempted to say that we should have update_accordion_panel()
but I probably also would have gone with accordion_panel_update()
back when there weren't any update_
functions at all. That said, maybe we'd have an alias? I think it's really helpful to be able to type out update_
and hit tab and see the things you can update. I think that for UI elements, prefixing within the component type makes sense, but once you've built out the UI, then the code lives in a different context.
I'm actually starting to talk myself into a few more things, like toggle_
, insert_
and remove_
prefixes:
toggle_sidebar()
instead ofsidebar_toggle()
(the second one kinda sounds like a noun and not a verb)toggle_accordion_panel()
instead ofaccordion_panel_set()
toggle_switch()
(keeping update_switch())update_accordion_panel()
update_accordion()
- maybe we don't need this one, but one thing it might do is open/close more than one panel at a time
insert_accordion_panel()
,remove_accordion_panel()
Quick thoughts behind those prefixes:
update_*()
changes the properties of the thing, like state, labels, styles, titles, etctoggle_*()
is used for binary state only — open/closed, on/off, active/inactive — by default flips state but can force a particular stateinsert_*()
andremove_*()
for adding and removing UI elementsinput_*
,output_*
,render_*
, standard shiny stuffpage_*
andlayout_*
for layoutsnavset_*
andnav_*
for navs and content toggles
This has some reach into nav land, too:
insert_nav()
orinsert_nav_panel()
would consumenav_append()
,nav_prepend()
andnav_insert()
update_nav_panel()
would handlenav_hide()
andnav_show()
update_navset()
would handlenav_select()
(or maybe it'd betoggle_nav_panel()
)
Thinking about nav_hide()
and nav_show()
brought up that toggle_*
would only be used for binary state that's reported back to the server. iotw, we wouldn't use toggle_nav_panel()
to hide/show the nav because that's not the dominant state of the nav panel. We might also choose not to use toggle_nav_panel()
to activate the nav panel because there's no clear opposite (how do you "unactivate" a nav panel?)
I think the key for me is the distinction between contexts. When you're writing your UI you're in a "what else goes in an accordion" mind frame. You want to type accordion
and hit tab to see the other things you can include there. When you're in your server logic, you're in a different head space. You're thinking about the verb first... "okay so when this input value changes, I want to... update... my accordion"